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