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