1 /* 2 * Copyright © 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Jesse Barnes <jbarnes@virtuousgeek.org> 25 * 26 * New plane/sprite handling. 27 * 28 * The older chips had a separate interface for programming plane related 29 * registers; newer ones are much simpler and we can use the new DRM plane 30 * support. 31 */ 32 33 #include <drm/drm_atomic.h> 34 #include <drm/drm_atomic_helper.h> 35 #include <drm/drm_color_mgmt.h> 36 #include <drm/drm_crtc.h> 37 #include <drm/drm_damage_helper.h> 38 #include <drm/drm_fourcc.h> 39 #include <drm/drm_plane_helper.h> 40 #include <drm/drm_rect.h> 41 42 #include "i915_drv.h" 43 #include "i915_trace.h" 44 #include "i915_vgpu.h" 45 #include "intel_atomic_plane.h" 46 #include "intel_display_types.h" 47 #include "intel_frontbuffer.h" 48 #include "intel_pm.h" 49 #include "intel_psr.h" 50 #include "intel_sprite.h" 51 52 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 53 int usecs) 54 { 55 /* paranoia */ 56 if (!adjusted_mode->crtc_htotal) 57 return 1; 58 59 return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock, 60 1000 * adjusted_mode->crtc_htotal); 61 } 62 63 /* FIXME: We should instead only take spinlocks once for the entire update 64 * instead of once per mmio. */ 65 #if IS_ENABLED(CONFIG_PROVE_LOCKING) 66 #define VBLANK_EVASION_TIME_US 250 67 #else 68 #define VBLANK_EVASION_TIME_US 100 69 #endif 70 71 /** 72 * intel_pipe_update_start() - start update of a set of display registers 73 * @new_crtc_state: the new crtc state 74 * 75 * Mark the start of an update to pipe registers that should be updated 76 * atomically regarding vblank. If the next vblank will happens within 77 * the next 100 us, this function waits until the vblank passes. 78 * 79 * After a successful call to this function, interrupts will be disabled 80 * until a subsequent call to intel_pipe_update_end(). That is done to 81 * avoid random delays. 82 */ 83 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) 84 { 85 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); 86 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 87 const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode; 88 long timeout = msecs_to_jiffies_timeout(1); 89 int scanline, min, max, vblank_start; 90 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); 91 bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 92 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); 93 DEFINE_WAIT(wait); 94 u32 psr_status; 95 96 vblank_start = adjusted_mode->crtc_vblank_start; 97 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 98 vblank_start = DIV_ROUND_UP(vblank_start, 2); 99 100 /* FIXME needs to be calibrated sensibly */ 101 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode, 102 VBLANK_EVASION_TIME_US); 103 max = vblank_start - 1; 104 105 if (min <= 0 || max <= 0) 106 goto irq_disable; 107 108 if (drm_WARN_ON(&dev_priv->drm, drm_crtc_vblank_get(&crtc->base))) 109 goto irq_disable; 110 111 /* 112 * Wait for psr to idle out after enabling the VBL interrupts 113 * VBL interrupts will start the PSR exit and prevent a PSR 114 * re-entry as well. 115 */ 116 if (intel_psr_wait_for_idle(new_crtc_state, &psr_status)) 117 drm_err(&dev_priv->drm, 118 "PSR idle timed out 0x%x, atomic update may fail\n", 119 psr_status); 120 121 local_irq_disable(); 122 123 crtc->debug.min_vbl = min; 124 crtc->debug.max_vbl = max; 125 trace_intel_pipe_update_start(crtc); 126 127 for (;;) { 128 /* 129 * prepare_to_wait() has a memory barrier, which guarantees 130 * other CPUs can see the task state update by the time we 131 * read the scanline. 132 */ 133 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); 134 135 scanline = intel_get_crtc_scanline(crtc); 136 if (scanline < min || scanline > max) 137 break; 138 139 if (!timeout) { 140 drm_err(&dev_priv->drm, 141 "Potential atomic update failure on pipe %c\n", 142 pipe_name(crtc->pipe)); 143 break; 144 } 145 146 local_irq_enable(); 147 148 timeout = schedule_timeout(timeout); 149 150 local_irq_disable(); 151 } 152 153 finish_wait(wq, &wait); 154 155 drm_crtc_vblank_put(&crtc->base); 156 157 /* 158 * On VLV/CHV DSI the scanline counter would appear to 159 * increment approx. 1/3 of a scanline before start of vblank. 160 * The registers still get latched at start of vblank however. 161 * This means we must not write any registers on the first 162 * line of vblank (since not the whole line is actually in 163 * vblank). And unfortunately we can't use the interrupt to 164 * wait here since it will fire too soon. We could use the 165 * frame start interrupt instead since it will fire after the 166 * critical scanline, but that would require more changes 167 * in the interrupt code. So for now we'll just do the nasty 168 * thing and poll for the bad scanline to pass us by. 169 * 170 * FIXME figure out if BXT+ DSI suffers from this as well 171 */ 172 while (need_vlv_dsi_wa && scanline == vblank_start) 173 scanline = intel_get_crtc_scanline(crtc); 174 175 crtc->debug.scanline_start = scanline; 176 crtc->debug.start_vbl_time = ktime_get(); 177 crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); 178 179 trace_intel_pipe_update_vblank_evaded(crtc); 180 return; 181 182 irq_disable: 183 local_irq_disable(); 184 } 185 186 /** 187 * intel_pipe_update_end() - end update of a set of display registers 188 * @new_crtc_state: the new crtc state 189 * 190 * Mark the end of an update started with intel_pipe_update_start(). This 191 * re-enables interrupts and verifies the update was actually completed 192 * before a vblank. 193 */ 194 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) 195 { 196 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); 197 enum pipe pipe = crtc->pipe; 198 int scanline_end = intel_get_crtc_scanline(crtc); 199 u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc); 200 ktime_t end_vbl_time = ktime_get(); 201 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 202 203 trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end); 204 205 /* We're still in the vblank-evade critical section, this can't race. 206 * Would be slightly nice to just grab the vblank count and arm the 207 * event outside of the critical section - the spinlock might spin for a 208 * while ... */ 209 if (new_crtc_state->uapi.event) { 210 drm_WARN_ON(&dev_priv->drm, 211 drm_crtc_vblank_get(&crtc->base) != 0); 212 213 spin_lock(&crtc->base.dev->event_lock); 214 drm_crtc_arm_vblank_event(&crtc->base, 215 new_crtc_state->uapi.event); 216 spin_unlock(&crtc->base.dev->event_lock); 217 218 new_crtc_state->uapi.event = NULL; 219 } 220 221 local_irq_enable(); 222 223 if (intel_vgpu_active(dev_priv)) 224 return; 225 226 if (crtc->debug.start_vbl_count && 227 crtc->debug.start_vbl_count != end_vbl_count) { 228 drm_err(&dev_priv->drm, 229 "Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", 230 pipe_name(pipe), crtc->debug.start_vbl_count, 231 end_vbl_count, 232 ktime_us_delta(end_vbl_time, 233 crtc->debug.start_vbl_time), 234 crtc->debug.min_vbl, crtc->debug.max_vbl, 235 crtc->debug.scanline_start, scanline_end); 236 } 237 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE 238 else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) > 239 VBLANK_EVASION_TIME_US) 240 drm_warn(&dev_priv->drm, 241 "Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n", 242 pipe_name(pipe), 243 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 244 VBLANK_EVASION_TIME_US); 245 #endif 246 } 247 248 int intel_plane_check_stride(const struct intel_plane_state *plane_state) 249 { 250 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 251 const struct drm_framebuffer *fb = plane_state->hw.fb; 252 unsigned int rotation = plane_state->hw.rotation; 253 u32 stride, max_stride; 254 255 /* 256 * We ignore stride for all invisible planes that 257 * can be remapped. Otherwise we could end up 258 * with a false positive when the remapping didn't 259 * kick in due the plane being invisible. 260 */ 261 if (intel_plane_can_remap(plane_state) && 262 !plane_state->uapi.visible) 263 return 0; 264 265 /* FIXME other color planes? */ 266 stride = plane_state->color_plane[0].stride; 267 max_stride = plane->max_stride(plane, fb->format->format, 268 fb->modifier, rotation); 269 270 if (stride > max_stride) { 271 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n", 272 fb->base.id, stride, 273 plane->base.base.id, plane->base.name, max_stride); 274 return -EINVAL; 275 } 276 277 return 0; 278 } 279 280 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) 281 { 282 const struct drm_framebuffer *fb = plane_state->hw.fb; 283 struct drm_rect *src = &plane_state->uapi.src; 284 u32 src_x, src_y, src_w, src_h, hsub, vsub; 285 bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation); 286 287 /* 288 * FIXME hsub/vsub vs. block size is a mess. Pre-tgl CCS 289 * abuses hsub/vsub so we can't use them here. But as they 290 * are limited to 32bpp RGB formats we don't actually need 291 * to check anything. 292 */ 293 if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 294 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) 295 return 0; 296 297 /* 298 * Hardware doesn't handle subpixel coordinates. 299 * Adjust to (macro)pixel boundary, but be careful not to 300 * increase the source viewport size, because that could 301 * push the downscaling factor out of bounds. 302 */ 303 src_x = src->x1 >> 16; 304 src_w = drm_rect_width(src) >> 16; 305 src_y = src->y1 >> 16; 306 src_h = drm_rect_height(src) >> 16; 307 308 drm_rect_init(src, src_x << 16, src_y << 16, 309 src_w << 16, src_h << 16); 310 311 if (fb->format->format == DRM_FORMAT_RGB565 && rotated) { 312 hsub = 2; 313 vsub = 2; 314 } else { 315 hsub = fb->format->hsub; 316 vsub = fb->format->vsub; 317 } 318 319 if (rotated) 320 hsub = vsub = max(hsub, vsub); 321 322 if (src_x % hsub || src_w % hsub) { 323 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n", 324 src_x, src_w, hsub, yesno(rotated)); 325 return -EINVAL; 326 } 327 328 if (src_y % vsub || src_h % vsub) { 329 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n", 330 src_y, src_h, vsub, yesno(rotated)); 331 return -EINVAL; 332 } 333 334 return 0; 335 } 336 337 static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915) 338 { 339 if (IS_ROCKETLAKE(i915)) 340 return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3); 341 else 342 return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5); 343 } 344 345 bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv, 346 enum plane_id plane_id) 347 { 348 return INTEL_GEN(dev_priv) >= 11 && 349 icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id); 350 } 351 352 bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id) 353 { 354 return INTEL_GEN(dev_priv) >= 11 && 355 icl_hdr_plane_mask() & BIT(plane_id); 356 } 357 358 static void 359 skl_plane_ratio(const struct intel_crtc_state *crtc_state, 360 const struct intel_plane_state *plane_state, 361 unsigned int *num, unsigned int *den) 362 { 363 struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev); 364 const struct drm_framebuffer *fb = plane_state->hw.fb; 365 366 if (fb->format->cpp[0] == 8) { 367 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { 368 *num = 10; 369 *den = 8; 370 } else { 371 *num = 9; 372 *den = 8; 373 } 374 } else { 375 *num = 1; 376 *den = 1; 377 } 378 } 379 380 static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 381 const struct intel_plane_state *plane_state) 382 { 383 struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev); 384 unsigned int num, den; 385 unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state); 386 387 skl_plane_ratio(crtc_state, plane_state, &num, &den); 388 389 /* two pixels per clock on glk+ */ 390 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 391 den *= 2; 392 393 return DIV_ROUND_UP(pixel_rate * num, den); 394 } 395 396 static unsigned int 397 skl_plane_max_stride(struct intel_plane *plane, 398 u32 pixel_format, u64 modifier, 399 unsigned int rotation) 400 { 401 const struct drm_format_info *info = drm_format_info(pixel_format); 402 int cpp = info->cpp[0]; 403 404 /* 405 * "The stride in bytes must not exceed the 406 * of the size of 8K pixels and 32K bytes." 407 */ 408 if (drm_rotation_90_or_270(rotation)) 409 return min(8192, 32768 / cpp); 410 else 411 return min(8192 * cpp, 32768); 412 } 413 414 static void 415 skl_program_scaler(struct intel_plane *plane, 416 const struct intel_crtc_state *crtc_state, 417 const struct intel_plane_state *plane_state) 418 { 419 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 420 const struct drm_framebuffer *fb = plane_state->hw.fb; 421 enum pipe pipe = plane->pipe; 422 int scaler_id = plane_state->scaler_id; 423 const struct intel_scaler *scaler = 424 &crtc_state->scaler_state.scalers[scaler_id]; 425 int crtc_x = plane_state->uapi.dst.x1; 426 int crtc_y = plane_state->uapi.dst.y1; 427 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 428 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 429 u16 y_hphase, uv_rgb_hphase; 430 u16 y_vphase, uv_rgb_vphase; 431 int hscale, vscale; 432 433 hscale = drm_rect_calc_hscale(&plane_state->uapi.src, 434 &plane_state->uapi.dst, 435 0, INT_MAX); 436 vscale = drm_rect_calc_vscale(&plane_state->uapi.src, 437 &plane_state->uapi.dst, 438 0, INT_MAX); 439 440 /* TODO: handle sub-pixel coordinates */ 441 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 442 !icl_is_hdr_plane(dev_priv, plane->id)) { 443 y_hphase = skl_scaler_calc_phase(1, hscale, false); 444 y_vphase = skl_scaler_calc_phase(1, vscale, false); 445 446 /* MPEG2 chroma siting convention */ 447 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true); 448 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false); 449 } else { 450 /* not used */ 451 y_hphase = 0; 452 y_vphase = 0; 453 454 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false); 455 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); 456 } 457 458 intel_de_write_fw(dev_priv, SKL_PS_CTRL(pipe, scaler_id), 459 PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode); 460 intel_de_write_fw(dev_priv, SKL_PS_VPHASE(pipe, scaler_id), 461 PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); 462 intel_de_write_fw(dev_priv, SKL_PS_HPHASE(pipe, scaler_id), 463 PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); 464 intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(pipe, scaler_id), 465 (crtc_x << 16) | crtc_y); 466 intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(pipe, scaler_id), 467 (crtc_w << 16) | crtc_h); 468 } 469 470 /* Preoffset values for YUV to RGB Conversion */ 471 #define PREOFF_YUV_TO_RGB_HI 0x1800 472 #define PREOFF_YUV_TO_RGB_ME 0x1F00 473 #define PREOFF_YUV_TO_RGB_LO 0x1800 474 475 #define ROFF(x) (((x) & 0xffff) << 16) 476 #define GOFF(x) (((x) & 0xffff) << 0) 477 #define BOFF(x) (((x) & 0xffff) << 16) 478 479 static void 480 icl_program_input_csc(struct intel_plane *plane, 481 const struct intel_crtc_state *crtc_state, 482 const struct intel_plane_state *plane_state) 483 { 484 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 485 enum pipe pipe = plane->pipe; 486 enum plane_id plane_id = plane->id; 487 488 static const u16 input_csc_matrix[][9] = { 489 /* 490 * BT.601 full range YCbCr -> full range RGB 491 * The matrix required is : 492 * [1.000, 0.000, 1.371, 493 * 1.000, -0.336, -0.698, 494 * 1.000, 1.732, 0.0000] 495 */ 496 [DRM_COLOR_YCBCR_BT601] = { 497 0x7AF8, 0x7800, 0x0, 498 0x8B28, 0x7800, 0x9AC0, 499 0x0, 0x7800, 0x7DD8, 500 }, 501 /* 502 * BT.709 full range YCbCr -> full range RGB 503 * The matrix required is : 504 * [1.000, 0.000, 1.574, 505 * 1.000, -0.187, -0.468, 506 * 1.000, 1.855, 0.0000] 507 */ 508 [DRM_COLOR_YCBCR_BT709] = { 509 0x7C98, 0x7800, 0x0, 510 0x9EF8, 0x7800, 0xAC00, 511 0x0, 0x7800, 0x7ED8, 512 }, 513 /* 514 * BT.2020 full range YCbCr -> full range RGB 515 * The matrix required is : 516 * [1.000, 0.000, 1.474, 517 * 1.000, -0.1645, -0.5713, 518 * 1.000, 1.8814, 0.0000] 519 */ 520 [DRM_COLOR_YCBCR_BT2020] = { 521 0x7BC8, 0x7800, 0x0, 522 0x8928, 0x7800, 0xAA88, 523 0x0, 0x7800, 0x7F10, 524 }, 525 }; 526 527 /* Matrix for Limited Range to Full Range Conversion */ 528 static const u16 input_csc_matrix_lr[][9] = { 529 /* 530 * BT.601 Limted range YCbCr -> full range RGB 531 * The matrix required is : 532 * [1.164384, 0.000, 1.596027, 533 * 1.164384, -0.39175, -0.812813, 534 * 1.164384, 2.017232, 0.0000] 535 */ 536 [DRM_COLOR_YCBCR_BT601] = { 537 0x7CC8, 0x7950, 0x0, 538 0x8D00, 0x7950, 0x9C88, 539 0x0, 0x7950, 0x6810, 540 }, 541 /* 542 * BT.709 Limited range YCbCr -> full range RGB 543 * The matrix required is : 544 * [1.164384, 0.000, 1.792741, 545 * 1.164384, -0.213249, -0.532909, 546 * 1.164384, 2.112402, 0.0000] 547 */ 548 [DRM_COLOR_YCBCR_BT709] = { 549 0x7E58, 0x7950, 0x0, 550 0x8888, 0x7950, 0xADA8, 551 0x0, 0x7950, 0x6870, 552 }, 553 /* 554 * BT.2020 Limited range YCbCr -> full range RGB 555 * The matrix required is : 556 * [1.164, 0.000, 1.678, 557 * 1.164, -0.1873, -0.6504, 558 * 1.164, 2.1417, 0.0000] 559 */ 560 [DRM_COLOR_YCBCR_BT2020] = { 561 0x7D70, 0x7950, 0x0, 562 0x8A68, 0x7950, 0xAC00, 563 0x0, 0x7950, 0x6890, 564 }, 565 }; 566 const u16 *csc; 567 568 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 569 csc = input_csc_matrix[plane_state->hw.color_encoding]; 570 else 571 csc = input_csc_matrix_lr[plane_state->hw.color_encoding]; 572 573 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), 574 ROFF(csc[0]) | GOFF(csc[1])); 575 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), 576 BOFF(csc[2])); 577 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), 578 ROFF(csc[3]) | GOFF(csc[4])); 579 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), 580 BOFF(csc[5])); 581 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), 582 ROFF(csc[6]) | GOFF(csc[7])); 583 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), 584 BOFF(csc[8])); 585 586 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), 587 PREOFF_YUV_TO_RGB_HI); 588 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 589 intel_de_write_fw(dev_priv, 590 PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 591 0); 592 else 593 intel_de_write_fw(dev_priv, 594 PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 595 PREOFF_YUV_TO_RGB_ME); 596 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), 597 PREOFF_YUV_TO_RGB_LO); 598 intel_de_write_fw(dev_priv, 599 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0); 600 intel_de_write_fw(dev_priv, 601 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0); 602 intel_de_write_fw(dev_priv, 603 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0); 604 } 605 606 static void 607 skl_program_plane(struct intel_plane *plane, 608 const struct intel_crtc_state *crtc_state, 609 const struct intel_plane_state *plane_state, 610 int color_plane) 611 { 612 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 613 enum plane_id plane_id = plane->id; 614 enum pipe pipe = plane->pipe; 615 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 616 u32 surf_addr = plane_state->color_plane[color_plane].offset; 617 u32 stride = skl_plane_stride(plane_state, color_plane); 618 const struct drm_framebuffer *fb = plane_state->hw.fb; 619 int aux_plane = intel_main_to_aux_plane(fb, color_plane); 620 u32 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr; 621 u32 aux_stride = skl_plane_stride(plane_state, aux_plane); 622 int crtc_x = plane_state->uapi.dst.x1; 623 int crtc_y = plane_state->uapi.dst.y1; 624 u32 x = plane_state->color_plane[color_plane].x; 625 u32 y = plane_state->color_plane[color_plane].y; 626 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 627 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 628 u8 alpha = plane_state->hw.alpha >> 8; 629 u32 plane_color_ctl = 0; 630 unsigned long irqflags; 631 u32 keymsk, keymax; 632 u32 plane_ctl = plane_state->ctl; 633 634 plane_ctl |= skl_plane_ctl_crtc(crtc_state); 635 636 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 637 plane_color_ctl = plane_state->color_ctl | 638 glk_plane_color_ctl_crtc(crtc_state); 639 640 /* Sizes are 0 based */ 641 src_w--; 642 src_h--; 643 644 keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha); 645 646 keymsk = key->channel_mask & 0x7ffffff; 647 if (alpha < 0xff) 648 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE; 649 650 /* The scaler will handle the output position */ 651 if (plane_state->scaler_id >= 0) { 652 crtc_x = 0; 653 crtc_y = 0; 654 } 655 656 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 657 658 intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride); 659 intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id), 660 (crtc_y << 16) | crtc_x); 661 intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id), 662 (src_h << 16) | src_w); 663 664 if (INTEL_GEN(dev_priv) < 12) 665 aux_dist |= aux_stride; 666 intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist); 667 668 if (icl_is_hdr_plane(dev_priv, plane_id)) 669 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 670 plane_state->cus_ctl); 671 672 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 673 intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 674 plane_color_ctl); 675 676 if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id)) 677 icl_program_input_csc(plane, crtc_state, plane_state); 678 679 skl_write_plane_wm(plane, crtc_state); 680 681 intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), 682 key->min_value); 683 intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk); 684 intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax); 685 686 intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id), 687 (y << 16) | x); 688 689 if (INTEL_GEN(dev_priv) < 11) 690 intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id), 691 (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x); 692 693 /* 694 * The control register self-arms if the plane was previously 695 * disabled. Try to make the plane enable atomic by writing 696 * the control register just before the surface register. 697 */ 698 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); 699 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 700 intel_plane_ggtt_offset(plane_state) + surf_addr); 701 702 if (plane_state->scaler_id >= 0) 703 skl_program_scaler(plane, crtc_state, plane_state); 704 705 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 706 } 707 708 static void 709 skl_update_plane(struct intel_plane *plane, 710 const struct intel_crtc_state *crtc_state, 711 const struct intel_plane_state *plane_state) 712 { 713 int color_plane = 0; 714 715 if (plane_state->planar_linked_plane && !plane_state->planar_slave) 716 /* Program the UV plane on planar master */ 717 color_plane = 1; 718 719 skl_program_plane(plane, crtc_state, plane_state, color_plane); 720 } 721 static void 722 skl_disable_plane(struct intel_plane *plane, 723 const struct intel_crtc_state *crtc_state) 724 { 725 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 726 enum plane_id plane_id = plane->id; 727 enum pipe pipe = plane->pipe; 728 unsigned long irqflags; 729 730 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 731 732 if (icl_is_hdr_plane(dev_priv, plane_id)) 733 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0); 734 735 skl_write_plane_wm(plane, crtc_state); 736 737 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0); 738 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0); 739 740 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 741 } 742 743 static bool 744 skl_plane_get_hw_state(struct intel_plane *plane, 745 enum pipe *pipe) 746 { 747 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 748 enum intel_display_power_domain power_domain; 749 enum plane_id plane_id = plane->id; 750 intel_wakeref_t wakeref; 751 bool ret; 752 753 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 754 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 755 if (!wakeref) 756 return false; 757 758 ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; 759 760 *pipe = plane->pipe; 761 762 intel_display_power_put(dev_priv, power_domain, wakeref); 763 764 return ret; 765 } 766 767 static void i9xx_plane_linear_gamma(u16 gamma[8]) 768 { 769 /* The points are not evenly spaced. */ 770 static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 }; 771 int i; 772 773 for (i = 0; i < 8; i++) 774 gamma[i] = (in[i] << 8) / 32; 775 } 776 777 static void 778 chv_update_csc(const struct intel_plane_state *plane_state) 779 { 780 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 781 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 782 const struct drm_framebuffer *fb = plane_state->hw.fb; 783 enum plane_id plane_id = plane->id; 784 /* 785 * |r| | c0 c1 c2 | |cr| 786 * |g| = | c3 c4 c5 | x |y | 787 * |b| | c6 c7 c8 | |cb| 788 * 789 * Coefficients are s3.12. 790 * 791 * Cb and Cr apparently come in as signed already, and 792 * we always get full range data in on account of CLRC0/1. 793 */ 794 static const s16 csc_matrix[][9] = { 795 /* BT.601 full range YCbCr -> full range RGB */ 796 [DRM_COLOR_YCBCR_BT601] = { 797 5743, 4096, 0, 798 -2925, 4096, -1410, 799 0, 4096, 7258, 800 }, 801 /* BT.709 full range YCbCr -> full range RGB */ 802 [DRM_COLOR_YCBCR_BT709] = { 803 6450, 4096, 0, 804 -1917, 4096, -767, 805 0, 4096, 7601, 806 }, 807 }; 808 const s16 *csc = csc_matrix[plane_state->hw.color_encoding]; 809 810 /* Seems RGB data bypasses the CSC always */ 811 if (!fb->format->is_yuv) 812 return; 813 814 intel_de_write_fw(dev_priv, SPCSCYGOFF(plane_id), 815 SPCSC_OOFF(0) | SPCSC_IOFF(0)); 816 intel_de_write_fw(dev_priv, SPCSCCBOFF(plane_id), 817 SPCSC_OOFF(0) | SPCSC_IOFF(0)); 818 intel_de_write_fw(dev_priv, SPCSCCROFF(plane_id), 819 SPCSC_OOFF(0) | SPCSC_IOFF(0)); 820 821 intel_de_write_fw(dev_priv, SPCSCC01(plane_id), 822 SPCSC_C1(csc[1]) | SPCSC_C0(csc[0])); 823 intel_de_write_fw(dev_priv, SPCSCC23(plane_id), 824 SPCSC_C1(csc[3]) | SPCSC_C0(csc[2])); 825 intel_de_write_fw(dev_priv, SPCSCC45(plane_id), 826 SPCSC_C1(csc[5]) | SPCSC_C0(csc[4])); 827 intel_de_write_fw(dev_priv, SPCSCC67(plane_id), 828 SPCSC_C1(csc[7]) | SPCSC_C0(csc[6])); 829 intel_de_write_fw(dev_priv, SPCSCC8(plane_id), SPCSC_C0(csc[8])); 830 831 intel_de_write_fw(dev_priv, SPCSCYGICLAMP(plane_id), 832 SPCSC_IMAX(1023) | SPCSC_IMIN(0)); 833 intel_de_write_fw(dev_priv, SPCSCCBICLAMP(plane_id), 834 SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 835 intel_de_write_fw(dev_priv, SPCSCCRICLAMP(plane_id), 836 SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 837 838 intel_de_write_fw(dev_priv, SPCSCYGOCLAMP(plane_id), 839 SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 840 intel_de_write_fw(dev_priv, SPCSCCBOCLAMP(plane_id), 841 SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 842 intel_de_write_fw(dev_priv, SPCSCCROCLAMP(plane_id), 843 SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 844 } 845 846 #define SIN_0 0 847 #define COS_0 1 848 849 static void 850 vlv_update_clrc(const struct intel_plane_state *plane_state) 851 { 852 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 853 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 854 const struct drm_framebuffer *fb = plane_state->hw.fb; 855 enum pipe pipe = plane->pipe; 856 enum plane_id plane_id = plane->id; 857 int contrast, brightness, sh_scale, sh_sin, sh_cos; 858 859 if (fb->format->is_yuv && 860 plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) { 861 /* 862 * Expand limited range to full range: 863 * Contrast is applied first and is used to expand Y range. 864 * Brightness is applied second and is used to remove the 865 * offset from Y. Saturation/hue is used to expand CbCr range. 866 */ 867 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16); 868 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16); 869 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128); 870 sh_sin = SIN_0 * sh_scale; 871 sh_cos = COS_0 * sh_scale; 872 } else { 873 /* Pass-through everything. */ 874 contrast = 1 << 6; 875 brightness = 0; 876 sh_scale = 1 << 7; 877 sh_sin = SIN_0 * sh_scale; 878 sh_cos = COS_0 * sh_scale; 879 } 880 881 /* FIXME these register are single buffered :( */ 882 intel_de_write_fw(dev_priv, SPCLRC0(pipe, plane_id), 883 SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness)); 884 intel_de_write_fw(dev_priv, SPCLRC1(pipe, plane_id), 885 SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos)); 886 } 887 888 static void 889 vlv_plane_ratio(const struct intel_crtc_state *crtc_state, 890 const struct intel_plane_state *plane_state, 891 unsigned int *num, unsigned int *den) 892 { 893 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 894 const struct drm_framebuffer *fb = plane_state->hw.fb; 895 unsigned int cpp = fb->format->cpp[0]; 896 897 /* 898 * VLV bspec only considers cases where all three planes are 899 * enabled, and cases where the primary and one sprite is enabled. 900 * Let's assume the case with just two sprites enabled also 901 * maps to the latter case. 902 */ 903 if (hweight8(active_planes) == 3) { 904 switch (cpp) { 905 case 8: 906 *num = 11; 907 *den = 8; 908 break; 909 case 4: 910 *num = 18; 911 *den = 16; 912 break; 913 default: 914 *num = 1; 915 *den = 1; 916 break; 917 } 918 } else if (hweight8(active_planes) == 2) { 919 switch (cpp) { 920 case 8: 921 *num = 10; 922 *den = 8; 923 break; 924 case 4: 925 *num = 17; 926 *den = 16; 927 break; 928 default: 929 *num = 1; 930 *den = 1; 931 break; 932 } 933 } else { 934 switch (cpp) { 935 case 8: 936 *num = 10; 937 *den = 8; 938 break; 939 default: 940 *num = 1; 941 *den = 1; 942 break; 943 } 944 } 945 } 946 947 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 948 const struct intel_plane_state *plane_state) 949 { 950 unsigned int pixel_rate; 951 unsigned int num, den; 952 953 /* 954 * Note that crtc_state->pixel_rate accounts for both 955 * horizontal and vertical panel fitter downscaling factors. 956 * Pre-HSW bspec tells us to only consider the horizontal 957 * downscaling factor here. We ignore that and just consider 958 * both for simplicity. 959 */ 960 pixel_rate = crtc_state->pixel_rate; 961 962 vlv_plane_ratio(crtc_state, plane_state, &num, &den); 963 964 return DIV_ROUND_UP(pixel_rate * num, den); 965 } 966 967 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 968 { 969 u32 sprctl = 0; 970 971 if (crtc_state->gamma_enable) 972 sprctl |= SP_GAMMA_ENABLE; 973 974 return sprctl; 975 } 976 977 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, 978 const struct intel_plane_state *plane_state) 979 { 980 const struct drm_framebuffer *fb = plane_state->hw.fb; 981 unsigned int rotation = plane_state->hw.rotation; 982 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 983 u32 sprctl; 984 985 sprctl = SP_ENABLE; 986 987 switch (fb->format->format) { 988 case DRM_FORMAT_YUYV: 989 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 990 break; 991 case DRM_FORMAT_YVYU: 992 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 993 break; 994 case DRM_FORMAT_UYVY: 995 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 996 break; 997 case DRM_FORMAT_VYUY: 998 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 999 break; 1000 case DRM_FORMAT_C8: 1001 sprctl |= SP_FORMAT_8BPP; 1002 break; 1003 case DRM_FORMAT_RGB565: 1004 sprctl |= SP_FORMAT_BGR565; 1005 break; 1006 case DRM_FORMAT_XRGB8888: 1007 sprctl |= SP_FORMAT_BGRX8888; 1008 break; 1009 case DRM_FORMAT_ARGB8888: 1010 sprctl |= SP_FORMAT_BGRA8888; 1011 break; 1012 case DRM_FORMAT_XBGR2101010: 1013 sprctl |= SP_FORMAT_RGBX1010102; 1014 break; 1015 case DRM_FORMAT_ABGR2101010: 1016 sprctl |= SP_FORMAT_RGBA1010102; 1017 break; 1018 case DRM_FORMAT_XRGB2101010: 1019 sprctl |= SP_FORMAT_BGRX1010102; 1020 break; 1021 case DRM_FORMAT_ARGB2101010: 1022 sprctl |= SP_FORMAT_BGRA1010102; 1023 break; 1024 case DRM_FORMAT_XBGR8888: 1025 sprctl |= SP_FORMAT_RGBX8888; 1026 break; 1027 case DRM_FORMAT_ABGR8888: 1028 sprctl |= SP_FORMAT_RGBA8888; 1029 break; 1030 default: 1031 MISSING_CASE(fb->format->format); 1032 return 0; 1033 } 1034 1035 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 1036 sprctl |= SP_YUV_FORMAT_BT709; 1037 1038 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1039 sprctl |= SP_TILED; 1040 1041 if (rotation & DRM_MODE_ROTATE_180) 1042 sprctl |= SP_ROTATE_180; 1043 1044 if (rotation & DRM_MODE_REFLECT_X) 1045 sprctl |= SP_MIRROR; 1046 1047 if (key->flags & I915_SET_COLORKEY_SOURCE) 1048 sprctl |= SP_SOURCE_KEY; 1049 1050 return sprctl; 1051 } 1052 1053 static void vlv_update_gamma(const struct intel_plane_state *plane_state) 1054 { 1055 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1056 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1057 const struct drm_framebuffer *fb = plane_state->hw.fb; 1058 enum pipe pipe = plane->pipe; 1059 enum plane_id plane_id = plane->id; 1060 u16 gamma[8]; 1061 int i; 1062 1063 /* Seems RGB data bypasses the gamma always */ 1064 if (!fb->format->is_yuv) 1065 return; 1066 1067 i9xx_plane_linear_gamma(gamma); 1068 1069 /* FIXME these register are single buffered :( */ 1070 /* The two end points are implicit (0.0 and 1.0) */ 1071 for (i = 1; i < 8 - 1; i++) 1072 intel_de_write_fw(dev_priv, SPGAMC(pipe, plane_id, i - 1), 1073 gamma[i] << 16 | gamma[i] << 8 | gamma[i]); 1074 } 1075 1076 static void 1077 vlv_update_plane(struct intel_plane *plane, 1078 const struct intel_crtc_state *crtc_state, 1079 const struct intel_plane_state *plane_state) 1080 { 1081 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1082 enum pipe pipe = plane->pipe; 1083 enum plane_id plane_id = plane->id; 1084 u32 sprsurf_offset = plane_state->color_plane[0].offset; 1085 u32 linear_offset; 1086 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1087 int crtc_x = plane_state->uapi.dst.x1; 1088 int crtc_y = plane_state->uapi.dst.y1; 1089 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1090 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1091 u32 x = plane_state->color_plane[0].x; 1092 u32 y = plane_state->color_plane[0].y; 1093 unsigned long irqflags; 1094 u32 sprctl; 1095 1096 sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state); 1097 1098 /* Sizes are 0 based */ 1099 crtc_w--; 1100 crtc_h--; 1101 1102 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1103 1104 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1105 1106 intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id), 1107 plane_state->color_plane[0].stride); 1108 intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id), 1109 (crtc_y << 16) | crtc_x); 1110 intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id), 1111 (crtc_h << 16) | crtc_w); 1112 intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0); 1113 1114 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 1115 chv_update_csc(plane_state); 1116 1117 if (key->flags) { 1118 intel_de_write_fw(dev_priv, SPKEYMINVAL(pipe, plane_id), 1119 key->min_value); 1120 intel_de_write_fw(dev_priv, SPKEYMSK(pipe, plane_id), 1121 key->channel_mask); 1122 intel_de_write_fw(dev_priv, SPKEYMAXVAL(pipe, plane_id), 1123 key->max_value); 1124 } 1125 1126 intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset); 1127 intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id), (y << 16) | x); 1128 1129 /* 1130 * The control register self-arms if the plane was previously 1131 * disabled. Try to make the plane enable atomic by writing 1132 * the control register just before the surface register. 1133 */ 1134 intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), sprctl); 1135 intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 1136 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1137 1138 vlv_update_clrc(plane_state); 1139 vlv_update_gamma(plane_state); 1140 1141 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1142 } 1143 1144 static void 1145 vlv_disable_plane(struct intel_plane *plane, 1146 const struct intel_crtc_state *crtc_state) 1147 { 1148 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1149 enum pipe pipe = plane->pipe; 1150 enum plane_id plane_id = plane->id; 1151 unsigned long irqflags; 1152 1153 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1154 1155 intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), 0); 1156 intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 0); 1157 1158 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1159 } 1160 1161 static bool 1162 vlv_plane_get_hw_state(struct intel_plane *plane, 1163 enum pipe *pipe) 1164 { 1165 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1166 enum intel_display_power_domain power_domain; 1167 enum plane_id plane_id = plane->id; 1168 intel_wakeref_t wakeref; 1169 bool ret; 1170 1171 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1172 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1173 if (!wakeref) 1174 return false; 1175 1176 ret = intel_de_read(dev_priv, SPCNTR(plane->pipe, plane_id)) & SP_ENABLE; 1177 1178 *pipe = plane->pipe; 1179 1180 intel_display_power_put(dev_priv, power_domain, wakeref); 1181 1182 return ret; 1183 } 1184 1185 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state, 1186 const struct intel_plane_state *plane_state, 1187 unsigned int *num, unsigned int *den) 1188 { 1189 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 1190 const struct drm_framebuffer *fb = plane_state->hw.fb; 1191 unsigned int cpp = fb->format->cpp[0]; 1192 1193 if (hweight8(active_planes) == 2) { 1194 switch (cpp) { 1195 case 8: 1196 *num = 10; 1197 *den = 8; 1198 break; 1199 case 4: 1200 *num = 17; 1201 *den = 16; 1202 break; 1203 default: 1204 *num = 1; 1205 *den = 1; 1206 break; 1207 } 1208 } else { 1209 switch (cpp) { 1210 case 8: 1211 *num = 9; 1212 *den = 8; 1213 break; 1214 default: 1215 *num = 1; 1216 *den = 1; 1217 break; 1218 } 1219 } 1220 } 1221 1222 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state, 1223 const struct intel_plane_state *plane_state, 1224 unsigned int *num, unsigned int *den) 1225 { 1226 const struct drm_framebuffer *fb = plane_state->hw.fb; 1227 unsigned int cpp = fb->format->cpp[0]; 1228 1229 switch (cpp) { 1230 case 8: 1231 *num = 12; 1232 *den = 8; 1233 break; 1234 case 4: 1235 *num = 19; 1236 *den = 16; 1237 break; 1238 case 2: 1239 *num = 33; 1240 *den = 32; 1241 break; 1242 default: 1243 *num = 1; 1244 *den = 1; 1245 break; 1246 } 1247 } 1248 1249 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 1250 const struct intel_plane_state *plane_state) 1251 { 1252 unsigned int pixel_rate; 1253 unsigned int num, den; 1254 1255 /* 1256 * Note that crtc_state->pixel_rate accounts for both 1257 * horizontal and vertical panel fitter downscaling factors. 1258 * Pre-HSW bspec tells us to only consider the horizontal 1259 * downscaling factor here. We ignore that and just consider 1260 * both for simplicity. 1261 */ 1262 pixel_rate = crtc_state->pixel_rate; 1263 1264 ivb_plane_ratio(crtc_state, plane_state, &num, &den); 1265 1266 return DIV_ROUND_UP(pixel_rate * num, den); 1267 } 1268 1269 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 1270 const struct intel_plane_state *plane_state) 1271 { 1272 unsigned int src_w, dst_w, pixel_rate; 1273 unsigned int num, den; 1274 1275 /* 1276 * Note that crtc_state->pixel_rate accounts for both 1277 * horizontal and vertical panel fitter downscaling factors. 1278 * Pre-HSW bspec tells us to only consider the horizontal 1279 * downscaling factor here. We ignore that and just consider 1280 * both for simplicity. 1281 */ 1282 pixel_rate = crtc_state->pixel_rate; 1283 1284 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1285 dst_w = drm_rect_width(&plane_state->uapi.dst); 1286 1287 if (src_w != dst_w) 1288 ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den); 1289 else 1290 ivb_plane_ratio(crtc_state, plane_state, &num, &den); 1291 1292 /* Horizontal downscaling limits the maximum pixel rate */ 1293 dst_w = min(src_w, dst_w); 1294 1295 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w), 1296 den * dst_w); 1297 } 1298 1299 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state, 1300 const struct intel_plane_state *plane_state, 1301 unsigned int *num, unsigned int *den) 1302 { 1303 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 1304 const struct drm_framebuffer *fb = plane_state->hw.fb; 1305 unsigned int cpp = fb->format->cpp[0]; 1306 1307 if (hweight8(active_planes) == 2) { 1308 switch (cpp) { 1309 case 8: 1310 *num = 10; 1311 *den = 8; 1312 break; 1313 default: 1314 *num = 1; 1315 *den = 1; 1316 break; 1317 } 1318 } else { 1319 switch (cpp) { 1320 case 8: 1321 *num = 9; 1322 *den = 8; 1323 break; 1324 default: 1325 *num = 1; 1326 *den = 1; 1327 break; 1328 } 1329 } 1330 } 1331 1332 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 1333 const struct intel_plane_state *plane_state) 1334 { 1335 unsigned int pixel_rate = crtc_state->pixel_rate; 1336 unsigned int num, den; 1337 1338 hsw_plane_ratio(crtc_state, plane_state, &num, &den); 1339 1340 return DIV_ROUND_UP(pixel_rate * num, den); 1341 } 1342 1343 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1344 { 1345 u32 sprctl = 0; 1346 1347 if (crtc_state->gamma_enable) 1348 sprctl |= SPRITE_GAMMA_ENABLE; 1349 1350 if (crtc_state->csc_enable) 1351 sprctl |= SPRITE_PIPE_CSC_ENABLE; 1352 1353 return sprctl; 1354 } 1355 1356 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state) 1357 { 1358 struct drm_i915_private *dev_priv = 1359 to_i915(plane_state->uapi.plane->dev); 1360 const struct drm_framebuffer *fb = plane_state->hw.fb; 1361 1362 return fb->format->cpp[0] == 8 && 1363 (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)); 1364 } 1365 1366 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, 1367 const struct intel_plane_state *plane_state) 1368 { 1369 struct drm_i915_private *dev_priv = 1370 to_i915(plane_state->uapi.plane->dev); 1371 const struct drm_framebuffer *fb = plane_state->hw.fb; 1372 unsigned int rotation = plane_state->hw.rotation; 1373 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1374 u32 sprctl; 1375 1376 sprctl = SPRITE_ENABLE; 1377 1378 if (IS_IVYBRIDGE(dev_priv)) 1379 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 1380 1381 switch (fb->format->format) { 1382 case DRM_FORMAT_XBGR8888: 1383 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 1384 break; 1385 case DRM_FORMAT_XRGB8888: 1386 sprctl |= SPRITE_FORMAT_RGBX888; 1387 break; 1388 case DRM_FORMAT_XBGR2101010: 1389 sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX; 1390 break; 1391 case DRM_FORMAT_XRGB2101010: 1392 sprctl |= SPRITE_FORMAT_RGBX101010; 1393 break; 1394 case DRM_FORMAT_XBGR16161616F: 1395 sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX; 1396 break; 1397 case DRM_FORMAT_XRGB16161616F: 1398 sprctl |= SPRITE_FORMAT_RGBX161616; 1399 break; 1400 case DRM_FORMAT_YUYV: 1401 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 1402 break; 1403 case DRM_FORMAT_YVYU: 1404 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 1405 break; 1406 case DRM_FORMAT_UYVY: 1407 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 1408 break; 1409 case DRM_FORMAT_VYUY: 1410 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 1411 break; 1412 default: 1413 MISSING_CASE(fb->format->format); 1414 return 0; 1415 } 1416 1417 if (!ivb_need_sprite_gamma(plane_state)) 1418 sprctl |= SPRITE_INT_GAMMA_DISABLE; 1419 1420 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 1421 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; 1422 1423 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1424 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE; 1425 1426 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1427 sprctl |= SPRITE_TILED; 1428 1429 if (rotation & DRM_MODE_ROTATE_180) 1430 sprctl |= SPRITE_ROTATE_180; 1431 1432 if (key->flags & I915_SET_COLORKEY_DESTINATION) 1433 sprctl |= SPRITE_DEST_KEY; 1434 else if (key->flags & I915_SET_COLORKEY_SOURCE) 1435 sprctl |= SPRITE_SOURCE_KEY; 1436 1437 return sprctl; 1438 } 1439 1440 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state, 1441 u16 gamma[18]) 1442 { 1443 int scale, i; 1444 1445 /* 1446 * WaFP16GammaEnabling:ivb,hsw 1447 * "Workaround : When using the 64-bit format, the sprite output 1448 * on each color channel has one quarter amplitude. It can be 1449 * brought up to full amplitude by using sprite internal gamma 1450 * correction, pipe gamma correction, or pipe color space 1451 * conversion to multiply the sprite output by four." 1452 */ 1453 scale = 4; 1454 1455 for (i = 0; i < 16; i++) 1456 gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1); 1457 1458 gamma[i] = min((scale * i << 10) / 16, 1 << 10); 1459 i++; 1460 1461 gamma[i] = 3 << 10; 1462 i++; 1463 } 1464 1465 static void ivb_update_gamma(const struct intel_plane_state *plane_state) 1466 { 1467 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1468 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1469 enum pipe pipe = plane->pipe; 1470 u16 gamma[18]; 1471 int i; 1472 1473 if (!ivb_need_sprite_gamma(plane_state)) 1474 return; 1475 1476 ivb_sprite_linear_gamma(plane_state, gamma); 1477 1478 /* FIXME these register are single buffered :( */ 1479 for (i = 0; i < 16; i++) 1480 intel_de_write_fw(dev_priv, SPRGAMC(pipe, i), 1481 gamma[i] << 20 | gamma[i] << 10 | gamma[i]); 1482 1483 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 0), gamma[i]); 1484 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 1), gamma[i]); 1485 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 2), gamma[i]); 1486 i++; 1487 1488 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 0), gamma[i]); 1489 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 1), gamma[i]); 1490 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 2), gamma[i]); 1491 i++; 1492 } 1493 1494 static void 1495 ivb_update_plane(struct intel_plane *plane, 1496 const struct intel_crtc_state *crtc_state, 1497 const struct intel_plane_state *plane_state) 1498 { 1499 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1500 enum pipe pipe = plane->pipe; 1501 u32 sprsurf_offset = plane_state->color_plane[0].offset; 1502 u32 linear_offset; 1503 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1504 int crtc_x = plane_state->uapi.dst.x1; 1505 int crtc_y = plane_state->uapi.dst.y1; 1506 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1507 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1508 u32 x = plane_state->color_plane[0].x; 1509 u32 y = plane_state->color_plane[0].y; 1510 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1511 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 1512 u32 sprctl, sprscale = 0; 1513 unsigned long irqflags; 1514 1515 sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state); 1516 1517 /* Sizes are 0 based */ 1518 src_w--; 1519 src_h--; 1520 crtc_w--; 1521 crtc_h--; 1522 1523 if (crtc_w != src_w || crtc_h != src_h) 1524 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 1525 1526 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1527 1528 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1529 1530 intel_de_write_fw(dev_priv, SPRSTRIDE(pipe), 1531 plane_state->color_plane[0].stride); 1532 intel_de_write_fw(dev_priv, SPRPOS(pipe), (crtc_y << 16) | crtc_x); 1533 intel_de_write_fw(dev_priv, SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 1534 if (IS_IVYBRIDGE(dev_priv)) 1535 intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale); 1536 1537 if (key->flags) { 1538 intel_de_write_fw(dev_priv, SPRKEYVAL(pipe), key->min_value); 1539 intel_de_write_fw(dev_priv, SPRKEYMSK(pipe), 1540 key->channel_mask); 1541 intel_de_write_fw(dev_priv, SPRKEYMAX(pipe), key->max_value); 1542 } 1543 1544 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 1545 * register */ 1546 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 1547 intel_de_write_fw(dev_priv, SPROFFSET(pipe), (y << 16) | x); 1548 } else { 1549 intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset); 1550 intel_de_write_fw(dev_priv, SPRTILEOFF(pipe), (y << 16) | x); 1551 } 1552 1553 /* 1554 * The control register self-arms if the plane was previously 1555 * disabled. Try to make the plane enable atomic by writing 1556 * the control register just before the surface register. 1557 */ 1558 intel_de_write_fw(dev_priv, SPRCTL(pipe), sprctl); 1559 intel_de_write_fw(dev_priv, SPRSURF(pipe), 1560 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1561 1562 ivb_update_gamma(plane_state); 1563 1564 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1565 } 1566 1567 static void 1568 ivb_disable_plane(struct intel_plane *plane, 1569 const struct intel_crtc_state *crtc_state) 1570 { 1571 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1572 enum pipe pipe = plane->pipe; 1573 unsigned long irqflags; 1574 1575 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1576 1577 intel_de_write_fw(dev_priv, SPRCTL(pipe), 0); 1578 /* Disable the scaler */ 1579 if (IS_IVYBRIDGE(dev_priv)) 1580 intel_de_write_fw(dev_priv, SPRSCALE(pipe), 0); 1581 intel_de_write_fw(dev_priv, SPRSURF(pipe), 0); 1582 1583 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1584 } 1585 1586 static bool 1587 ivb_plane_get_hw_state(struct intel_plane *plane, 1588 enum pipe *pipe) 1589 { 1590 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1591 enum intel_display_power_domain power_domain; 1592 intel_wakeref_t wakeref; 1593 bool ret; 1594 1595 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1596 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1597 if (!wakeref) 1598 return false; 1599 1600 ret = intel_de_read(dev_priv, SPRCTL(plane->pipe)) & SPRITE_ENABLE; 1601 1602 *pipe = plane->pipe; 1603 1604 intel_display_power_put(dev_priv, power_domain, wakeref); 1605 1606 return ret; 1607 } 1608 1609 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 1610 const struct intel_plane_state *plane_state) 1611 { 1612 const struct drm_framebuffer *fb = plane_state->hw.fb; 1613 unsigned int hscale, pixel_rate; 1614 unsigned int limit, decimate; 1615 1616 /* 1617 * Note that crtc_state->pixel_rate accounts for both 1618 * horizontal and vertical panel fitter downscaling factors. 1619 * Pre-HSW bspec tells us to only consider the horizontal 1620 * downscaling factor here. We ignore that and just consider 1621 * both for simplicity. 1622 */ 1623 pixel_rate = crtc_state->pixel_rate; 1624 1625 /* Horizontal downscaling limits the maximum pixel rate */ 1626 hscale = drm_rect_calc_hscale(&plane_state->uapi.src, 1627 &plane_state->uapi.dst, 1628 0, INT_MAX); 1629 hscale = max(hscale, 0x10000u); 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->is_yuv) 1643 limit--; 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 fallthrough; 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 fallthrough; 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 fallthrough; 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 fallthrough; 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 fallthrough; 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 fallthrough; 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 fallthrough; 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],rkl[all] */ 2846 if (IS_ROCKETLAKE(dev_priv) || 2847 IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0)) 2848 return false; 2849 2850 return plane_id < PLANE_SPRITE4; 2851 } 2852 2853 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, 2854 u32 format, u64 modifier) 2855 { 2856 struct drm_i915_private *dev_priv = to_i915(_plane->dev); 2857 struct intel_plane *plane = to_intel_plane(_plane); 2858 2859 switch (modifier) { 2860 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: 2861 if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id)) 2862 return false; 2863 fallthrough; 2864 case DRM_FORMAT_MOD_LINEAR: 2865 case I915_FORMAT_MOD_X_TILED: 2866 case I915_FORMAT_MOD_Y_TILED: 2867 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: 2868 break; 2869 default: 2870 return false; 2871 } 2872 2873 switch (format) { 2874 case DRM_FORMAT_XRGB8888: 2875 case DRM_FORMAT_XBGR8888: 2876 case DRM_FORMAT_ARGB8888: 2877 case DRM_FORMAT_ABGR8888: 2878 if (is_ccs_modifier(modifier)) 2879 return true; 2880 fallthrough; 2881 case DRM_FORMAT_YUYV: 2882 case DRM_FORMAT_YVYU: 2883 case DRM_FORMAT_UYVY: 2884 case DRM_FORMAT_VYUY: 2885 case DRM_FORMAT_NV12: 2886 case DRM_FORMAT_XYUV8888: 2887 case DRM_FORMAT_P010: 2888 case DRM_FORMAT_P012: 2889 case DRM_FORMAT_P016: 2890 if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) 2891 return true; 2892 fallthrough; 2893 case DRM_FORMAT_RGB565: 2894 case DRM_FORMAT_XRGB2101010: 2895 case DRM_FORMAT_XBGR2101010: 2896 case DRM_FORMAT_ARGB2101010: 2897 case DRM_FORMAT_ABGR2101010: 2898 case DRM_FORMAT_XVYU2101010: 2899 case DRM_FORMAT_C8: 2900 case DRM_FORMAT_XBGR16161616F: 2901 case DRM_FORMAT_ABGR16161616F: 2902 case DRM_FORMAT_XRGB16161616F: 2903 case DRM_FORMAT_ARGB16161616F: 2904 case DRM_FORMAT_Y210: 2905 case DRM_FORMAT_Y212: 2906 case DRM_FORMAT_Y216: 2907 case DRM_FORMAT_XVYU12_16161616: 2908 case DRM_FORMAT_XVYU16161616: 2909 if (modifier == DRM_FORMAT_MOD_LINEAR || 2910 modifier == I915_FORMAT_MOD_X_TILED || 2911 modifier == I915_FORMAT_MOD_Y_TILED) 2912 return true; 2913 fallthrough; 2914 default: 2915 return false; 2916 } 2917 } 2918 2919 static const struct drm_plane_funcs g4x_sprite_funcs = { 2920 .update_plane = drm_atomic_helper_update_plane, 2921 .disable_plane = drm_atomic_helper_disable_plane, 2922 .destroy = intel_plane_destroy, 2923 .atomic_duplicate_state = intel_plane_duplicate_state, 2924 .atomic_destroy_state = intel_plane_destroy_state, 2925 .format_mod_supported = g4x_sprite_format_mod_supported, 2926 }; 2927 2928 static const struct drm_plane_funcs snb_sprite_funcs = { 2929 .update_plane = drm_atomic_helper_update_plane, 2930 .disable_plane = drm_atomic_helper_disable_plane, 2931 .destroy = intel_plane_destroy, 2932 .atomic_duplicate_state = intel_plane_duplicate_state, 2933 .atomic_destroy_state = intel_plane_destroy_state, 2934 .format_mod_supported = snb_sprite_format_mod_supported, 2935 }; 2936 2937 static const struct drm_plane_funcs vlv_sprite_funcs = { 2938 .update_plane = drm_atomic_helper_update_plane, 2939 .disable_plane = drm_atomic_helper_disable_plane, 2940 .destroy = intel_plane_destroy, 2941 .atomic_duplicate_state = intel_plane_duplicate_state, 2942 .atomic_destroy_state = intel_plane_destroy_state, 2943 .format_mod_supported = vlv_sprite_format_mod_supported, 2944 }; 2945 2946 static const struct drm_plane_funcs skl_plane_funcs = { 2947 .update_plane = drm_atomic_helper_update_plane, 2948 .disable_plane = drm_atomic_helper_disable_plane, 2949 .destroy = intel_plane_destroy, 2950 .atomic_duplicate_state = intel_plane_duplicate_state, 2951 .atomic_destroy_state = intel_plane_destroy_state, 2952 .format_mod_supported = skl_plane_format_mod_supported, 2953 }; 2954 2955 static const struct drm_plane_funcs gen12_plane_funcs = { 2956 .update_plane = drm_atomic_helper_update_plane, 2957 .disable_plane = drm_atomic_helper_disable_plane, 2958 .destroy = intel_plane_destroy, 2959 .atomic_duplicate_state = intel_plane_duplicate_state, 2960 .atomic_destroy_state = intel_plane_destroy_state, 2961 .format_mod_supported = gen12_plane_format_mod_supported, 2962 }; 2963 2964 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, 2965 enum pipe pipe, enum plane_id plane_id) 2966 { 2967 if (!HAS_FBC(dev_priv)) 2968 return false; 2969 2970 return pipe == PIPE_A && plane_id == PLANE_PRIMARY; 2971 } 2972 2973 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, 2974 enum pipe pipe, enum plane_id plane_id) 2975 { 2976 /* Display WA #0870: skl, bxt */ 2977 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) 2978 return false; 2979 2980 if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C) 2981 return false; 2982 2983 if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) 2984 return false; 2985 2986 return true; 2987 } 2988 2989 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, 2990 enum pipe pipe, enum plane_id plane_id, 2991 int *num_formats) 2992 { 2993 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2994 *num_formats = ARRAY_SIZE(skl_planar_formats); 2995 return skl_planar_formats; 2996 } else { 2997 *num_formats = ARRAY_SIZE(skl_plane_formats); 2998 return skl_plane_formats; 2999 } 3000 } 3001 3002 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, 3003 enum pipe pipe, enum plane_id plane_id, 3004 int *num_formats) 3005 { 3006 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 3007 *num_formats = ARRAY_SIZE(glk_planar_formats); 3008 return glk_planar_formats; 3009 } else { 3010 *num_formats = ARRAY_SIZE(skl_plane_formats); 3011 return skl_plane_formats; 3012 } 3013 } 3014 3015 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv, 3016 enum pipe pipe, enum plane_id plane_id, 3017 int *num_formats) 3018 { 3019 if (icl_is_hdr_plane(dev_priv, plane_id)) { 3020 *num_formats = ARRAY_SIZE(icl_hdr_plane_formats); 3021 return icl_hdr_plane_formats; 3022 } else if (icl_is_nv12_y_plane(dev_priv, plane_id)) { 3023 *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats); 3024 return icl_sdr_y_plane_formats; 3025 } else { 3026 *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats); 3027 return icl_sdr_uv_plane_formats; 3028 } 3029 } 3030 3031 static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv, 3032 enum plane_id plane_id) 3033 { 3034 if (gen12_plane_supports_mc_ccs(dev_priv, plane_id)) 3035 return gen12_plane_format_modifiers_mc_ccs; 3036 else 3037 return gen12_plane_format_modifiers_rc_ccs; 3038 } 3039 3040 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 3041 enum pipe pipe, enum plane_id plane_id) 3042 { 3043 if (plane_id == PLANE_CURSOR) 3044 return false; 3045 3046 if (INTEL_GEN(dev_priv) >= 10) 3047 return true; 3048 3049 if (IS_GEMINILAKE(dev_priv)) 3050 return pipe != PIPE_C; 3051 3052 return pipe != PIPE_C && 3053 (plane_id == PLANE_PRIMARY || 3054 plane_id == PLANE_SPRITE0); 3055 } 3056 3057 struct intel_plane * 3058 skl_universal_plane_create(struct drm_i915_private *dev_priv, 3059 enum pipe pipe, enum plane_id plane_id) 3060 { 3061 const struct drm_plane_funcs *plane_funcs; 3062 struct intel_plane *plane; 3063 enum drm_plane_type plane_type; 3064 unsigned int supported_rotations; 3065 unsigned int supported_csc; 3066 const u64 *modifiers; 3067 const u32 *formats; 3068 int num_formats; 3069 int ret; 3070 3071 plane = intel_plane_alloc(); 3072 if (IS_ERR(plane)) 3073 return plane; 3074 3075 plane->pipe = pipe; 3076 plane->id = plane_id; 3077 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id); 3078 3079 plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id); 3080 if (plane->has_fbc) { 3081 struct intel_fbc *fbc = &dev_priv->fbc; 3082 3083 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; 3084 } 3085 3086 plane->max_stride = skl_plane_max_stride; 3087 plane->update_plane = skl_update_plane; 3088 plane->disable_plane = skl_disable_plane; 3089 plane->get_hw_state = skl_plane_get_hw_state; 3090 plane->check_plane = skl_plane_check; 3091 plane->min_cdclk = skl_plane_min_cdclk; 3092 3093 if (INTEL_GEN(dev_priv) >= 11) 3094 formats = icl_get_plane_formats(dev_priv, pipe, 3095 plane_id, &num_formats); 3096 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 3097 formats = glk_get_plane_formats(dev_priv, pipe, 3098 plane_id, &num_formats); 3099 else 3100 formats = skl_get_plane_formats(dev_priv, pipe, 3101 plane_id, &num_formats); 3102 3103 plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id); 3104 if (INTEL_GEN(dev_priv) >= 12) { 3105 modifiers = gen12_get_plane_modifiers(dev_priv, plane_id); 3106 plane_funcs = &gen12_plane_funcs; 3107 } else { 3108 if (plane->has_ccs) 3109 modifiers = skl_plane_format_modifiers_ccs; 3110 else 3111 modifiers = skl_plane_format_modifiers_noccs; 3112 plane_funcs = &skl_plane_funcs; 3113 } 3114 3115 if (plane_id == PLANE_PRIMARY) 3116 plane_type = DRM_PLANE_TYPE_PRIMARY; 3117 else 3118 plane_type = DRM_PLANE_TYPE_OVERLAY; 3119 3120 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 3121 0, plane_funcs, 3122 formats, num_formats, modifiers, 3123 plane_type, 3124 "plane %d%c", plane_id + 1, 3125 pipe_name(pipe)); 3126 if (ret) 3127 goto fail; 3128 3129 supported_rotations = 3130 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | 3131 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; 3132 3133 if (INTEL_GEN(dev_priv) >= 10) 3134 supported_rotations |= DRM_MODE_REFLECT_X; 3135 3136 drm_plane_create_rotation_property(&plane->base, 3137 DRM_MODE_ROTATE_0, 3138 supported_rotations); 3139 3140 supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709); 3141 3142 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 3143 supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020); 3144 3145 drm_plane_create_color_properties(&plane->base, 3146 supported_csc, 3147 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 3148 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 3149 DRM_COLOR_YCBCR_BT709, 3150 DRM_COLOR_YCBCR_LIMITED_RANGE); 3151 3152 drm_plane_create_alpha_property(&plane->base); 3153 drm_plane_create_blend_mode_property(&plane->base, 3154 BIT(DRM_MODE_BLEND_PIXEL_NONE) | 3155 BIT(DRM_MODE_BLEND_PREMULTI) | 3156 BIT(DRM_MODE_BLEND_COVERAGE)); 3157 3158 drm_plane_create_zpos_immutable_property(&plane->base, plane_id); 3159 3160 if (INTEL_GEN(dev_priv) >= 12) 3161 drm_plane_enable_fb_damage_clips(&plane->base); 3162 3163 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 3164 3165 return plane; 3166 3167 fail: 3168 intel_plane_free(plane); 3169 3170 return ERR_PTR(ret); 3171 } 3172 3173 struct intel_plane * 3174 intel_sprite_plane_create(struct drm_i915_private *dev_priv, 3175 enum pipe pipe, int sprite) 3176 { 3177 struct intel_plane *plane; 3178 const struct drm_plane_funcs *plane_funcs; 3179 unsigned int supported_rotations; 3180 const u64 *modifiers; 3181 const u32 *formats; 3182 int num_formats; 3183 int ret, zpos; 3184 3185 if (INTEL_GEN(dev_priv) >= 9) 3186 return skl_universal_plane_create(dev_priv, pipe, 3187 PLANE_SPRITE0 + sprite); 3188 3189 plane = intel_plane_alloc(); 3190 if (IS_ERR(plane)) 3191 return plane; 3192 3193 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 3194 plane->max_stride = i9xx_plane_max_stride; 3195 plane->update_plane = vlv_update_plane; 3196 plane->disable_plane = vlv_disable_plane; 3197 plane->get_hw_state = vlv_plane_get_hw_state; 3198 plane->check_plane = vlv_sprite_check; 3199 plane->min_cdclk = vlv_plane_min_cdclk; 3200 3201 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 3202 formats = chv_pipe_b_sprite_formats; 3203 num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats); 3204 } else { 3205 formats = vlv_plane_formats; 3206 num_formats = ARRAY_SIZE(vlv_plane_formats); 3207 } 3208 modifiers = i9xx_plane_format_modifiers; 3209 3210 plane_funcs = &vlv_sprite_funcs; 3211 } else if (INTEL_GEN(dev_priv) >= 7) { 3212 plane->max_stride = g4x_sprite_max_stride; 3213 plane->update_plane = ivb_update_plane; 3214 plane->disable_plane = ivb_disable_plane; 3215 plane->get_hw_state = ivb_plane_get_hw_state; 3216 plane->check_plane = g4x_sprite_check; 3217 3218 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) 3219 plane->min_cdclk = hsw_plane_min_cdclk; 3220 else 3221 plane->min_cdclk = ivb_sprite_min_cdclk; 3222 3223 formats = snb_plane_formats; 3224 num_formats = ARRAY_SIZE(snb_plane_formats); 3225 modifiers = i9xx_plane_format_modifiers; 3226 3227 plane_funcs = &snb_sprite_funcs; 3228 } else { 3229 plane->max_stride = g4x_sprite_max_stride; 3230 plane->update_plane = g4x_update_plane; 3231 plane->disable_plane = g4x_disable_plane; 3232 plane->get_hw_state = g4x_plane_get_hw_state; 3233 plane->check_plane = g4x_sprite_check; 3234 plane->min_cdclk = g4x_sprite_min_cdclk; 3235 3236 modifiers = i9xx_plane_format_modifiers; 3237 if (IS_GEN(dev_priv, 6)) { 3238 formats = snb_plane_formats; 3239 num_formats = ARRAY_SIZE(snb_plane_formats); 3240 3241 plane_funcs = &snb_sprite_funcs; 3242 } else { 3243 formats = g4x_plane_formats; 3244 num_formats = ARRAY_SIZE(g4x_plane_formats); 3245 3246 plane_funcs = &g4x_sprite_funcs; 3247 } 3248 } 3249 3250 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 3251 supported_rotations = 3252 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 3253 DRM_MODE_REFLECT_X; 3254 } else { 3255 supported_rotations = 3256 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 3257 } 3258 3259 plane->pipe = pipe; 3260 plane->id = PLANE_SPRITE0 + sprite; 3261 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 3262 3263 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 3264 0, plane_funcs, 3265 formats, num_formats, modifiers, 3266 DRM_PLANE_TYPE_OVERLAY, 3267 "sprite %c", sprite_name(pipe, sprite)); 3268 if (ret) 3269 goto fail; 3270 3271 drm_plane_create_rotation_property(&plane->base, 3272 DRM_MODE_ROTATE_0, 3273 supported_rotations); 3274 3275 drm_plane_create_color_properties(&plane->base, 3276 BIT(DRM_COLOR_YCBCR_BT601) | 3277 BIT(DRM_COLOR_YCBCR_BT709), 3278 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 3279 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 3280 DRM_COLOR_YCBCR_BT709, 3281 DRM_COLOR_YCBCR_LIMITED_RANGE); 3282 3283 zpos = sprite + 1; 3284 drm_plane_create_zpos_immutable_property(&plane->base, zpos); 3285 3286 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 3287 3288 return plane; 3289 3290 fail: 3291 intel_plane_free(plane); 3292 3293 return ERR_PTR(ret); 3294 } 3295