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