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