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