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