1 /* 2 * Copyright © 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Jesse Barnes <jbarnes@virtuousgeek.org> 25 * 26 * New plane/sprite handling. 27 * 28 * The older chips had a separate interface for programming plane related 29 * registers; newer ones are much simpler and we can use the new DRM plane 30 * support. 31 */ 32 33 #include <drm/drm_atomic.h> 34 #include <drm/drm_atomic_helper.h> 35 #include <drm/drm_color_mgmt.h> 36 #include <drm/drm_crtc.h> 37 #include <drm/drm_fourcc.h> 38 #include <drm/drm_plane_helper.h> 39 #include <drm/drm_rect.h> 40 #include <drm/i915_drm.h> 41 42 #include "i915_drv.h" 43 #include "intel_atomic_plane.h" 44 #include "intel_drv.h" 45 #include "intel_frontbuffer.h" 46 #include "intel_pm.h" 47 #include "intel_psr.h" 48 #include "intel_sprite.h" 49 50 bool is_planar_yuv_format(u32 pixelformat) 51 { 52 switch (pixelformat) { 53 case DRM_FORMAT_NV12: 54 case DRM_FORMAT_P010: 55 case DRM_FORMAT_P012: 56 case DRM_FORMAT_P016: 57 return true; 58 default: 59 return false; 60 } 61 } 62 63 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 64 int usecs) 65 { 66 /* paranoia */ 67 if (!adjusted_mode->crtc_htotal) 68 return 1; 69 70 return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock, 71 1000 * adjusted_mode->crtc_htotal); 72 } 73 74 /* FIXME: We should instead only take spinlocks once for the entire update 75 * instead of once per mmio. */ 76 #if IS_ENABLED(CONFIG_PROVE_LOCKING) 77 #define VBLANK_EVASION_TIME_US 250 78 #else 79 #define VBLANK_EVASION_TIME_US 100 80 #endif 81 82 /** 83 * intel_pipe_update_start() - start update of a set of display registers 84 * @new_crtc_state: the new crtc state 85 * 86 * Mark the start of an update to pipe registers that should be updated 87 * atomically regarding vblank. If the next vblank will happens within 88 * the next 100 us, this function waits until the vblank passes. 89 * 90 * After a successful call to this function, interrupts will be disabled 91 * until a subsequent call to intel_pipe_update_end(). That is done to 92 * avoid random delays. 93 */ 94 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) 95 { 96 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc); 97 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 98 const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode; 99 long timeout = msecs_to_jiffies_timeout(1); 100 int scanline, min, max, vblank_start; 101 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); 102 bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 103 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); 104 DEFINE_WAIT(wait); 105 u32 psr_status; 106 107 vblank_start = adjusted_mode->crtc_vblank_start; 108 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 109 vblank_start = DIV_ROUND_UP(vblank_start, 2); 110 111 /* FIXME needs to be calibrated sensibly */ 112 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode, 113 VBLANK_EVASION_TIME_US); 114 max = vblank_start - 1; 115 116 if (min <= 0 || max <= 0) 117 goto irq_disable; 118 119 if (WARN_ON(drm_crtc_vblank_get(&crtc->base))) 120 goto irq_disable; 121 122 /* 123 * Wait for psr to idle out after enabling the VBL interrupts 124 * VBL interrupts will start the PSR exit and prevent a PSR 125 * re-entry as well. 126 */ 127 if (intel_psr_wait_for_idle(new_crtc_state, &psr_status)) 128 DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n", 129 psr_status); 130 131 local_irq_disable(); 132 133 crtc->debug.min_vbl = min; 134 crtc->debug.max_vbl = max; 135 trace_i915_pipe_update_start(crtc); 136 137 for (;;) { 138 /* 139 * prepare_to_wait() has a memory barrier, which guarantees 140 * other CPUs can see the task state update by the time we 141 * read the scanline. 142 */ 143 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); 144 145 scanline = intel_get_crtc_scanline(crtc); 146 if (scanline < min || scanline > max) 147 break; 148 149 if (!timeout) { 150 DRM_ERROR("Potential atomic update failure on pipe %c\n", 151 pipe_name(crtc->pipe)); 152 break; 153 } 154 155 local_irq_enable(); 156 157 timeout = schedule_timeout(timeout); 158 159 local_irq_disable(); 160 } 161 162 finish_wait(wq, &wait); 163 164 drm_crtc_vblank_put(&crtc->base); 165 166 /* 167 * On VLV/CHV DSI the scanline counter would appear to 168 * increment approx. 1/3 of a scanline before start of vblank. 169 * The registers still get latched at start of vblank however. 170 * This means we must not write any registers on the first 171 * line of vblank (since not the whole line is actually in 172 * vblank). And unfortunately we can't use the interrupt to 173 * wait here since it will fire too soon. We could use the 174 * frame start interrupt instead since it will fire after the 175 * critical scanline, but that would require more changes 176 * in the interrupt code. So for now we'll just do the nasty 177 * thing and poll for the bad scanline to pass us by. 178 * 179 * FIXME figure out if BXT+ DSI suffers from this as well 180 */ 181 while (need_vlv_dsi_wa && scanline == vblank_start) 182 scanline = intel_get_crtc_scanline(crtc); 183 184 crtc->debug.scanline_start = scanline; 185 crtc->debug.start_vbl_time = ktime_get(); 186 crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); 187 188 trace_i915_pipe_update_vblank_evaded(crtc); 189 return; 190 191 irq_disable: 192 local_irq_disable(); 193 } 194 195 /** 196 * intel_pipe_update_end() - end update of a set of display registers 197 * @new_crtc_state: the new crtc state 198 * 199 * Mark the end of an update started with intel_pipe_update_start(). This 200 * re-enables interrupts and verifies the update was actually completed 201 * before a vblank. 202 */ 203 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) 204 { 205 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc); 206 enum pipe pipe = crtc->pipe; 207 int scanline_end = intel_get_crtc_scanline(crtc); 208 u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc); 209 ktime_t end_vbl_time = ktime_get(); 210 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 211 212 trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); 213 214 /* We're still in the vblank-evade critical section, this can't race. 215 * Would be slightly nice to just grab the vblank count and arm the 216 * event outside of the critical section - the spinlock might spin for a 217 * while ... */ 218 if (new_crtc_state->base.event) { 219 WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0); 220 221 spin_lock(&crtc->base.dev->event_lock); 222 drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event); 223 spin_unlock(&crtc->base.dev->event_lock); 224 225 new_crtc_state->base.event = NULL; 226 } 227 228 local_irq_enable(); 229 230 if (intel_vgpu_active(dev_priv)) 231 return; 232 233 if (crtc->debug.start_vbl_count && 234 crtc->debug.start_vbl_count != end_vbl_count) { 235 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", 236 pipe_name(pipe), crtc->debug.start_vbl_count, 237 end_vbl_count, 238 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 239 crtc->debug.min_vbl, crtc->debug.max_vbl, 240 crtc->debug.scanline_start, scanline_end); 241 } 242 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE 243 else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) > 244 VBLANK_EVASION_TIME_US) 245 DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n", 246 pipe_name(pipe), 247 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 248 VBLANK_EVASION_TIME_US); 249 #endif 250 } 251 252 int intel_plane_check_stride(const struct intel_plane_state *plane_state) 253 { 254 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 255 const struct drm_framebuffer *fb = plane_state->base.fb; 256 unsigned int rotation = plane_state->base.rotation; 257 u32 stride, max_stride; 258 259 /* 260 * We ignore stride for all invisible planes that 261 * can be remapped. Otherwise we could end up 262 * with a false positive when the remapping didn't 263 * kick in due the plane being invisible. 264 */ 265 if (intel_plane_can_remap(plane_state) && 266 !plane_state->base.visible) 267 return 0; 268 269 /* FIXME other color planes? */ 270 stride = plane_state->color_plane[0].stride; 271 max_stride = plane->max_stride(plane, fb->format->format, 272 fb->modifier, rotation); 273 274 if (stride > max_stride) { 275 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n", 276 fb->base.id, stride, 277 plane->base.base.id, plane->base.name, max_stride); 278 return -EINVAL; 279 } 280 281 return 0; 282 } 283 284 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) 285 { 286 const struct drm_framebuffer *fb = plane_state->base.fb; 287 struct drm_rect *src = &plane_state->base.src; 288 u32 src_x, src_y, src_w, src_h, hsub, vsub; 289 bool rotated = drm_rotation_90_or_270(plane_state->base.rotation); 290 291 /* 292 * Hardware doesn't handle subpixel coordinates. 293 * Adjust to (macro)pixel boundary, but be careful not to 294 * increase the source viewport size, because that could 295 * push the downscaling factor out of bounds. 296 */ 297 src_x = src->x1 >> 16; 298 src_w = drm_rect_width(src) >> 16; 299 src_y = src->y1 >> 16; 300 src_h = drm_rect_height(src) >> 16; 301 302 src->x1 = src_x << 16; 303 src->x2 = (src_x + src_w) << 16; 304 src->y1 = src_y << 16; 305 src->y2 = (src_y + src_h) << 16; 306 307 if (!fb->format->is_yuv) 308 return 0; 309 310 /* YUV specific checks */ 311 if (!rotated) { 312 hsub = fb->format->hsub; 313 vsub = fb->format->vsub; 314 } else { 315 hsub = vsub = max(fb->format->hsub, fb->format->vsub); 316 } 317 318 if (src_x % hsub || src_w % hsub) { 319 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u for %sYUV planes\n", 320 src_x, src_w, hsub, rotated ? "rotated " : ""); 321 return -EINVAL; 322 } 323 324 if (src_y % vsub || src_h % vsub) { 325 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u for %sYUV planes\n", 326 src_y, src_h, vsub, rotated ? "rotated " : ""); 327 return -EINVAL; 328 } 329 330 return 0; 331 } 332 333 static unsigned int 334 skl_plane_max_stride(struct intel_plane *plane, 335 u32 pixel_format, u64 modifier, 336 unsigned int rotation) 337 { 338 const struct drm_format_info *info = drm_format_info(pixel_format); 339 int cpp = info->cpp[0]; 340 341 /* 342 * "The stride in bytes must not exceed the 343 * of the size of 8K pixels and 32K bytes." 344 */ 345 if (drm_rotation_90_or_270(rotation)) 346 return min(8192, 32768 / cpp); 347 else 348 return min(8192 * cpp, 32768); 349 } 350 351 static void 352 skl_program_scaler(struct intel_plane *plane, 353 const struct intel_crtc_state *crtc_state, 354 const struct intel_plane_state *plane_state) 355 { 356 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 357 enum pipe pipe = plane->pipe; 358 int scaler_id = plane_state->scaler_id; 359 const struct intel_scaler *scaler = 360 &crtc_state->scaler_state.scalers[scaler_id]; 361 int crtc_x = plane_state->base.dst.x1; 362 int crtc_y = plane_state->base.dst.y1; 363 u32 crtc_w = drm_rect_width(&plane_state->base.dst); 364 u32 crtc_h = drm_rect_height(&plane_state->base.dst); 365 u16 y_hphase, uv_rgb_hphase; 366 u16 y_vphase, uv_rgb_vphase; 367 int hscale, vscale; 368 369 hscale = drm_rect_calc_hscale(&plane_state->base.src, 370 &plane_state->base.dst, 371 0, INT_MAX); 372 vscale = drm_rect_calc_vscale(&plane_state->base.src, 373 &plane_state->base.dst, 374 0, INT_MAX); 375 376 /* TODO: handle sub-pixel coordinates */ 377 if (is_planar_yuv_format(plane_state->base.fb->format->format) && 378 !icl_is_hdr_plane(dev_priv, plane->id)) { 379 y_hphase = skl_scaler_calc_phase(1, hscale, false); 380 y_vphase = skl_scaler_calc_phase(1, vscale, false); 381 382 /* MPEG2 chroma siting convention */ 383 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true); 384 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false); 385 } else { 386 /* not used */ 387 y_hphase = 0; 388 y_vphase = 0; 389 390 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false); 391 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); 392 } 393 394 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), 395 PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode); 396 I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id), 397 PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); 398 I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id), 399 PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); 400 I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); 401 I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h); 402 } 403 404 /* Preoffset values for YUV to RGB Conversion */ 405 #define PREOFF_YUV_TO_RGB_HI 0x1800 406 #define PREOFF_YUV_TO_RGB_ME 0x1F00 407 #define PREOFF_YUV_TO_RGB_LO 0x1800 408 409 #define ROFF(x) (((x) & 0xffff) << 16) 410 #define GOFF(x) (((x) & 0xffff) << 0) 411 #define BOFF(x) (((x) & 0xffff) << 16) 412 413 static void 414 icl_program_input_csc(struct intel_plane *plane, 415 const struct intel_crtc_state *crtc_state, 416 const struct intel_plane_state *plane_state) 417 { 418 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 419 enum pipe pipe = plane->pipe; 420 enum plane_id plane_id = plane->id; 421 422 static const u16 input_csc_matrix[][9] = { 423 /* 424 * BT.601 full range YCbCr -> full range RGB 425 * The matrix required is : 426 * [1.000, 0.000, 1.371, 427 * 1.000, -0.336, -0.698, 428 * 1.000, 1.732, 0.0000] 429 */ 430 [DRM_COLOR_YCBCR_BT601] = { 431 0x7AF8, 0x7800, 0x0, 432 0x8B28, 0x7800, 0x9AC0, 433 0x0, 0x7800, 0x7DD8, 434 }, 435 /* 436 * BT.709 full range YCbCr -> full range RGB 437 * The matrix required is : 438 * [1.000, 0.000, 1.574, 439 * 1.000, -0.187, -0.468, 440 * 1.000, 1.855, 0.0000] 441 */ 442 [DRM_COLOR_YCBCR_BT709] = { 443 0x7C98, 0x7800, 0x0, 444 0x9EF8, 0x7800, 0xAC00, 445 0x0, 0x7800, 0x7ED8, 446 }, 447 /* 448 * BT.2020 full range YCbCr -> full range RGB 449 * The matrix required is : 450 * [1.000, 0.000, 1.474, 451 * 1.000, -0.1645, -0.5713, 452 * 1.000, 1.8814, 0.0000] 453 */ 454 [DRM_COLOR_YCBCR_BT2020] = { 455 0x7BC8, 0x7800, 0x0, 456 0x8928, 0x7800, 0xAA88, 457 0x0, 0x7800, 0x7F10, 458 }, 459 }; 460 461 /* Matrix for Limited Range to Full Range Conversion */ 462 static const u16 input_csc_matrix_lr[][9] = { 463 /* 464 * BT.601 Limted range YCbCr -> full range RGB 465 * The matrix required is : 466 * [1.164384, 0.000, 1.596027, 467 * 1.164384, -0.39175, -0.812813, 468 * 1.164384, 2.017232, 0.0000] 469 */ 470 [DRM_COLOR_YCBCR_BT601] = { 471 0x7CC8, 0x7950, 0x0, 472 0x8D00, 0x7950, 0x9C88, 473 0x0, 0x7950, 0x6810, 474 }, 475 /* 476 * BT.709 Limited range YCbCr -> full range RGB 477 * The matrix required is : 478 * [1.164384, 0.000, 1.792741, 479 * 1.164384, -0.213249, -0.532909, 480 * 1.164384, 2.112402, 0.0000] 481 */ 482 [DRM_COLOR_YCBCR_BT709] = { 483 0x7E58, 0x7950, 0x0, 484 0x8888, 0x7950, 0xADA8, 485 0x0, 0x7950, 0x6870, 486 }, 487 /* 488 * BT.2020 Limited range YCbCr -> full range RGB 489 * The matrix required is : 490 * [1.164, 0.000, 1.678, 491 * 1.164, -0.1873, -0.6504, 492 * 1.164, 2.1417, 0.0000] 493 */ 494 [DRM_COLOR_YCBCR_BT2020] = { 495 0x7D70, 0x7950, 0x0, 496 0x8A68, 0x7950, 0xAC00, 497 0x0, 0x7950, 0x6890, 498 }, 499 }; 500 const u16 *csc; 501 502 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 503 csc = input_csc_matrix[plane_state->base.color_encoding]; 504 else 505 csc = input_csc_matrix_lr[plane_state->base.color_encoding]; 506 507 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) | 508 GOFF(csc[1])); 509 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2])); 510 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) | 511 GOFF(csc[4])); 512 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5])); 513 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) | 514 GOFF(csc[7])); 515 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8])); 516 517 I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), 518 PREOFF_YUV_TO_RGB_HI); 519 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 520 I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 0); 521 else 522 I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 523 PREOFF_YUV_TO_RGB_ME); 524 I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), 525 PREOFF_YUV_TO_RGB_LO); 526 I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0); 527 I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0); 528 I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0); 529 } 530 531 static void 532 skl_program_plane(struct intel_plane *plane, 533 const struct intel_crtc_state *crtc_state, 534 const struct intel_plane_state *plane_state, 535 int color_plane, bool slave, u32 plane_ctl) 536 { 537 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 538 enum plane_id plane_id = plane->id; 539 enum pipe pipe = plane->pipe; 540 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 541 u32 surf_addr = plane_state->color_plane[color_plane].offset; 542 u32 stride = skl_plane_stride(plane_state, color_plane); 543 u32 aux_stride = skl_plane_stride(plane_state, 1); 544 int crtc_x = plane_state->base.dst.x1; 545 int crtc_y = plane_state->base.dst.y1; 546 u32 x = plane_state->color_plane[color_plane].x; 547 u32 y = plane_state->color_plane[color_plane].y; 548 u32 src_w = drm_rect_width(&plane_state->base.src) >> 16; 549 u32 src_h = drm_rect_height(&plane_state->base.src) >> 16; 550 struct intel_plane *linked = plane_state->linked_plane; 551 const struct drm_framebuffer *fb = plane_state->base.fb; 552 u8 alpha = plane_state->base.alpha >> 8; 553 u32 plane_color_ctl = 0; 554 unsigned long irqflags; 555 u32 keymsk, keymax; 556 557 plane_ctl |= skl_plane_ctl_crtc(crtc_state); 558 559 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 560 plane_color_ctl = plane_state->color_ctl | 561 glk_plane_color_ctl_crtc(crtc_state); 562 563 /* Sizes are 0 based */ 564 src_w--; 565 src_h--; 566 567 keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha); 568 569 keymsk = key->channel_mask & 0x7ffffff; 570 if (alpha < 0xff) 571 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE; 572 573 /* The scaler will handle the output position */ 574 if (plane_state->scaler_id >= 0) { 575 crtc_x = 0; 576 crtc_y = 0; 577 } 578 579 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 580 581 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); 582 I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x); 583 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); 584 I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), 585 (plane_state->color_plane[1].offset - surf_addr) | aux_stride); 586 587 if (icl_is_hdr_plane(dev_priv, plane_id)) { 588 u32 cus_ctl = 0; 589 590 if (linked) { 591 /* Enable and use MPEG-2 chroma siting */ 592 cus_ctl = PLANE_CUS_ENABLE | 593 PLANE_CUS_HPHASE_0 | 594 PLANE_CUS_VPHASE_SIGN_NEGATIVE | 595 PLANE_CUS_VPHASE_0_25; 596 597 if (linked->id == PLANE_SPRITE5) 598 cus_ctl |= PLANE_CUS_PLANE_7; 599 else if (linked->id == PLANE_SPRITE4) 600 cus_ctl |= PLANE_CUS_PLANE_6; 601 else 602 MISSING_CASE(linked->id); 603 } 604 605 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl); 606 } 607 608 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 609 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); 610 611 if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id)) 612 icl_program_input_csc(plane, crtc_state, plane_state); 613 614 skl_write_plane_wm(plane, crtc_state); 615 616 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 617 I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk); 618 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax); 619 620 I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x); 621 622 if (INTEL_GEN(dev_priv) < 11) 623 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id), 624 (plane_state->color_plane[1].y << 16) | 625 plane_state->color_plane[1].x); 626 627 /* 628 * The control register self-arms if the plane was previously 629 * disabled. Try to make the plane enable atomic by writing 630 * the control register just before the surface register. 631 */ 632 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); 633 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 634 intel_plane_ggtt_offset(plane_state) + surf_addr); 635 636 if (!slave && plane_state->scaler_id >= 0) 637 skl_program_scaler(plane, crtc_state, plane_state); 638 639 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 640 } 641 642 static void 643 skl_update_plane(struct intel_plane *plane, 644 const struct intel_crtc_state *crtc_state, 645 const struct intel_plane_state *plane_state) 646 { 647 int color_plane = 0; 648 649 if (plane_state->linked_plane) { 650 /* Program the UV plane */ 651 color_plane = 1; 652 } 653 654 skl_program_plane(plane, crtc_state, plane_state, 655 color_plane, false, plane_state->ctl); 656 } 657 658 static void 659 icl_update_slave(struct intel_plane *plane, 660 const struct intel_crtc_state *crtc_state, 661 const struct intel_plane_state *plane_state) 662 { 663 skl_program_plane(plane, crtc_state, plane_state, 0, true, 664 plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE); 665 } 666 667 static void 668 skl_disable_plane(struct intel_plane *plane, 669 const struct intel_crtc_state *crtc_state) 670 { 671 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 672 enum plane_id plane_id = plane->id; 673 enum pipe pipe = plane->pipe; 674 unsigned long irqflags; 675 676 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 677 678 if (icl_is_hdr_plane(dev_priv, plane_id)) 679 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0); 680 681 skl_write_plane_wm(plane, crtc_state); 682 683 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0); 684 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0); 685 686 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 687 } 688 689 static bool 690 skl_plane_get_hw_state(struct intel_plane *plane, 691 enum pipe *pipe) 692 { 693 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 694 enum intel_display_power_domain power_domain; 695 enum plane_id plane_id = plane->id; 696 intel_wakeref_t wakeref; 697 bool ret; 698 699 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 700 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 701 if (!wakeref) 702 return false; 703 704 ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; 705 706 *pipe = plane->pipe; 707 708 intel_display_power_put(dev_priv, power_domain, wakeref); 709 710 return ret; 711 } 712 713 static void i9xx_plane_linear_gamma(u16 gamma[8]) 714 { 715 /* The points are not evenly spaced. */ 716 static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 }; 717 int i; 718 719 for (i = 0; i < 8; i++) 720 gamma[i] = (in[i] << 8) / 32; 721 } 722 723 static void 724 chv_update_csc(const struct intel_plane_state *plane_state) 725 { 726 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 727 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 728 const struct drm_framebuffer *fb = plane_state->base.fb; 729 enum plane_id plane_id = plane->id; 730 /* 731 * |r| | c0 c1 c2 | |cr| 732 * |g| = | c3 c4 c5 | x |y | 733 * |b| | c6 c7 c8 | |cb| 734 * 735 * Coefficients are s3.12. 736 * 737 * Cb and Cr apparently come in as signed already, and 738 * we always get full range data in on account of CLRC0/1. 739 */ 740 static const s16 csc_matrix[][9] = { 741 /* BT.601 full range YCbCr -> full range RGB */ 742 [DRM_COLOR_YCBCR_BT601] = { 743 5743, 4096, 0, 744 -2925, 4096, -1410, 745 0, 4096, 7258, 746 }, 747 /* BT.709 full range YCbCr -> full range RGB */ 748 [DRM_COLOR_YCBCR_BT709] = { 749 6450, 4096, 0, 750 -1917, 4096, -767, 751 0, 4096, 7601, 752 }, 753 }; 754 const s16 *csc = csc_matrix[plane_state->base.color_encoding]; 755 756 /* Seems RGB data bypasses the CSC always */ 757 if (!fb->format->is_yuv) 758 return; 759 760 I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 761 I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 762 I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 763 764 I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0])); 765 I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2])); 766 I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4])); 767 I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6])); 768 I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8])); 769 770 I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); 771 I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 772 I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 773 774 I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 775 I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 776 I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 777 } 778 779 #define SIN_0 0 780 #define COS_0 1 781 782 static void 783 vlv_update_clrc(const struct intel_plane_state *plane_state) 784 { 785 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 786 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 787 const struct drm_framebuffer *fb = plane_state->base.fb; 788 enum pipe pipe = plane->pipe; 789 enum plane_id plane_id = plane->id; 790 int contrast, brightness, sh_scale, sh_sin, sh_cos; 791 792 if (fb->format->is_yuv && 793 plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) { 794 /* 795 * Expand limited range to full range: 796 * Contrast is applied first and is used to expand Y range. 797 * Brightness is applied second and is used to remove the 798 * offset from Y. Saturation/hue is used to expand CbCr range. 799 */ 800 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16); 801 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16); 802 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128); 803 sh_sin = SIN_0 * sh_scale; 804 sh_cos = COS_0 * sh_scale; 805 } else { 806 /* Pass-through everything. */ 807 contrast = 1 << 6; 808 brightness = 0; 809 sh_scale = 1 << 7; 810 sh_sin = SIN_0 * sh_scale; 811 sh_cos = COS_0 * sh_scale; 812 } 813 814 /* FIXME these register are single buffered :( */ 815 I915_WRITE_FW(SPCLRC0(pipe, plane_id), 816 SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness)); 817 I915_WRITE_FW(SPCLRC1(pipe, plane_id), 818 SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos)); 819 } 820 821 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 822 { 823 u32 sprctl = 0; 824 825 if (crtc_state->gamma_enable) 826 sprctl |= SP_GAMMA_ENABLE; 827 828 return sprctl; 829 } 830 831 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, 832 const struct intel_plane_state *plane_state) 833 { 834 const struct drm_framebuffer *fb = plane_state->base.fb; 835 unsigned int rotation = plane_state->base.rotation; 836 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 837 u32 sprctl; 838 839 sprctl = SP_ENABLE; 840 841 switch (fb->format->format) { 842 case DRM_FORMAT_YUYV: 843 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 844 break; 845 case DRM_FORMAT_YVYU: 846 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 847 break; 848 case DRM_FORMAT_UYVY: 849 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 850 break; 851 case DRM_FORMAT_VYUY: 852 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 853 break; 854 case DRM_FORMAT_RGB565: 855 sprctl |= SP_FORMAT_BGR565; 856 break; 857 case DRM_FORMAT_XRGB8888: 858 sprctl |= SP_FORMAT_BGRX8888; 859 break; 860 case DRM_FORMAT_ARGB8888: 861 sprctl |= SP_FORMAT_BGRA8888; 862 break; 863 case DRM_FORMAT_XBGR2101010: 864 sprctl |= SP_FORMAT_RGBX1010102; 865 break; 866 case DRM_FORMAT_ABGR2101010: 867 sprctl |= SP_FORMAT_RGBA1010102; 868 break; 869 case DRM_FORMAT_XBGR8888: 870 sprctl |= SP_FORMAT_RGBX8888; 871 break; 872 case DRM_FORMAT_ABGR8888: 873 sprctl |= SP_FORMAT_RGBA8888; 874 break; 875 default: 876 MISSING_CASE(fb->format->format); 877 return 0; 878 } 879 880 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) 881 sprctl |= SP_YUV_FORMAT_BT709; 882 883 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 884 sprctl |= SP_TILED; 885 886 if (rotation & DRM_MODE_ROTATE_180) 887 sprctl |= SP_ROTATE_180; 888 889 if (rotation & DRM_MODE_REFLECT_X) 890 sprctl |= SP_MIRROR; 891 892 if (key->flags & I915_SET_COLORKEY_SOURCE) 893 sprctl |= SP_SOURCE_KEY; 894 895 return sprctl; 896 } 897 898 static void vlv_update_gamma(const struct intel_plane_state *plane_state) 899 { 900 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 901 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 902 const struct drm_framebuffer *fb = plane_state->base.fb; 903 enum pipe pipe = plane->pipe; 904 enum plane_id plane_id = plane->id; 905 u16 gamma[8]; 906 int i; 907 908 /* Seems RGB data bypasses the gamma always */ 909 if (!fb->format->is_yuv) 910 return; 911 912 i9xx_plane_linear_gamma(gamma); 913 914 /* FIXME these register are single buffered :( */ 915 /* The two end points are implicit (0.0 and 1.0) */ 916 for (i = 1; i < 8 - 1; i++) 917 I915_WRITE_FW(SPGAMC(pipe, plane_id, i - 1), 918 gamma[i] << 16 | 919 gamma[i] << 8 | 920 gamma[i]); 921 } 922 923 static void 924 vlv_update_plane(struct intel_plane *plane, 925 const struct intel_crtc_state *crtc_state, 926 const struct intel_plane_state *plane_state) 927 { 928 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 929 enum pipe pipe = plane->pipe; 930 enum plane_id plane_id = plane->id; 931 u32 sprsurf_offset = plane_state->color_plane[0].offset; 932 u32 linear_offset; 933 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 934 int crtc_x = plane_state->base.dst.x1; 935 int crtc_y = plane_state->base.dst.y1; 936 u32 crtc_w = drm_rect_width(&plane_state->base.dst); 937 u32 crtc_h = drm_rect_height(&plane_state->base.dst); 938 u32 x = plane_state->color_plane[0].x; 939 u32 y = plane_state->color_plane[0].y; 940 unsigned long irqflags; 941 u32 sprctl; 942 943 sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state); 944 945 /* Sizes are 0 based */ 946 crtc_w--; 947 crtc_h--; 948 949 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 950 951 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 952 953 I915_WRITE_FW(SPSTRIDE(pipe, plane_id), 954 plane_state->color_plane[0].stride); 955 I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 956 I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w); 957 I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0); 958 959 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 960 chv_update_csc(plane_state); 961 962 if (key->flags) { 963 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value); 964 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask); 965 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); 966 } 967 968 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset); 969 I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x); 970 971 /* 972 * The control register self-arms if the plane was previously 973 * disabled. Try to make the plane enable atomic by writing 974 * the control register just before the surface register. 975 */ 976 I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl); 977 I915_WRITE_FW(SPSURF(pipe, plane_id), 978 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 979 980 vlv_update_clrc(plane_state); 981 vlv_update_gamma(plane_state); 982 983 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 984 } 985 986 static void 987 vlv_disable_plane(struct intel_plane *plane, 988 const struct intel_crtc_state *crtc_state) 989 { 990 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 991 enum pipe pipe = plane->pipe; 992 enum plane_id plane_id = plane->id; 993 unsigned long irqflags; 994 995 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 996 997 I915_WRITE_FW(SPCNTR(pipe, plane_id), 0); 998 I915_WRITE_FW(SPSURF(pipe, plane_id), 0); 999 1000 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1001 } 1002 1003 static bool 1004 vlv_plane_get_hw_state(struct intel_plane *plane, 1005 enum pipe *pipe) 1006 { 1007 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1008 enum intel_display_power_domain power_domain; 1009 enum plane_id plane_id = plane->id; 1010 intel_wakeref_t wakeref; 1011 bool ret; 1012 1013 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1014 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1015 if (!wakeref) 1016 return false; 1017 1018 ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE; 1019 1020 *pipe = plane->pipe; 1021 1022 intel_display_power_put(dev_priv, power_domain, wakeref); 1023 1024 return ret; 1025 } 1026 1027 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1028 { 1029 u32 sprctl = 0; 1030 1031 if (crtc_state->gamma_enable) 1032 sprctl |= SPRITE_GAMMA_ENABLE; 1033 1034 if (crtc_state->csc_enable) 1035 sprctl |= SPRITE_PIPE_CSC_ENABLE; 1036 1037 return sprctl; 1038 } 1039 1040 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, 1041 const struct intel_plane_state *plane_state) 1042 { 1043 struct drm_i915_private *dev_priv = 1044 to_i915(plane_state->base.plane->dev); 1045 const struct drm_framebuffer *fb = plane_state->base.fb; 1046 unsigned int rotation = plane_state->base.rotation; 1047 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1048 u32 sprctl; 1049 1050 sprctl = SPRITE_ENABLE; 1051 1052 if (IS_IVYBRIDGE(dev_priv)) 1053 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 1054 1055 switch (fb->format->format) { 1056 case DRM_FORMAT_XBGR8888: 1057 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 1058 break; 1059 case DRM_FORMAT_XRGB8888: 1060 sprctl |= SPRITE_FORMAT_RGBX888; 1061 break; 1062 case DRM_FORMAT_YUYV: 1063 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 1064 break; 1065 case DRM_FORMAT_YVYU: 1066 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 1067 break; 1068 case DRM_FORMAT_UYVY: 1069 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 1070 break; 1071 case DRM_FORMAT_VYUY: 1072 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 1073 break; 1074 default: 1075 MISSING_CASE(fb->format->format); 1076 return 0; 1077 } 1078 1079 sprctl |= SPRITE_INT_GAMMA_DISABLE; 1080 1081 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) 1082 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; 1083 1084 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1085 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE; 1086 1087 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1088 sprctl |= SPRITE_TILED; 1089 1090 if (rotation & DRM_MODE_ROTATE_180) 1091 sprctl |= SPRITE_ROTATE_180; 1092 1093 if (key->flags & I915_SET_COLORKEY_DESTINATION) 1094 sprctl |= SPRITE_DEST_KEY; 1095 else if (key->flags & I915_SET_COLORKEY_SOURCE) 1096 sprctl |= SPRITE_SOURCE_KEY; 1097 1098 return sprctl; 1099 } 1100 1101 static void ivb_sprite_linear_gamma(u16 gamma[18]) 1102 { 1103 int i; 1104 1105 for (i = 0; i < 17; i++) 1106 gamma[i] = (i << 10) / 16; 1107 1108 gamma[i] = 3 << 10; 1109 i++; 1110 } 1111 1112 static void ivb_update_gamma(const struct intel_plane_state *plane_state) 1113 { 1114 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1115 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1116 enum pipe pipe = plane->pipe; 1117 u16 gamma[18]; 1118 int i; 1119 1120 ivb_sprite_linear_gamma(gamma); 1121 1122 /* FIXME these register are single buffered :( */ 1123 for (i = 0; i < 16; i++) 1124 I915_WRITE_FW(SPRGAMC(pipe, i), 1125 gamma[i] << 20 | 1126 gamma[i] << 10 | 1127 gamma[i]); 1128 1129 I915_WRITE_FW(SPRGAMC16(pipe, 0), gamma[i]); 1130 I915_WRITE_FW(SPRGAMC16(pipe, 1), gamma[i]); 1131 I915_WRITE_FW(SPRGAMC16(pipe, 2), gamma[i]); 1132 i++; 1133 1134 I915_WRITE_FW(SPRGAMC17(pipe, 0), gamma[i]); 1135 I915_WRITE_FW(SPRGAMC17(pipe, 1), gamma[i]); 1136 I915_WRITE_FW(SPRGAMC17(pipe, 2), gamma[i]); 1137 i++; 1138 } 1139 1140 static void 1141 ivb_update_plane(struct intel_plane *plane, 1142 const struct intel_crtc_state *crtc_state, 1143 const struct intel_plane_state *plane_state) 1144 { 1145 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1146 enum pipe pipe = plane->pipe; 1147 u32 sprsurf_offset = plane_state->color_plane[0].offset; 1148 u32 linear_offset; 1149 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1150 int crtc_x = plane_state->base.dst.x1; 1151 int crtc_y = plane_state->base.dst.y1; 1152 u32 crtc_w = drm_rect_width(&plane_state->base.dst); 1153 u32 crtc_h = drm_rect_height(&plane_state->base.dst); 1154 u32 x = plane_state->color_plane[0].x; 1155 u32 y = plane_state->color_plane[0].y; 1156 u32 src_w = drm_rect_width(&plane_state->base.src) >> 16; 1157 u32 src_h = drm_rect_height(&plane_state->base.src) >> 16; 1158 u32 sprctl, sprscale = 0; 1159 unsigned long irqflags; 1160 1161 sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state); 1162 1163 /* Sizes are 0 based */ 1164 src_w--; 1165 src_h--; 1166 crtc_w--; 1167 crtc_h--; 1168 1169 if (crtc_w != src_w || crtc_h != src_h) 1170 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 1171 1172 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1173 1174 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1175 1176 I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride); 1177 I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 1178 I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 1179 if (IS_IVYBRIDGE(dev_priv)) 1180 I915_WRITE_FW(SPRSCALE(pipe), sprscale); 1181 1182 if (key->flags) { 1183 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value); 1184 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 1185 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value); 1186 } 1187 1188 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 1189 * register */ 1190 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 1191 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x); 1192 } else { 1193 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset); 1194 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x); 1195 } 1196 1197 /* 1198 * The control register self-arms if the plane was previously 1199 * disabled. Try to make the plane enable atomic by writing 1200 * the control register just before the surface register. 1201 */ 1202 I915_WRITE_FW(SPRCTL(pipe), sprctl); 1203 I915_WRITE_FW(SPRSURF(pipe), 1204 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1205 1206 ivb_update_gamma(plane_state); 1207 1208 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1209 } 1210 1211 static void 1212 ivb_disable_plane(struct intel_plane *plane, 1213 const struct intel_crtc_state *crtc_state) 1214 { 1215 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1216 enum pipe pipe = plane->pipe; 1217 unsigned long irqflags; 1218 1219 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1220 1221 I915_WRITE_FW(SPRCTL(pipe), 0); 1222 /* Disable the scaler */ 1223 if (IS_IVYBRIDGE(dev_priv)) 1224 I915_WRITE_FW(SPRSCALE(pipe), 0); 1225 I915_WRITE_FW(SPRSURF(pipe), 0); 1226 1227 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1228 } 1229 1230 static bool 1231 ivb_plane_get_hw_state(struct intel_plane *plane, 1232 enum pipe *pipe) 1233 { 1234 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1235 enum intel_display_power_domain power_domain; 1236 intel_wakeref_t wakeref; 1237 bool ret; 1238 1239 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1240 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1241 if (!wakeref) 1242 return false; 1243 1244 ret = I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE; 1245 1246 *pipe = plane->pipe; 1247 1248 intel_display_power_put(dev_priv, power_domain, wakeref); 1249 1250 return ret; 1251 } 1252 1253 static unsigned int 1254 g4x_sprite_max_stride(struct intel_plane *plane, 1255 u32 pixel_format, u64 modifier, 1256 unsigned int rotation) 1257 { 1258 return 16384; 1259 } 1260 1261 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1262 { 1263 u32 dvscntr = 0; 1264 1265 if (crtc_state->gamma_enable) 1266 dvscntr |= DVS_GAMMA_ENABLE; 1267 1268 if (crtc_state->csc_enable) 1269 dvscntr |= DVS_PIPE_CSC_ENABLE; 1270 1271 return dvscntr; 1272 } 1273 1274 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, 1275 const struct intel_plane_state *plane_state) 1276 { 1277 struct drm_i915_private *dev_priv = 1278 to_i915(plane_state->base.plane->dev); 1279 const struct drm_framebuffer *fb = plane_state->base.fb; 1280 unsigned int rotation = plane_state->base.rotation; 1281 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1282 u32 dvscntr; 1283 1284 dvscntr = DVS_ENABLE; 1285 1286 if (IS_GEN(dev_priv, 6)) 1287 dvscntr |= DVS_TRICKLE_FEED_DISABLE; 1288 1289 switch (fb->format->format) { 1290 case DRM_FORMAT_XBGR8888: 1291 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 1292 break; 1293 case DRM_FORMAT_XRGB8888: 1294 dvscntr |= DVS_FORMAT_RGBX888; 1295 break; 1296 case DRM_FORMAT_YUYV: 1297 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 1298 break; 1299 case DRM_FORMAT_YVYU: 1300 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 1301 break; 1302 case DRM_FORMAT_UYVY: 1303 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 1304 break; 1305 case DRM_FORMAT_VYUY: 1306 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 1307 break; 1308 default: 1309 MISSING_CASE(fb->format->format); 1310 return 0; 1311 } 1312 1313 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) 1314 dvscntr |= DVS_YUV_FORMAT_BT709; 1315 1316 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1317 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE; 1318 1319 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1320 dvscntr |= DVS_TILED; 1321 1322 if (rotation & DRM_MODE_ROTATE_180) 1323 dvscntr |= DVS_ROTATE_180; 1324 1325 if (key->flags & I915_SET_COLORKEY_DESTINATION) 1326 dvscntr |= DVS_DEST_KEY; 1327 else if (key->flags & I915_SET_COLORKEY_SOURCE) 1328 dvscntr |= DVS_SOURCE_KEY; 1329 1330 return dvscntr; 1331 } 1332 1333 static void g4x_update_gamma(const struct intel_plane_state *plane_state) 1334 { 1335 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1336 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1337 const struct drm_framebuffer *fb = plane_state->base.fb; 1338 enum pipe pipe = plane->pipe; 1339 u16 gamma[8]; 1340 int i; 1341 1342 /* Seems RGB data bypasses the gamma always */ 1343 if (!fb->format->is_yuv) 1344 return; 1345 1346 i9xx_plane_linear_gamma(gamma); 1347 1348 /* FIXME these register are single buffered :( */ 1349 /* The two end points are implicit (0.0 and 1.0) */ 1350 for (i = 1; i < 8 - 1; i++) 1351 I915_WRITE_FW(DVSGAMC_G4X(pipe, i - 1), 1352 gamma[i] << 16 | 1353 gamma[i] << 8 | 1354 gamma[i]); 1355 } 1356 1357 static void ilk_sprite_linear_gamma(u16 gamma[17]) 1358 { 1359 int i; 1360 1361 for (i = 0; i < 17; i++) 1362 gamma[i] = (i << 10) / 16; 1363 } 1364 1365 static void ilk_update_gamma(const struct intel_plane_state *plane_state) 1366 { 1367 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1368 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1369 const struct drm_framebuffer *fb = plane_state->base.fb; 1370 enum pipe pipe = plane->pipe; 1371 u16 gamma[17]; 1372 int i; 1373 1374 /* Seems RGB data bypasses the gamma always */ 1375 if (!fb->format->is_yuv) 1376 return; 1377 1378 ilk_sprite_linear_gamma(gamma); 1379 1380 /* FIXME these register are single buffered :( */ 1381 for (i = 0; i < 16; i++) 1382 I915_WRITE_FW(DVSGAMC_ILK(pipe, i), 1383 gamma[i] << 20 | 1384 gamma[i] << 10 | 1385 gamma[i]); 1386 1387 I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 0), gamma[i]); 1388 I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 1), gamma[i]); 1389 I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 2), gamma[i]); 1390 i++; 1391 } 1392 1393 static void 1394 g4x_update_plane(struct intel_plane *plane, 1395 const struct intel_crtc_state *crtc_state, 1396 const struct intel_plane_state *plane_state) 1397 { 1398 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1399 enum pipe pipe = plane->pipe; 1400 u32 dvssurf_offset = plane_state->color_plane[0].offset; 1401 u32 linear_offset; 1402 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1403 int crtc_x = plane_state->base.dst.x1; 1404 int crtc_y = plane_state->base.dst.y1; 1405 u32 crtc_w = drm_rect_width(&plane_state->base.dst); 1406 u32 crtc_h = drm_rect_height(&plane_state->base.dst); 1407 u32 x = plane_state->color_plane[0].x; 1408 u32 y = plane_state->color_plane[0].y; 1409 u32 src_w = drm_rect_width(&plane_state->base.src) >> 16; 1410 u32 src_h = drm_rect_height(&plane_state->base.src) >> 16; 1411 u32 dvscntr, dvsscale = 0; 1412 unsigned long irqflags; 1413 1414 dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state); 1415 1416 /* Sizes are 0 based */ 1417 src_w--; 1418 src_h--; 1419 crtc_w--; 1420 crtc_h--; 1421 1422 if (crtc_w != src_w || crtc_h != src_h) 1423 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 1424 1425 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1426 1427 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1428 1429 I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride); 1430 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 1431 I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 1432 I915_WRITE_FW(DVSSCALE(pipe), dvsscale); 1433 1434 if (key->flags) { 1435 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value); 1436 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 1437 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value); 1438 } 1439 1440 I915_WRITE_FW(DVSLINOFF(pipe), linear_offset); 1441 I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x); 1442 1443 /* 1444 * The control register self-arms if the plane was previously 1445 * disabled. Try to make the plane enable atomic by writing 1446 * the control register just before the surface register. 1447 */ 1448 I915_WRITE_FW(DVSCNTR(pipe), dvscntr); 1449 I915_WRITE_FW(DVSSURF(pipe), 1450 intel_plane_ggtt_offset(plane_state) + dvssurf_offset); 1451 1452 if (IS_G4X(dev_priv)) 1453 g4x_update_gamma(plane_state); 1454 else 1455 ilk_update_gamma(plane_state); 1456 1457 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1458 } 1459 1460 static void 1461 g4x_disable_plane(struct intel_plane *plane, 1462 const struct intel_crtc_state *crtc_state) 1463 { 1464 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1465 enum pipe pipe = plane->pipe; 1466 unsigned long irqflags; 1467 1468 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1469 1470 I915_WRITE_FW(DVSCNTR(pipe), 0); 1471 /* Disable the scaler */ 1472 I915_WRITE_FW(DVSSCALE(pipe), 0); 1473 I915_WRITE_FW(DVSSURF(pipe), 0); 1474 1475 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1476 } 1477 1478 static bool 1479 g4x_plane_get_hw_state(struct intel_plane *plane, 1480 enum pipe *pipe) 1481 { 1482 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1483 enum intel_display_power_domain power_domain; 1484 intel_wakeref_t wakeref; 1485 bool ret; 1486 1487 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1488 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1489 if (!wakeref) 1490 return false; 1491 1492 ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE; 1493 1494 *pipe = plane->pipe; 1495 1496 intel_display_power_put(dev_priv, power_domain, wakeref); 1497 1498 return ret; 1499 } 1500 1501 static bool intel_fb_scalable(const struct drm_framebuffer *fb) 1502 { 1503 if (!fb) 1504 return false; 1505 1506 switch (fb->format->format) { 1507 case DRM_FORMAT_C8: 1508 return false; 1509 default: 1510 return true; 1511 } 1512 } 1513 1514 static int 1515 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state, 1516 struct intel_plane_state *plane_state) 1517 { 1518 const struct drm_framebuffer *fb = plane_state->base.fb; 1519 const struct drm_rect *src = &plane_state->base.src; 1520 const struct drm_rect *dst = &plane_state->base.dst; 1521 int src_x, src_w, src_h, crtc_w, crtc_h; 1522 const struct drm_display_mode *adjusted_mode = 1523 &crtc_state->base.adjusted_mode; 1524 unsigned int cpp = fb->format->cpp[0]; 1525 unsigned int width_bytes; 1526 int min_width, min_height; 1527 1528 crtc_w = drm_rect_width(dst); 1529 crtc_h = drm_rect_height(dst); 1530 1531 src_x = src->x1 >> 16; 1532 src_w = drm_rect_width(src) >> 16; 1533 src_h = drm_rect_height(src) >> 16; 1534 1535 if (src_w == crtc_w && src_h == crtc_h) 1536 return 0; 1537 1538 min_width = 3; 1539 1540 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 1541 if (src_h & 1) { 1542 DRM_DEBUG_KMS("Source height must be even with interlaced modes\n"); 1543 return -EINVAL; 1544 } 1545 min_height = 6; 1546 } else { 1547 min_height = 3; 1548 } 1549 1550 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1551 1552 if (src_w < min_width || src_h < min_height || 1553 src_w > 2048 || src_h > 2048) { 1554 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n", 1555 src_w, src_h, min_width, min_height, 2048, 2048); 1556 return -EINVAL; 1557 } 1558 1559 if (width_bytes > 4096) { 1560 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n", 1561 width_bytes, 4096); 1562 return -EINVAL; 1563 } 1564 1565 if (width_bytes > 4096 || fb->pitches[0] > 4096) { 1566 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n", 1567 fb->pitches[0], 4096); 1568 return -EINVAL; 1569 } 1570 1571 return 0; 1572 } 1573 1574 static int 1575 g4x_sprite_check(struct intel_crtc_state *crtc_state, 1576 struct intel_plane_state *plane_state) 1577 { 1578 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1579 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1580 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1581 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1582 int ret; 1583 1584 if (intel_fb_scalable(plane_state->base.fb)) { 1585 if (INTEL_GEN(dev_priv) < 7) { 1586 min_scale = 1; 1587 max_scale = 16 << 16; 1588 } else if (IS_IVYBRIDGE(dev_priv)) { 1589 min_scale = 1; 1590 max_scale = 2 << 16; 1591 } 1592 } 1593 1594 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1595 &crtc_state->base, 1596 min_scale, max_scale, 1597 true, true); 1598 if (ret) 1599 return ret; 1600 1601 ret = i9xx_check_plane_surface(plane_state); 1602 if (ret) 1603 return ret; 1604 1605 if (!plane_state->base.visible) 1606 return 0; 1607 1608 ret = intel_plane_check_src_coordinates(plane_state); 1609 if (ret) 1610 return ret; 1611 1612 ret = g4x_sprite_check_scaling(crtc_state, plane_state); 1613 if (ret) 1614 return ret; 1615 1616 if (INTEL_GEN(dev_priv) >= 7) 1617 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state); 1618 else 1619 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state); 1620 1621 return 0; 1622 } 1623 1624 int chv_plane_check_rotation(const struct intel_plane_state *plane_state) 1625 { 1626 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1627 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1628 unsigned int rotation = plane_state->base.rotation; 1629 1630 /* CHV ignores the mirror bit when the rotate bit is set :( */ 1631 if (IS_CHERRYVIEW(dev_priv) && 1632 rotation & DRM_MODE_ROTATE_180 && 1633 rotation & DRM_MODE_REFLECT_X) { 1634 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n"); 1635 return -EINVAL; 1636 } 1637 1638 return 0; 1639 } 1640 1641 static int 1642 vlv_sprite_check(struct intel_crtc_state *crtc_state, 1643 struct intel_plane_state *plane_state) 1644 { 1645 int ret; 1646 1647 ret = chv_plane_check_rotation(plane_state); 1648 if (ret) 1649 return ret; 1650 1651 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1652 &crtc_state->base, 1653 DRM_PLANE_HELPER_NO_SCALING, 1654 DRM_PLANE_HELPER_NO_SCALING, 1655 true, true); 1656 if (ret) 1657 return ret; 1658 1659 ret = i9xx_check_plane_surface(plane_state); 1660 if (ret) 1661 return ret; 1662 1663 if (!plane_state->base.visible) 1664 return 0; 1665 1666 ret = intel_plane_check_src_coordinates(plane_state); 1667 if (ret) 1668 return ret; 1669 1670 plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state); 1671 1672 return 0; 1673 } 1674 1675 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, 1676 const struct intel_plane_state *plane_state) 1677 { 1678 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1679 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1680 const struct drm_framebuffer *fb = plane_state->base.fb; 1681 unsigned int rotation = plane_state->base.rotation; 1682 struct drm_format_name_buf format_name; 1683 1684 if (!fb) 1685 return 0; 1686 1687 if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) && 1688 is_ccs_modifier(fb->modifier)) { 1689 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n", 1690 rotation); 1691 return -EINVAL; 1692 } 1693 1694 if (rotation & DRM_MODE_REFLECT_X && 1695 fb->modifier == DRM_FORMAT_MOD_LINEAR) { 1696 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n"); 1697 return -EINVAL; 1698 } 1699 1700 if (drm_rotation_90_or_270(rotation)) { 1701 if (fb->modifier != I915_FORMAT_MOD_Y_TILED && 1702 fb->modifier != I915_FORMAT_MOD_Yf_TILED) { 1703 DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); 1704 return -EINVAL; 1705 } 1706 1707 /* 1708 * 90/270 is not allowed with RGB64 16:16:16:16 and 1709 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards. 1710 */ 1711 switch (fb->format->format) { 1712 case DRM_FORMAT_RGB565: 1713 if (INTEL_GEN(dev_priv) >= 11) 1714 break; 1715 /* fall through */ 1716 case DRM_FORMAT_C8: 1717 case DRM_FORMAT_XRGB16161616F: 1718 case DRM_FORMAT_XBGR16161616F: 1719 case DRM_FORMAT_ARGB16161616F: 1720 case DRM_FORMAT_ABGR16161616F: 1721 case DRM_FORMAT_Y210: 1722 case DRM_FORMAT_Y212: 1723 case DRM_FORMAT_Y216: 1724 case DRM_FORMAT_XVYU12_16161616: 1725 case DRM_FORMAT_XVYU16161616: 1726 DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", 1727 drm_get_format_name(fb->format->format, 1728 &format_name)); 1729 return -EINVAL; 1730 default: 1731 break; 1732 } 1733 } 1734 1735 /* Y-tiling is not supported in IF-ID Interlace mode */ 1736 if (crtc_state->base.enable && 1737 crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE && 1738 (fb->modifier == I915_FORMAT_MOD_Y_TILED || 1739 fb->modifier == I915_FORMAT_MOD_Yf_TILED || 1740 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 1741 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) { 1742 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n"); 1743 return -EINVAL; 1744 } 1745 1746 return 0; 1747 } 1748 1749 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state, 1750 const struct intel_plane_state *plane_state) 1751 { 1752 struct drm_i915_private *dev_priv = 1753 to_i915(plane_state->base.plane->dev); 1754 int crtc_x = plane_state->base.dst.x1; 1755 int crtc_w = drm_rect_width(&plane_state->base.dst); 1756 int pipe_src_w = crtc_state->pipe_src_w; 1757 1758 /* 1759 * Display WA #1175: cnl,glk 1760 * Planes other than the cursor may cause FIFO underflow and display 1761 * corruption if starting less than 4 pixels from the right edge of 1762 * the screen. 1763 * Besides the above WA fix the similar problem, where planes other 1764 * than the cursor ending less than 4 pixels from the left edge of the 1765 * screen may cause FIFO underflow and display corruption. 1766 */ 1767 if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) && 1768 (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { 1769 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n", 1770 crtc_x + crtc_w < 4 ? "end" : "start", 1771 crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x, 1772 4, pipe_src_w - 4); 1773 return -ERANGE; 1774 } 1775 1776 return 0; 1777 } 1778 1779 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) 1780 { 1781 const struct drm_framebuffer *fb = plane_state->base.fb; 1782 unsigned int rotation = plane_state->base.rotation; 1783 int src_w = drm_rect_width(&plane_state->base.src) >> 16; 1784 1785 /* Display WA #1106 */ 1786 if (is_planar_yuv_format(fb->format->format) && src_w & 3 && 1787 (rotation == DRM_MODE_ROTATE_270 || 1788 rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { 1789 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); 1790 return -EINVAL; 1791 } 1792 1793 return 0; 1794 } 1795 1796 static int skl_plane_check(struct intel_crtc_state *crtc_state, 1797 struct intel_plane_state *plane_state) 1798 { 1799 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1800 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1801 const struct drm_framebuffer *fb = plane_state->base.fb; 1802 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1803 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1804 int ret; 1805 1806 ret = skl_plane_check_fb(crtc_state, plane_state); 1807 if (ret) 1808 return ret; 1809 1810 /* use scaler when colorkey is not required */ 1811 if (!plane_state->ckey.flags && intel_fb_scalable(fb)) { 1812 min_scale = 1; 1813 max_scale = skl_max_scale(crtc_state, fb->format->format); 1814 } 1815 1816 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1817 &crtc_state->base, 1818 min_scale, max_scale, 1819 true, true); 1820 if (ret) 1821 return ret; 1822 1823 ret = skl_check_plane_surface(plane_state); 1824 if (ret) 1825 return ret; 1826 1827 if (!plane_state->base.visible) 1828 return 0; 1829 1830 ret = skl_plane_check_dst_coordinates(crtc_state, plane_state); 1831 if (ret) 1832 return ret; 1833 1834 ret = intel_plane_check_src_coordinates(plane_state); 1835 if (ret) 1836 return ret; 1837 1838 ret = skl_plane_check_nv12_rotation(plane_state); 1839 if (ret) 1840 return ret; 1841 1842 /* HW only has 8 bits pixel precision, disable plane if invisible */ 1843 if (!(plane_state->base.alpha >> 8)) 1844 plane_state->base.visible = false; 1845 1846 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); 1847 1848 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 1849 plane_state->color_ctl = glk_plane_color_ctl(crtc_state, 1850 plane_state); 1851 1852 return 0; 1853 } 1854 1855 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv) 1856 { 1857 return INTEL_GEN(dev_priv) >= 9; 1858 } 1859 1860 static void intel_plane_set_ckey(struct intel_plane_state *plane_state, 1861 const struct drm_intel_sprite_colorkey *set) 1862 { 1863 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1864 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1865 struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1866 1867 *key = *set; 1868 1869 /* 1870 * We want src key enabled on the 1871 * sprite and not on the primary. 1872 */ 1873 if (plane->id == PLANE_PRIMARY && 1874 set->flags & I915_SET_COLORKEY_SOURCE) 1875 key->flags = 0; 1876 1877 /* 1878 * On SKL+ we want dst key enabled on 1879 * the primary and not on the sprite. 1880 */ 1881 if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY && 1882 set->flags & I915_SET_COLORKEY_DESTINATION) 1883 key->flags = 0; 1884 } 1885 1886 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, 1887 struct drm_file *file_priv) 1888 { 1889 struct drm_i915_private *dev_priv = to_i915(dev); 1890 struct drm_intel_sprite_colorkey *set = data; 1891 struct drm_plane *plane; 1892 struct drm_plane_state *plane_state; 1893 struct drm_atomic_state *state; 1894 struct drm_modeset_acquire_ctx ctx; 1895 int ret = 0; 1896 1897 /* ignore the pointless "none" flag */ 1898 set->flags &= ~I915_SET_COLORKEY_NONE; 1899 1900 if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1901 return -EINVAL; 1902 1903 /* Make sure we don't try to enable both src & dest simultaneously */ 1904 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1905 return -EINVAL; 1906 1907 if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 1908 set->flags & I915_SET_COLORKEY_DESTINATION) 1909 return -EINVAL; 1910 1911 plane = drm_plane_find(dev, file_priv, set->plane_id); 1912 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) 1913 return -ENOENT; 1914 1915 /* 1916 * SKL+ only plane 2 can do destination keying against plane 1. 1917 * Also multiple planes can't do destination keying on the same 1918 * pipe simultaneously. 1919 */ 1920 if (INTEL_GEN(dev_priv) >= 9 && 1921 to_intel_plane(plane)->id >= PLANE_SPRITE1 && 1922 set->flags & I915_SET_COLORKEY_DESTINATION) 1923 return -EINVAL; 1924 1925 drm_modeset_acquire_init(&ctx, 0); 1926 1927 state = drm_atomic_state_alloc(plane->dev); 1928 if (!state) { 1929 ret = -ENOMEM; 1930 goto out; 1931 } 1932 state->acquire_ctx = &ctx; 1933 1934 while (1) { 1935 plane_state = drm_atomic_get_plane_state(state, plane); 1936 ret = PTR_ERR_OR_ZERO(plane_state); 1937 if (!ret) 1938 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 1939 1940 /* 1941 * On some platforms we have to configure 1942 * the dst colorkey on the primary plane. 1943 */ 1944 if (!ret && has_dst_key_in_primary_plane(dev_priv)) { 1945 struct intel_crtc *crtc = 1946 intel_get_crtc_for_pipe(dev_priv, 1947 to_intel_plane(plane)->pipe); 1948 1949 plane_state = drm_atomic_get_plane_state(state, 1950 crtc->base.primary); 1951 ret = PTR_ERR_OR_ZERO(plane_state); 1952 if (!ret) 1953 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 1954 } 1955 1956 if (!ret) 1957 ret = drm_atomic_commit(state); 1958 1959 if (ret != -EDEADLK) 1960 break; 1961 1962 drm_atomic_state_clear(state); 1963 drm_modeset_backoff(&ctx); 1964 } 1965 1966 drm_atomic_state_put(state); 1967 out: 1968 drm_modeset_drop_locks(&ctx); 1969 drm_modeset_acquire_fini(&ctx); 1970 return ret; 1971 } 1972 1973 static const u32 g4x_plane_formats[] = { 1974 DRM_FORMAT_XRGB8888, 1975 DRM_FORMAT_YUYV, 1976 DRM_FORMAT_YVYU, 1977 DRM_FORMAT_UYVY, 1978 DRM_FORMAT_VYUY, 1979 }; 1980 1981 static const u64 i9xx_plane_format_modifiers[] = { 1982 I915_FORMAT_MOD_X_TILED, 1983 DRM_FORMAT_MOD_LINEAR, 1984 DRM_FORMAT_MOD_INVALID 1985 }; 1986 1987 static const u32 snb_plane_formats[] = { 1988 DRM_FORMAT_XBGR8888, 1989 DRM_FORMAT_XRGB8888, 1990 DRM_FORMAT_YUYV, 1991 DRM_FORMAT_YVYU, 1992 DRM_FORMAT_UYVY, 1993 DRM_FORMAT_VYUY, 1994 }; 1995 1996 static const u32 vlv_plane_formats[] = { 1997 DRM_FORMAT_RGB565, 1998 DRM_FORMAT_ABGR8888, 1999 DRM_FORMAT_ARGB8888, 2000 DRM_FORMAT_XBGR8888, 2001 DRM_FORMAT_XRGB8888, 2002 DRM_FORMAT_XBGR2101010, 2003 DRM_FORMAT_ABGR2101010, 2004 DRM_FORMAT_YUYV, 2005 DRM_FORMAT_YVYU, 2006 DRM_FORMAT_UYVY, 2007 DRM_FORMAT_VYUY, 2008 }; 2009 2010 static const u32 skl_plane_formats[] = { 2011 DRM_FORMAT_C8, 2012 DRM_FORMAT_RGB565, 2013 DRM_FORMAT_XRGB8888, 2014 DRM_FORMAT_XBGR8888, 2015 DRM_FORMAT_ARGB8888, 2016 DRM_FORMAT_ABGR8888, 2017 DRM_FORMAT_XRGB2101010, 2018 DRM_FORMAT_XBGR2101010, 2019 DRM_FORMAT_YUYV, 2020 DRM_FORMAT_YVYU, 2021 DRM_FORMAT_UYVY, 2022 DRM_FORMAT_VYUY, 2023 }; 2024 2025 static const u32 skl_planar_formats[] = { 2026 DRM_FORMAT_C8, 2027 DRM_FORMAT_RGB565, 2028 DRM_FORMAT_XRGB8888, 2029 DRM_FORMAT_XBGR8888, 2030 DRM_FORMAT_ARGB8888, 2031 DRM_FORMAT_ABGR8888, 2032 DRM_FORMAT_XRGB2101010, 2033 DRM_FORMAT_XBGR2101010, 2034 DRM_FORMAT_YUYV, 2035 DRM_FORMAT_YVYU, 2036 DRM_FORMAT_UYVY, 2037 DRM_FORMAT_VYUY, 2038 DRM_FORMAT_NV12, 2039 }; 2040 2041 static const u32 glk_planar_formats[] = { 2042 DRM_FORMAT_C8, 2043 DRM_FORMAT_RGB565, 2044 DRM_FORMAT_XRGB8888, 2045 DRM_FORMAT_XBGR8888, 2046 DRM_FORMAT_ARGB8888, 2047 DRM_FORMAT_ABGR8888, 2048 DRM_FORMAT_XRGB2101010, 2049 DRM_FORMAT_XBGR2101010, 2050 DRM_FORMAT_YUYV, 2051 DRM_FORMAT_YVYU, 2052 DRM_FORMAT_UYVY, 2053 DRM_FORMAT_VYUY, 2054 DRM_FORMAT_NV12, 2055 DRM_FORMAT_P010, 2056 DRM_FORMAT_P012, 2057 DRM_FORMAT_P016, 2058 }; 2059 2060 static const u32 icl_sdr_y_plane_formats[] = { 2061 DRM_FORMAT_C8, 2062 DRM_FORMAT_RGB565, 2063 DRM_FORMAT_XRGB8888, 2064 DRM_FORMAT_XBGR8888, 2065 DRM_FORMAT_ARGB8888, 2066 DRM_FORMAT_ABGR8888, 2067 DRM_FORMAT_XRGB2101010, 2068 DRM_FORMAT_XBGR2101010, 2069 DRM_FORMAT_YUYV, 2070 DRM_FORMAT_YVYU, 2071 DRM_FORMAT_UYVY, 2072 DRM_FORMAT_VYUY, 2073 DRM_FORMAT_Y210, 2074 DRM_FORMAT_Y212, 2075 DRM_FORMAT_Y216, 2076 DRM_FORMAT_XVYU2101010, 2077 DRM_FORMAT_XVYU12_16161616, 2078 DRM_FORMAT_XVYU16161616, 2079 }; 2080 2081 static const u32 icl_sdr_uv_plane_formats[] = { 2082 DRM_FORMAT_C8, 2083 DRM_FORMAT_RGB565, 2084 DRM_FORMAT_XRGB8888, 2085 DRM_FORMAT_XBGR8888, 2086 DRM_FORMAT_ARGB8888, 2087 DRM_FORMAT_ABGR8888, 2088 DRM_FORMAT_XRGB2101010, 2089 DRM_FORMAT_XBGR2101010, 2090 DRM_FORMAT_YUYV, 2091 DRM_FORMAT_YVYU, 2092 DRM_FORMAT_UYVY, 2093 DRM_FORMAT_VYUY, 2094 DRM_FORMAT_NV12, 2095 DRM_FORMAT_P010, 2096 DRM_FORMAT_P012, 2097 DRM_FORMAT_P016, 2098 DRM_FORMAT_Y210, 2099 DRM_FORMAT_Y212, 2100 DRM_FORMAT_Y216, 2101 DRM_FORMAT_XVYU2101010, 2102 DRM_FORMAT_XVYU12_16161616, 2103 DRM_FORMAT_XVYU16161616, 2104 }; 2105 2106 static const u32 icl_hdr_plane_formats[] = { 2107 DRM_FORMAT_C8, 2108 DRM_FORMAT_RGB565, 2109 DRM_FORMAT_XRGB8888, 2110 DRM_FORMAT_XBGR8888, 2111 DRM_FORMAT_ARGB8888, 2112 DRM_FORMAT_ABGR8888, 2113 DRM_FORMAT_XRGB2101010, 2114 DRM_FORMAT_XBGR2101010, 2115 DRM_FORMAT_XRGB16161616F, 2116 DRM_FORMAT_XBGR16161616F, 2117 DRM_FORMAT_ARGB16161616F, 2118 DRM_FORMAT_ABGR16161616F, 2119 DRM_FORMAT_YUYV, 2120 DRM_FORMAT_YVYU, 2121 DRM_FORMAT_UYVY, 2122 DRM_FORMAT_VYUY, 2123 DRM_FORMAT_NV12, 2124 DRM_FORMAT_P010, 2125 DRM_FORMAT_P012, 2126 DRM_FORMAT_P016, 2127 DRM_FORMAT_Y210, 2128 DRM_FORMAT_Y212, 2129 DRM_FORMAT_Y216, 2130 DRM_FORMAT_XVYU2101010, 2131 DRM_FORMAT_XVYU12_16161616, 2132 DRM_FORMAT_XVYU16161616, 2133 }; 2134 2135 static const u64 skl_plane_format_modifiers_noccs[] = { 2136 I915_FORMAT_MOD_Yf_TILED, 2137 I915_FORMAT_MOD_Y_TILED, 2138 I915_FORMAT_MOD_X_TILED, 2139 DRM_FORMAT_MOD_LINEAR, 2140 DRM_FORMAT_MOD_INVALID 2141 }; 2142 2143 static const u64 skl_plane_format_modifiers_ccs[] = { 2144 I915_FORMAT_MOD_Yf_TILED_CCS, 2145 I915_FORMAT_MOD_Y_TILED_CCS, 2146 I915_FORMAT_MOD_Yf_TILED, 2147 I915_FORMAT_MOD_Y_TILED, 2148 I915_FORMAT_MOD_X_TILED, 2149 DRM_FORMAT_MOD_LINEAR, 2150 DRM_FORMAT_MOD_INVALID 2151 }; 2152 2153 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane, 2154 u32 format, u64 modifier) 2155 { 2156 switch (modifier) { 2157 case DRM_FORMAT_MOD_LINEAR: 2158 case I915_FORMAT_MOD_X_TILED: 2159 break; 2160 default: 2161 return false; 2162 } 2163 2164 switch (format) { 2165 case DRM_FORMAT_XRGB8888: 2166 case DRM_FORMAT_YUYV: 2167 case DRM_FORMAT_YVYU: 2168 case DRM_FORMAT_UYVY: 2169 case DRM_FORMAT_VYUY: 2170 if (modifier == DRM_FORMAT_MOD_LINEAR || 2171 modifier == I915_FORMAT_MOD_X_TILED) 2172 return true; 2173 /* fall through */ 2174 default: 2175 return false; 2176 } 2177 } 2178 2179 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane, 2180 u32 format, u64 modifier) 2181 { 2182 switch (modifier) { 2183 case DRM_FORMAT_MOD_LINEAR: 2184 case I915_FORMAT_MOD_X_TILED: 2185 break; 2186 default: 2187 return false; 2188 } 2189 2190 switch (format) { 2191 case DRM_FORMAT_XRGB8888: 2192 case DRM_FORMAT_XBGR8888: 2193 case DRM_FORMAT_YUYV: 2194 case DRM_FORMAT_YVYU: 2195 case DRM_FORMAT_UYVY: 2196 case DRM_FORMAT_VYUY: 2197 if (modifier == DRM_FORMAT_MOD_LINEAR || 2198 modifier == I915_FORMAT_MOD_X_TILED) 2199 return true; 2200 /* fall through */ 2201 default: 2202 return false; 2203 } 2204 } 2205 2206 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane, 2207 u32 format, u64 modifier) 2208 { 2209 switch (modifier) { 2210 case DRM_FORMAT_MOD_LINEAR: 2211 case I915_FORMAT_MOD_X_TILED: 2212 break; 2213 default: 2214 return false; 2215 } 2216 2217 switch (format) { 2218 case DRM_FORMAT_RGB565: 2219 case DRM_FORMAT_ABGR8888: 2220 case DRM_FORMAT_ARGB8888: 2221 case DRM_FORMAT_XBGR8888: 2222 case DRM_FORMAT_XRGB8888: 2223 case DRM_FORMAT_XBGR2101010: 2224 case DRM_FORMAT_ABGR2101010: 2225 case DRM_FORMAT_YUYV: 2226 case DRM_FORMAT_YVYU: 2227 case DRM_FORMAT_UYVY: 2228 case DRM_FORMAT_VYUY: 2229 if (modifier == DRM_FORMAT_MOD_LINEAR || 2230 modifier == I915_FORMAT_MOD_X_TILED) 2231 return true; 2232 /* fall through */ 2233 default: 2234 return false; 2235 } 2236 } 2237 2238 static bool skl_plane_format_mod_supported(struct drm_plane *_plane, 2239 u32 format, u64 modifier) 2240 { 2241 struct intel_plane *plane = to_intel_plane(_plane); 2242 2243 switch (modifier) { 2244 case DRM_FORMAT_MOD_LINEAR: 2245 case I915_FORMAT_MOD_X_TILED: 2246 case I915_FORMAT_MOD_Y_TILED: 2247 case I915_FORMAT_MOD_Yf_TILED: 2248 break; 2249 case I915_FORMAT_MOD_Y_TILED_CCS: 2250 case I915_FORMAT_MOD_Yf_TILED_CCS: 2251 if (!plane->has_ccs) 2252 return false; 2253 break; 2254 default: 2255 return false; 2256 } 2257 2258 switch (format) { 2259 case DRM_FORMAT_XRGB8888: 2260 case DRM_FORMAT_XBGR8888: 2261 case DRM_FORMAT_ARGB8888: 2262 case DRM_FORMAT_ABGR8888: 2263 if (is_ccs_modifier(modifier)) 2264 return true; 2265 /* fall through */ 2266 case DRM_FORMAT_RGB565: 2267 case DRM_FORMAT_XRGB2101010: 2268 case DRM_FORMAT_XBGR2101010: 2269 case DRM_FORMAT_YUYV: 2270 case DRM_FORMAT_YVYU: 2271 case DRM_FORMAT_UYVY: 2272 case DRM_FORMAT_VYUY: 2273 case DRM_FORMAT_NV12: 2274 case DRM_FORMAT_P010: 2275 case DRM_FORMAT_P012: 2276 case DRM_FORMAT_P016: 2277 case DRM_FORMAT_XVYU2101010: 2278 if (modifier == I915_FORMAT_MOD_Yf_TILED) 2279 return true; 2280 /* fall through */ 2281 case DRM_FORMAT_C8: 2282 case DRM_FORMAT_XBGR16161616F: 2283 case DRM_FORMAT_ABGR16161616F: 2284 case DRM_FORMAT_XRGB16161616F: 2285 case DRM_FORMAT_ARGB16161616F: 2286 case DRM_FORMAT_Y210: 2287 case DRM_FORMAT_Y212: 2288 case DRM_FORMAT_Y216: 2289 case DRM_FORMAT_XVYU12_16161616: 2290 case DRM_FORMAT_XVYU16161616: 2291 if (modifier == DRM_FORMAT_MOD_LINEAR || 2292 modifier == I915_FORMAT_MOD_X_TILED || 2293 modifier == I915_FORMAT_MOD_Y_TILED) 2294 return true; 2295 /* fall through */ 2296 default: 2297 return false; 2298 } 2299 } 2300 2301 static const struct drm_plane_funcs g4x_sprite_funcs = { 2302 .update_plane = drm_atomic_helper_update_plane, 2303 .disable_plane = drm_atomic_helper_disable_plane, 2304 .destroy = intel_plane_destroy, 2305 .atomic_duplicate_state = intel_plane_duplicate_state, 2306 .atomic_destroy_state = intel_plane_destroy_state, 2307 .format_mod_supported = g4x_sprite_format_mod_supported, 2308 }; 2309 2310 static const struct drm_plane_funcs snb_sprite_funcs = { 2311 .update_plane = drm_atomic_helper_update_plane, 2312 .disable_plane = drm_atomic_helper_disable_plane, 2313 .destroy = intel_plane_destroy, 2314 .atomic_duplicate_state = intel_plane_duplicate_state, 2315 .atomic_destroy_state = intel_plane_destroy_state, 2316 .format_mod_supported = snb_sprite_format_mod_supported, 2317 }; 2318 2319 static const struct drm_plane_funcs vlv_sprite_funcs = { 2320 .update_plane = drm_atomic_helper_update_plane, 2321 .disable_plane = drm_atomic_helper_disable_plane, 2322 .destroy = intel_plane_destroy, 2323 .atomic_duplicate_state = intel_plane_duplicate_state, 2324 .atomic_destroy_state = intel_plane_destroy_state, 2325 .format_mod_supported = vlv_sprite_format_mod_supported, 2326 }; 2327 2328 static const struct drm_plane_funcs skl_plane_funcs = { 2329 .update_plane = drm_atomic_helper_update_plane, 2330 .disable_plane = drm_atomic_helper_disable_plane, 2331 .destroy = intel_plane_destroy, 2332 .atomic_duplicate_state = intel_plane_duplicate_state, 2333 .atomic_destroy_state = intel_plane_destroy_state, 2334 .format_mod_supported = skl_plane_format_mod_supported, 2335 }; 2336 2337 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, 2338 enum pipe pipe, enum plane_id plane_id) 2339 { 2340 if (!HAS_FBC(dev_priv)) 2341 return false; 2342 2343 return pipe == PIPE_A && plane_id == PLANE_PRIMARY; 2344 } 2345 2346 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, 2347 enum pipe pipe, enum plane_id plane_id) 2348 { 2349 /* Display WA #0870: skl, bxt */ 2350 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) 2351 return false; 2352 2353 if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C) 2354 return false; 2355 2356 if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) 2357 return false; 2358 2359 return true; 2360 } 2361 2362 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, 2363 enum pipe pipe, enum plane_id plane_id, 2364 int *num_formats) 2365 { 2366 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2367 *num_formats = ARRAY_SIZE(skl_planar_formats); 2368 return skl_planar_formats; 2369 } else { 2370 *num_formats = ARRAY_SIZE(skl_plane_formats); 2371 return skl_plane_formats; 2372 } 2373 } 2374 2375 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, 2376 enum pipe pipe, enum plane_id plane_id, 2377 int *num_formats) 2378 { 2379 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2380 *num_formats = ARRAY_SIZE(glk_planar_formats); 2381 return glk_planar_formats; 2382 } else { 2383 *num_formats = ARRAY_SIZE(skl_plane_formats); 2384 return skl_plane_formats; 2385 } 2386 } 2387 2388 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv, 2389 enum pipe pipe, enum plane_id plane_id, 2390 int *num_formats) 2391 { 2392 if (icl_is_hdr_plane(dev_priv, plane_id)) { 2393 *num_formats = ARRAY_SIZE(icl_hdr_plane_formats); 2394 return icl_hdr_plane_formats; 2395 } else if (icl_is_nv12_y_plane(plane_id)) { 2396 *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats); 2397 return icl_sdr_y_plane_formats; 2398 } else { 2399 *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats); 2400 return icl_sdr_uv_plane_formats; 2401 } 2402 } 2403 2404 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 2405 enum pipe pipe, enum plane_id plane_id) 2406 { 2407 if (plane_id == PLANE_CURSOR) 2408 return false; 2409 2410 if (INTEL_GEN(dev_priv) >= 10) 2411 return true; 2412 2413 if (IS_GEMINILAKE(dev_priv)) 2414 return pipe != PIPE_C; 2415 2416 return pipe != PIPE_C && 2417 (plane_id == PLANE_PRIMARY || 2418 plane_id == PLANE_SPRITE0); 2419 } 2420 2421 struct intel_plane * 2422 skl_universal_plane_create(struct drm_i915_private *dev_priv, 2423 enum pipe pipe, enum plane_id plane_id) 2424 { 2425 struct intel_plane *plane; 2426 enum drm_plane_type plane_type; 2427 unsigned int supported_rotations; 2428 unsigned int possible_crtcs; 2429 const u64 *modifiers; 2430 const u32 *formats; 2431 int num_formats; 2432 int ret; 2433 2434 plane = intel_plane_alloc(); 2435 if (IS_ERR(plane)) 2436 return plane; 2437 2438 plane->pipe = pipe; 2439 plane->id = plane_id; 2440 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id); 2441 2442 plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id); 2443 if (plane->has_fbc) { 2444 struct intel_fbc *fbc = &dev_priv->fbc; 2445 2446 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; 2447 } 2448 2449 plane->max_stride = skl_plane_max_stride; 2450 plane->update_plane = skl_update_plane; 2451 plane->disable_plane = skl_disable_plane; 2452 plane->get_hw_state = skl_plane_get_hw_state; 2453 plane->check_plane = skl_plane_check; 2454 if (icl_is_nv12_y_plane(plane_id)) 2455 plane->update_slave = icl_update_slave; 2456 2457 if (INTEL_GEN(dev_priv) >= 11) 2458 formats = icl_get_plane_formats(dev_priv, pipe, 2459 plane_id, &num_formats); 2460 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 2461 formats = glk_get_plane_formats(dev_priv, pipe, 2462 plane_id, &num_formats); 2463 else 2464 formats = skl_get_plane_formats(dev_priv, pipe, 2465 plane_id, &num_formats); 2466 2467 plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id); 2468 if (plane->has_ccs) 2469 modifiers = skl_plane_format_modifiers_ccs; 2470 else 2471 modifiers = skl_plane_format_modifiers_noccs; 2472 2473 if (plane_id == PLANE_PRIMARY) 2474 plane_type = DRM_PLANE_TYPE_PRIMARY; 2475 else 2476 plane_type = DRM_PLANE_TYPE_OVERLAY; 2477 2478 possible_crtcs = BIT(pipe); 2479 2480 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 2481 possible_crtcs, &skl_plane_funcs, 2482 formats, num_formats, modifiers, 2483 plane_type, 2484 "plane %d%c", plane_id + 1, 2485 pipe_name(pipe)); 2486 if (ret) 2487 goto fail; 2488 2489 supported_rotations = 2490 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | 2491 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; 2492 2493 if (INTEL_GEN(dev_priv) >= 10) 2494 supported_rotations |= DRM_MODE_REFLECT_X; 2495 2496 drm_plane_create_rotation_property(&plane->base, 2497 DRM_MODE_ROTATE_0, 2498 supported_rotations); 2499 2500 drm_plane_create_color_properties(&plane->base, 2501 BIT(DRM_COLOR_YCBCR_BT601) | 2502 BIT(DRM_COLOR_YCBCR_BT709), 2503 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 2504 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 2505 DRM_COLOR_YCBCR_BT709, 2506 DRM_COLOR_YCBCR_LIMITED_RANGE); 2507 2508 drm_plane_create_alpha_property(&plane->base); 2509 drm_plane_create_blend_mode_property(&plane->base, 2510 BIT(DRM_MODE_BLEND_PIXEL_NONE) | 2511 BIT(DRM_MODE_BLEND_PREMULTI) | 2512 BIT(DRM_MODE_BLEND_COVERAGE)); 2513 2514 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 2515 2516 return plane; 2517 2518 fail: 2519 intel_plane_free(plane); 2520 2521 return ERR_PTR(ret); 2522 } 2523 2524 struct intel_plane * 2525 intel_sprite_plane_create(struct drm_i915_private *dev_priv, 2526 enum pipe pipe, int sprite) 2527 { 2528 struct intel_plane *plane; 2529 const struct drm_plane_funcs *plane_funcs; 2530 unsigned long possible_crtcs; 2531 unsigned int supported_rotations; 2532 const u64 *modifiers; 2533 const u32 *formats; 2534 int num_formats; 2535 int ret; 2536 2537 if (INTEL_GEN(dev_priv) >= 9) 2538 return skl_universal_plane_create(dev_priv, pipe, 2539 PLANE_SPRITE0 + sprite); 2540 2541 plane = intel_plane_alloc(); 2542 if (IS_ERR(plane)) 2543 return plane; 2544 2545 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 2546 plane->max_stride = i9xx_plane_max_stride; 2547 plane->update_plane = vlv_update_plane; 2548 plane->disable_plane = vlv_disable_plane; 2549 plane->get_hw_state = vlv_plane_get_hw_state; 2550 plane->check_plane = vlv_sprite_check; 2551 2552 formats = vlv_plane_formats; 2553 num_formats = ARRAY_SIZE(vlv_plane_formats); 2554 modifiers = i9xx_plane_format_modifiers; 2555 2556 plane_funcs = &vlv_sprite_funcs; 2557 } else if (INTEL_GEN(dev_priv) >= 7) { 2558 plane->max_stride = g4x_sprite_max_stride; 2559 plane->update_plane = ivb_update_plane; 2560 plane->disable_plane = ivb_disable_plane; 2561 plane->get_hw_state = ivb_plane_get_hw_state; 2562 plane->check_plane = g4x_sprite_check; 2563 2564 formats = snb_plane_formats; 2565 num_formats = ARRAY_SIZE(snb_plane_formats); 2566 modifiers = i9xx_plane_format_modifiers; 2567 2568 plane_funcs = &snb_sprite_funcs; 2569 } else { 2570 plane->max_stride = g4x_sprite_max_stride; 2571 plane->update_plane = g4x_update_plane; 2572 plane->disable_plane = g4x_disable_plane; 2573 plane->get_hw_state = g4x_plane_get_hw_state; 2574 plane->check_plane = g4x_sprite_check; 2575 2576 modifiers = i9xx_plane_format_modifiers; 2577 if (IS_GEN(dev_priv, 6)) { 2578 formats = snb_plane_formats; 2579 num_formats = ARRAY_SIZE(snb_plane_formats); 2580 2581 plane_funcs = &snb_sprite_funcs; 2582 } else { 2583 formats = g4x_plane_formats; 2584 num_formats = ARRAY_SIZE(g4x_plane_formats); 2585 2586 plane_funcs = &g4x_sprite_funcs; 2587 } 2588 } 2589 2590 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 2591 supported_rotations = 2592 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 2593 DRM_MODE_REFLECT_X; 2594 } else { 2595 supported_rotations = 2596 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 2597 } 2598 2599 plane->pipe = pipe; 2600 plane->id = PLANE_SPRITE0 + sprite; 2601 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 2602 2603 possible_crtcs = BIT(pipe); 2604 2605 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 2606 possible_crtcs, plane_funcs, 2607 formats, num_formats, modifiers, 2608 DRM_PLANE_TYPE_OVERLAY, 2609 "sprite %c", sprite_name(pipe, sprite)); 2610 if (ret) 2611 goto fail; 2612 2613 drm_plane_create_rotation_property(&plane->base, 2614 DRM_MODE_ROTATE_0, 2615 supported_rotations); 2616 2617 drm_plane_create_color_properties(&plane->base, 2618 BIT(DRM_COLOR_YCBCR_BT601) | 2619 BIT(DRM_COLOR_YCBCR_BT709), 2620 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 2621 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 2622 DRM_COLOR_YCBCR_BT709, 2623 DRM_COLOR_YCBCR_LIMITED_RANGE); 2624 2625 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 2626 2627 return plane; 2628 2629 fail: 2630 intel_plane_free(plane); 2631 2632 return ERR_PTR(ret); 2633 } 2634