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