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