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 const struct drm_framebuffer *fb = plane_state->hw.fb; 587 int aux_plane = intel_main_to_aux_plane(fb, color_plane); 588 u32 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr; 589 u32 aux_stride = skl_plane_stride(plane_state, aux_plane); 590 int crtc_x = plane_state->uapi.dst.x1; 591 int crtc_y = plane_state->uapi.dst.y1; 592 u32 x = plane_state->color_plane[color_plane].x; 593 u32 y = plane_state->color_plane[color_plane].y; 594 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 595 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 596 u8 alpha = plane_state->hw.alpha >> 8; 597 u32 plane_color_ctl = 0; 598 unsigned long irqflags; 599 u32 keymsk, keymax; 600 u32 plane_ctl = plane_state->ctl; 601 602 plane_ctl |= skl_plane_ctl_crtc(crtc_state); 603 604 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 605 plane_color_ctl = plane_state->color_ctl | 606 glk_plane_color_ctl_crtc(crtc_state); 607 608 /* Sizes are 0 based */ 609 src_w--; 610 src_h--; 611 612 keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha); 613 614 keymsk = key->channel_mask & 0x7ffffff; 615 if (alpha < 0xff) 616 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE; 617 618 /* The scaler will handle the output position */ 619 if (plane_state->scaler_id >= 0) { 620 crtc_x = 0; 621 crtc_y = 0; 622 } 623 624 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 625 626 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); 627 I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x); 628 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); 629 630 if (INTEL_GEN(dev_priv) < 12) 631 aux_dist |= aux_stride; 632 I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), aux_dist); 633 634 if (icl_is_hdr_plane(dev_priv, plane_id)) 635 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), plane_state->cus_ctl); 636 637 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 638 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); 639 640 if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id)) 641 icl_program_input_csc(plane, crtc_state, plane_state); 642 643 skl_write_plane_wm(plane, crtc_state); 644 645 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 646 I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk); 647 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax); 648 649 I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x); 650 651 if (INTEL_GEN(dev_priv) < 11) 652 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id), 653 (plane_state->color_plane[1].y << 16) | 654 plane_state->color_plane[1].x); 655 656 /* 657 * The control register self-arms if the plane was previously 658 * disabled. Try to make the plane enable atomic by writing 659 * the control register just before the surface register. 660 */ 661 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); 662 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 663 intel_plane_ggtt_offset(plane_state) + surf_addr); 664 665 if (plane_state->scaler_id >= 0) 666 skl_program_scaler(plane, crtc_state, plane_state); 667 668 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 669 } 670 671 static void 672 skl_update_plane(struct intel_plane *plane, 673 const struct intel_crtc_state *crtc_state, 674 const struct intel_plane_state *plane_state) 675 { 676 int color_plane = 0; 677 678 if (plane_state->planar_linked_plane && !plane_state->planar_slave) 679 /* Program the UV plane on planar master */ 680 color_plane = 1; 681 682 skl_program_plane(plane, crtc_state, plane_state, color_plane); 683 } 684 static void 685 skl_disable_plane(struct intel_plane *plane, 686 const struct intel_crtc_state *crtc_state) 687 { 688 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 689 enum plane_id plane_id = plane->id; 690 enum pipe pipe = plane->pipe; 691 unsigned long irqflags; 692 693 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 694 695 if (icl_is_hdr_plane(dev_priv, plane_id)) 696 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0); 697 698 skl_write_plane_wm(plane, crtc_state); 699 700 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0); 701 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0); 702 703 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 704 } 705 706 static bool 707 skl_plane_get_hw_state(struct intel_plane *plane, 708 enum pipe *pipe) 709 { 710 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 711 enum intel_display_power_domain power_domain; 712 enum plane_id plane_id = plane->id; 713 intel_wakeref_t wakeref; 714 bool ret; 715 716 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 717 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 718 if (!wakeref) 719 return false; 720 721 ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; 722 723 *pipe = plane->pipe; 724 725 intel_display_power_put(dev_priv, power_domain, wakeref); 726 727 return ret; 728 } 729 730 static void i9xx_plane_linear_gamma(u16 gamma[8]) 731 { 732 /* The points are not evenly spaced. */ 733 static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 }; 734 int i; 735 736 for (i = 0; i < 8; i++) 737 gamma[i] = (in[i] << 8) / 32; 738 } 739 740 static void 741 chv_update_csc(const struct intel_plane_state *plane_state) 742 { 743 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 744 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 745 const struct drm_framebuffer *fb = plane_state->hw.fb; 746 enum plane_id plane_id = plane->id; 747 /* 748 * |r| | c0 c1 c2 | |cr| 749 * |g| = | c3 c4 c5 | x |y | 750 * |b| | c6 c7 c8 | |cb| 751 * 752 * Coefficients are s3.12. 753 * 754 * Cb and Cr apparently come in as signed already, and 755 * we always get full range data in on account of CLRC0/1. 756 */ 757 static const s16 csc_matrix[][9] = { 758 /* BT.601 full range YCbCr -> full range RGB */ 759 [DRM_COLOR_YCBCR_BT601] = { 760 5743, 4096, 0, 761 -2925, 4096, -1410, 762 0, 4096, 7258, 763 }, 764 /* BT.709 full range YCbCr -> full range RGB */ 765 [DRM_COLOR_YCBCR_BT709] = { 766 6450, 4096, 0, 767 -1917, 4096, -767, 768 0, 4096, 7601, 769 }, 770 }; 771 const s16 *csc = csc_matrix[plane_state->hw.color_encoding]; 772 773 /* Seems RGB data bypasses the CSC always */ 774 if (!fb->format->is_yuv) 775 return; 776 777 I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 778 I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 779 I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 780 781 I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0])); 782 I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2])); 783 I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4])); 784 I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6])); 785 I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8])); 786 787 I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); 788 I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 789 I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 790 791 I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 792 I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 793 I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 794 } 795 796 #define SIN_0 0 797 #define COS_0 1 798 799 static void 800 vlv_update_clrc(const struct intel_plane_state *plane_state) 801 { 802 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 803 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 804 const struct drm_framebuffer *fb = plane_state->hw.fb; 805 enum pipe pipe = plane->pipe; 806 enum plane_id plane_id = plane->id; 807 int contrast, brightness, sh_scale, sh_sin, sh_cos; 808 809 if (fb->format->is_yuv && 810 plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) { 811 /* 812 * Expand limited range to full range: 813 * Contrast is applied first and is used to expand Y range. 814 * Brightness is applied second and is used to remove the 815 * offset from Y. Saturation/hue is used to expand CbCr range. 816 */ 817 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16); 818 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16); 819 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128); 820 sh_sin = SIN_0 * sh_scale; 821 sh_cos = COS_0 * sh_scale; 822 } else { 823 /* Pass-through everything. */ 824 contrast = 1 << 6; 825 brightness = 0; 826 sh_scale = 1 << 7; 827 sh_sin = SIN_0 * sh_scale; 828 sh_cos = COS_0 * sh_scale; 829 } 830 831 /* FIXME these register are single buffered :( */ 832 I915_WRITE_FW(SPCLRC0(pipe, plane_id), 833 SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness)); 834 I915_WRITE_FW(SPCLRC1(pipe, plane_id), 835 SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos)); 836 } 837 838 static void 839 vlv_plane_ratio(const struct intel_crtc_state *crtc_state, 840 const struct intel_plane_state *plane_state, 841 unsigned int *num, unsigned int *den) 842 { 843 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 844 const struct drm_framebuffer *fb = plane_state->hw.fb; 845 unsigned int cpp = fb->format->cpp[0]; 846 847 /* 848 * VLV bspec only considers cases where all three planes are 849 * enabled, and cases where the primary and one sprite is enabled. 850 * Let's assume the case with just two sprites enabled also 851 * maps to the latter case. 852 */ 853 if (hweight8(active_planes) == 3) { 854 switch (cpp) { 855 case 8: 856 *num = 11; 857 *den = 8; 858 break; 859 case 4: 860 *num = 18; 861 *den = 16; 862 break; 863 default: 864 *num = 1; 865 *den = 1; 866 break; 867 } 868 } else if (hweight8(active_planes) == 2) { 869 switch (cpp) { 870 case 8: 871 *num = 10; 872 *den = 8; 873 break; 874 case 4: 875 *num = 17; 876 *den = 16; 877 break; 878 default: 879 *num = 1; 880 *den = 1; 881 break; 882 } 883 } else { 884 switch (cpp) { 885 case 8: 886 *num = 10; 887 *den = 8; 888 break; 889 default: 890 *num = 1; 891 *den = 1; 892 break; 893 } 894 } 895 } 896 897 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 898 const struct intel_plane_state *plane_state) 899 { 900 unsigned int pixel_rate; 901 unsigned int num, den; 902 903 /* 904 * Note that crtc_state->pixel_rate accounts for both 905 * horizontal and vertical panel fitter downscaling factors. 906 * Pre-HSW bspec tells us to only consider the horizontal 907 * downscaling factor here. We ignore that and just consider 908 * both for simplicity. 909 */ 910 pixel_rate = crtc_state->pixel_rate; 911 912 vlv_plane_ratio(crtc_state, plane_state, &num, &den); 913 914 return DIV_ROUND_UP(pixel_rate * num, den); 915 } 916 917 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 918 { 919 u32 sprctl = 0; 920 921 if (crtc_state->gamma_enable) 922 sprctl |= SP_GAMMA_ENABLE; 923 924 return sprctl; 925 } 926 927 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, 928 const struct intel_plane_state *plane_state) 929 { 930 const struct drm_framebuffer *fb = plane_state->hw.fb; 931 unsigned int rotation = plane_state->hw.rotation; 932 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 933 u32 sprctl; 934 935 sprctl = SP_ENABLE; 936 937 switch (fb->format->format) { 938 case DRM_FORMAT_YUYV: 939 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 940 break; 941 case DRM_FORMAT_YVYU: 942 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 943 break; 944 case DRM_FORMAT_UYVY: 945 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 946 break; 947 case DRM_FORMAT_VYUY: 948 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 949 break; 950 case DRM_FORMAT_C8: 951 sprctl |= SP_FORMAT_8BPP; 952 break; 953 case DRM_FORMAT_RGB565: 954 sprctl |= SP_FORMAT_BGR565; 955 break; 956 case DRM_FORMAT_XRGB8888: 957 sprctl |= SP_FORMAT_BGRX8888; 958 break; 959 case DRM_FORMAT_ARGB8888: 960 sprctl |= SP_FORMAT_BGRA8888; 961 break; 962 case DRM_FORMAT_XBGR2101010: 963 sprctl |= SP_FORMAT_RGBX1010102; 964 break; 965 case DRM_FORMAT_ABGR2101010: 966 sprctl |= SP_FORMAT_RGBA1010102; 967 break; 968 case DRM_FORMAT_XRGB2101010: 969 sprctl |= SP_FORMAT_BGRX1010102; 970 break; 971 case DRM_FORMAT_ARGB2101010: 972 sprctl |= SP_FORMAT_BGRA1010102; 973 break; 974 case DRM_FORMAT_XBGR8888: 975 sprctl |= SP_FORMAT_RGBX8888; 976 break; 977 case DRM_FORMAT_ABGR8888: 978 sprctl |= SP_FORMAT_RGBA8888; 979 break; 980 default: 981 MISSING_CASE(fb->format->format); 982 return 0; 983 } 984 985 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 986 sprctl |= SP_YUV_FORMAT_BT709; 987 988 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 989 sprctl |= SP_TILED; 990 991 if (rotation & DRM_MODE_ROTATE_180) 992 sprctl |= SP_ROTATE_180; 993 994 if (rotation & DRM_MODE_REFLECT_X) 995 sprctl |= SP_MIRROR; 996 997 if (key->flags & I915_SET_COLORKEY_SOURCE) 998 sprctl |= SP_SOURCE_KEY; 999 1000 return sprctl; 1001 } 1002 1003 static void vlv_update_gamma(const struct intel_plane_state *plane_state) 1004 { 1005 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1006 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1007 const struct drm_framebuffer *fb = plane_state->hw.fb; 1008 enum pipe pipe = plane->pipe; 1009 enum plane_id plane_id = plane->id; 1010 u16 gamma[8]; 1011 int i; 1012 1013 /* Seems RGB data bypasses the gamma always */ 1014 if (!fb->format->is_yuv) 1015 return; 1016 1017 i9xx_plane_linear_gamma(gamma); 1018 1019 /* FIXME these register are single buffered :( */ 1020 /* The two end points are implicit (0.0 and 1.0) */ 1021 for (i = 1; i < 8 - 1; i++) 1022 I915_WRITE_FW(SPGAMC(pipe, plane_id, i - 1), 1023 gamma[i] << 16 | 1024 gamma[i] << 8 | 1025 gamma[i]); 1026 } 1027 1028 static void 1029 vlv_update_plane(struct intel_plane *plane, 1030 const struct intel_crtc_state *crtc_state, 1031 const struct intel_plane_state *plane_state) 1032 { 1033 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1034 enum pipe pipe = plane->pipe; 1035 enum plane_id plane_id = plane->id; 1036 u32 sprsurf_offset = plane_state->color_plane[0].offset; 1037 u32 linear_offset; 1038 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1039 int crtc_x = plane_state->uapi.dst.x1; 1040 int crtc_y = plane_state->uapi.dst.y1; 1041 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1042 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1043 u32 x = plane_state->color_plane[0].x; 1044 u32 y = plane_state->color_plane[0].y; 1045 unsigned long irqflags; 1046 u32 sprctl; 1047 1048 sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state); 1049 1050 /* Sizes are 0 based */ 1051 crtc_w--; 1052 crtc_h--; 1053 1054 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1055 1056 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1057 1058 I915_WRITE_FW(SPSTRIDE(pipe, plane_id), 1059 plane_state->color_plane[0].stride); 1060 I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 1061 I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w); 1062 I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0); 1063 1064 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 1065 chv_update_csc(plane_state); 1066 1067 if (key->flags) { 1068 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value); 1069 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask); 1070 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); 1071 } 1072 1073 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset); 1074 I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x); 1075 1076 /* 1077 * The control register self-arms if the plane was previously 1078 * disabled. Try to make the plane enable atomic by writing 1079 * the control register just before the surface register. 1080 */ 1081 I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl); 1082 I915_WRITE_FW(SPSURF(pipe, plane_id), 1083 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1084 1085 vlv_update_clrc(plane_state); 1086 vlv_update_gamma(plane_state); 1087 1088 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1089 } 1090 1091 static void 1092 vlv_disable_plane(struct intel_plane *plane, 1093 const struct intel_crtc_state *crtc_state) 1094 { 1095 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1096 enum pipe pipe = plane->pipe; 1097 enum plane_id plane_id = plane->id; 1098 unsigned long irqflags; 1099 1100 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1101 1102 I915_WRITE_FW(SPCNTR(pipe, plane_id), 0); 1103 I915_WRITE_FW(SPSURF(pipe, plane_id), 0); 1104 1105 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1106 } 1107 1108 static bool 1109 vlv_plane_get_hw_state(struct intel_plane *plane, 1110 enum pipe *pipe) 1111 { 1112 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1113 enum intel_display_power_domain power_domain; 1114 enum plane_id plane_id = plane->id; 1115 intel_wakeref_t wakeref; 1116 bool ret; 1117 1118 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1119 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1120 if (!wakeref) 1121 return false; 1122 1123 ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE; 1124 1125 *pipe = plane->pipe; 1126 1127 intel_display_power_put(dev_priv, power_domain, wakeref); 1128 1129 return ret; 1130 } 1131 1132 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state, 1133 const struct intel_plane_state *plane_state, 1134 unsigned int *num, unsigned int *den) 1135 { 1136 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 1137 const struct drm_framebuffer *fb = plane_state->hw.fb; 1138 unsigned int cpp = fb->format->cpp[0]; 1139 1140 if (hweight8(active_planes) == 2) { 1141 switch (cpp) { 1142 case 8: 1143 *num = 10; 1144 *den = 8; 1145 break; 1146 case 4: 1147 *num = 17; 1148 *den = 16; 1149 break; 1150 default: 1151 *num = 1; 1152 *den = 1; 1153 break; 1154 } 1155 } else { 1156 switch (cpp) { 1157 case 8: 1158 *num = 9; 1159 *den = 8; 1160 break; 1161 default: 1162 *num = 1; 1163 *den = 1; 1164 break; 1165 } 1166 } 1167 } 1168 1169 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state, 1170 const struct intel_plane_state *plane_state, 1171 unsigned int *num, unsigned int *den) 1172 { 1173 const struct drm_framebuffer *fb = plane_state->hw.fb; 1174 unsigned int cpp = fb->format->cpp[0]; 1175 1176 switch (cpp) { 1177 case 8: 1178 *num = 12; 1179 *den = 8; 1180 break; 1181 case 4: 1182 *num = 19; 1183 *den = 16; 1184 break; 1185 case 2: 1186 *num = 33; 1187 *den = 32; 1188 break; 1189 default: 1190 *num = 1; 1191 *den = 1; 1192 break; 1193 } 1194 } 1195 1196 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 1197 const struct intel_plane_state *plane_state) 1198 { 1199 unsigned int pixel_rate; 1200 unsigned int num, den; 1201 1202 /* 1203 * Note that crtc_state->pixel_rate accounts for both 1204 * horizontal and vertical panel fitter downscaling factors. 1205 * Pre-HSW bspec tells us to only consider the horizontal 1206 * downscaling factor here. We ignore that and just consider 1207 * both for simplicity. 1208 */ 1209 pixel_rate = crtc_state->pixel_rate; 1210 1211 ivb_plane_ratio(crtc_state, plane_state, &num, &den); 1212 1213 return DIV_ROUND_UP(pixel_rate * num, den); 1214 } 1215 1216 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 1217 const struct intel_plane_state *plane_state) 1218 { 1219 unsigned int src_w, dst_w, pixel_rate; 1220 unsigned int num, den; 1221 1222 /* 1223 * Note that crtc_state->pixel_rate accounts for both 1224 * horizontal and vertical panel fitter downscaling factors. 1225 * Pre-HSW bspec tells us to only consider the horizontal 1226 * downscaling factor here. We ignore that and just consider 1227 * both for simplicity. 1228 */ 1229 pixel_rate = crtc_state->pixel_rate; 1230 1231 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1232 dst_w = drm_rect_width(&plane_state->uapi.dst); 1233 1234 if (src_w != dst_w) 1235 ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den); 1236 else 1237 ivb_plane_ratio(crtc_state, plane_state, &num, &den); 1238 1239 /* Horizontal downscaling limits the maximum pixel rate */ 1240 dst_w = min(src_w, dst_w); 1241 1242 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w), 1243 den * dst_w); 1244 } 1245 1246 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state, 1247 const struct intel_plane_state *plane_state, 1248 unsigned int *num, unsigned int *den) 1249 { 1250 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 1251 const struct drm_framebuffer *fb = plane_state->hw.fb; 1252 unsigned int cpp = fb->format->cpp[0]; 1253 1254 if (hweight8(active_planes) == 2) { 1255 switch (cpp) { 1256 case 8: 1257 *num = 10; 1258 *den = 8; 1259 break; 1260 default: 1261 *num = 1; 1262 *den = 1; 1263 break; 1264 } 1265 } else { 1266 switch (cpp) { 1267 case 8: 1268 *num = 9; 1269 *den = 8; 1270 break; 1271 default: 1272 *num = 1; 1273 *den = 1; 1274 break; 1275 } 1276 } 1277 } 1278 1279 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 1280 const struct intel_plane_state *plane_state) 1281 { 1282 unsigned int pixel_rate = crtc_state->pixel_rate; 1283 unsigned int num, den; 1284 1285 hsw_plane_ratio(crtc_state, plane_state, &num, &den); 1286 1287 return DIV_ROUND_UP(pixel_rate * num, den); 1288 } 1289 1290 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1291 { 1292 u32 sprctl = 0; 1293 1294 if (crtc_state->gamma_enable) 1295 sprctl |= SPRITE_GAMMA_ENABLE; 1296 1297 if (crtc_state->csc_enable) 1298 sprctl |= SPRITE_PIPE_CSC_ENABLE; 1299 1300 return sprctl; 1301 } 1302 1303 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state) 1304 { 1305 struct drm_i915_private *dev_priv = 1306 to_i915(plane_state->uapi.plane->dev); 1307 const struct drm_framebuffer *fb = plane_state->hw.fb; 1308 1309 return fb->format->cpp[0] == 8 && 1310 (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)); 1311 } 1312 1313 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, 1314 const struct intel_plane_state *plane_state) 1315 { 1316 struct drm_i915_private *dev_priv = 1317 to_i915(plane_state->uapi.plane->dev); 1318 const struct drm_framebuffer *fb = plane_state->hw.fb; 1319 unsigned int rotation = plane_state->hw.rotation; 1320 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1321 u32 sprctl; 1322 1323 sprctl = SPRITE_ENABLE; 1324 1325 if (IS_IVYBRIDGE(dev_priv)) 1326 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 1327 1328 switch (fb->format->format) { 1329 case DRM_FORMAT_XBGR8888: 1330 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 1331 break; 1332 case DRM_FORMAT_XRGB8888: 1333 sprctl |= SPRITE_FORMAT_RGBX888; 1334 break; 1335 case DRM_FORMAT_XBGR2101010: 1336 sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX; 1337 break; 1338 case DRM_FORMAT_XRGB2101010: 1339 sprctl |= SPRITE_FORMAT_RGBX101010; 1340 break; 1341 case DRM_FORMAT_XBGR16161616F: 1342 sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX; 1343 break; 1344 case DRM_FORMAT_XRGB16161616F: 1345 sprctl |= SPRITE_FORMAT_RGBX161616; 1346 break; 1347 case DRM_FORMAT_YUYV: 1348 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 1349 break; 1350 case DRM_FORMAT_YVYU: 1351 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 1352 break; 1353 case DRM_FORMAT_UYVY: 1354 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 1355 break; 1356 case DRM_FORMAT_VYUY: 1357 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 1358 break; 1359 default: 1360 MISSING_CASE(fb->format->format); 1361 return 0; 1362 } 1363 1364 if (!ivb_need_sprite_gamma(plane_state)) 1365 sprctl |= SPRITE_INT_GAMMA_DISABLE; 1366 1367 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 1368 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; 1369 1370 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1371 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE; 1372 1373 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1374 sprctl |= SPRITE_TILED; 1375 1376 if (rotation & DRM_MODE_ROTATE_180) 1377 sprctl |= SPRITE_ROTATE_180; 1378 1379 if (key->flags & I915_SET_COLORKEY_DESTINATION) 1380 sprctl |= SPRITE_DEST_KEY; 1381 else if (key->flags & I915_SET_COLORKEY_SOURCE) 1382 sprctl |= SPRITE_SOURCE_KEY; 1383 1384 return sprctl; 1385 } 1386 1387 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state, 1388 u16 gamma[18]) 1389 { 1390 int scale, i; 1391 1392 /* 1393 * WaFP16GammaEnabling:ivb,hsw 1394 * "Workaround : When using the 64-bit format, the sprite output 1395 * on each color channel has one quarter amplitude. It can be 1396 * brought up to full amplitude by using sprite internal gamma 1397 * correction, pipe gamma correction, or pipe color space 1398 * conversion to multiply the sprite output by four." 1399 */ 1400 scale = 4; 1401 1402 for (i = 0; i < 16; i++) 1403 gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1); 1404 1405 gamma[i] = min((scale * i << 10) / 16, 1 << 10); 1406 i++; 1407 1408 gamma[i] = 3 << 10; 1409 i++; 1410 } 1411 1412 static void ivb_update_gamma(const struct intel_plane_state *plane_state) 1413 { 1414 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1415 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1416 enum pipe pipe = plane->pipe; 1417 u16 gamma[18]; 1418 int i; 1419 1420 if (!ivb_need_sprite_gamma(plane_state)) 1421 return; 1422 1423 ivb_sprite_linear_gamma(plane_state, gamma); 1424 1425 /* FIXME these register are single buffered :( */ 1426 for (i = 0; i < 16; i++) 1427 I915_WRITE_FW(SPRGAMC(pipe, i), 1428 gamma[i] << 20 | 1429 gamma[i] << 10 | 1430 gamma[i]); 1431 1432 I915_WRITE_FW(SPRGAMC16(pipe, 0), gamma[i]); 1433 I915_WRITE_FW(SPRGAMC16(pipe, 1), gamma[i]); 1434 I915_WRITE_FW(SPRGAMC16(pipe, 2), gamma[i]); 1435 i++; 1436 1437 I915_WRITE_FW(SPRGAMC17(pipe, 0), gamma[i]); 1438 I915_WRITE_FW(SPRGAMC17(pipe, 1), gamma[i]); 1439 I915_WRITE_FW(SPRGAMC17(pipe, 2), gamma[i]); 1440 i++; 1441 } 1442 1443 static void 1444 ivb_update_plane(struct intel_plane *plane, 1445 const struct intel_crtc_state *crtc_state, 1446 const struct intel_plane_state *plane_state) 1447 { 1448 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1449 enum pipe pipe = plane->pipe; 1450 u32 sprsurf_offset = plane_state->color_plane[0].offset; 1451 u32 linear_offset; 1452 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1453 int crtc_x = plane_state->uapi.dst.x1; 1454 int crtc_y = plane_state->uapi.dst.y1; 1455 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1456 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1457 u32 x = plane_state->color_plane[0].x; 1458 u32 y = plane_state->color_plane[0].y; 1459 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1460 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 1461 u32 sprctl, sprscale = 0; 1462 unsigned long irqflags; 1463 1464 sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state); 1465 1466 /* Sizes are 0 based */ 1467 src_w--; 1468 src_h--; 1469 crtc_w--; 1470 crtc_h--; 1471 1472 if (crtc_w != src_w || crtc_h != src_h) 1473 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 1474 1475 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1476 1477 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1478 1479 I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride); 1480 I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 1481 I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 1482 if (IS_IVYBRIDGE(dev_priv)) 1483 I915_WRITE_FW(SPRSCALE(pipe), sprscale); 1484 1485 if (key->flags) { 1486 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value); 1487 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 1488 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value); 1489 } 1490 1491 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 1492 * register */ 1493 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 1494 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x); 1495 } else { 1496 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset); 1497 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x); 1498 } 1499 1500 /* 1501 * The control register self-arms if the plane was previously 1502 * disabled. Try to make the plane enable atomic by writing 1503 * the control register just before the surface register. 1504 */ 1505 I915_WRITE_FW(SPRCTL(pipe), sprctl); 1506 I915_WRITE_FW(SPRSURF(pipe), 1507 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1508 1509 ivb_update_gamma(plane_state); 1510 1511 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1512 } 1513 1514 static void 1515 ivb_disable_plane(struct intel_plane *plane, 1516 const struct intel_crtc_state *crtc_state) 1517 { 1518 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1519 enum pipe pipe = plane->pipe; 1520 unsigned long irqflags; 1521 1522 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1523 1524 I915_WRITE_FW(SPRCTL(pipe), 0); 1525 /* Disable the scaler */ 1526 if (IS_IVYBRIDGE(dev_priv)) 1527 I915_WRITE_FW(SPRSCALE(pipe), 0); 1528 I915_WRITE_FW(SPRSURF(pipe), 0); 1529 1530 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1531 } 1532 1533 static bool 1534 ivb_plane_get_hw_state(struct intel_plane *plane, 1535 enum pipe *pipe) 1536 { 1537 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1538 enum intel_display_power_domain power_domain; 1539 intel_wakeref_t wakeref; 1540 bool ret; 1541 1542 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1543 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1544 if (!wakeref) 1545 return false; 1546 1547 ret = I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE; 1548 1549 *pipe = plane->pipe; 1550 1551 intel_display_power_put(dev_priv, power_domain, wakeref); 1552 1553 return ret; 1554 } 1555 1556 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 1557 const struct intel_plane_state *plane_state) 1558 { 1559 const struct drm_framebuffer *fb = plane_state->hw.fb; 1560 unsigned int hscale, pixel_rate; 1561 unsigned int limit, decimate; 1562 1563 /* 1564 * Note that crtc_state->pixel_rate accounts for both 1565 * horizontal and vertical panel fitter downscaling factors. 1566 * Pre-HSW bspec tells us to only consider the horizontal 1567 * downscaling factor here. We ignore that and just consider 1568 * both for simplicity. 1569 */ 1570 pixel_rate = crtc_state->pixel_rate; 1571 1572 /* Horizontal downscaling limits the maximum pixel rate */ 1573 hscale = drm_rect_calc_hscale(&plane_state->uapi.src, 1574 &plane_state->uapi.dst, 1575 0, INT_MAX); 1576 if (hscale < 0x10000) 1577 return pixel_rate; 1578 1579 /* Decimation steps at 2x,4x,8x,16x */ 1580 decimate = ilog2(hscale >> 16); 1581 hscale >>= decimate; 1582 1583 /* Starting limit is 90% of cdclk */ 1584 limit = 9; 1585 1586 /* -10% per decimation step */ 1587 limit -= decimate; 1588 1589 /* -10% for RGB */ 1590 if (fb->format->cpp[0] >= 4) 1591 limit--; /* -10% for RGB */ 1592 1593 /* 1594 * We should also do -10% if sprite scaling is enabled 1595 * on the other pipe, but we can't really check for that, 1596 * so we ignore it. 1597 */ 1598 1599 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale), 1600 limit << 16); 1601 } 1602 1603 static unsigned int 1604 g4x_sprite_max_stride(struct intel_plane *plane, 1605 u32 pixel_format, u64 modifier, 1606 unsigned int rotation) 1607 { 1608 return 16384; 1609 } 1610 1611 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1612 { 1613 u32 dvscntr = 0; 1614 1615 if (crtc_state->gamma_enable) 1616 dvscntr |= DVS_GAMMA_ENABLE; 1617 1618 if (crtc_state->csc_enable) 1619 dvscntr |= DVS_PIPE_CSC_ENABLE; 1620 1621 return dvscntr; 1622 } 1623 1624 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, 1625 const struct intel_plane_state *plane_state) 1626 { 1627 struct drm_i915_private *dev_priv = 1628 to_i915(plane_state->uapi.plane->dev); 1629 const struct drm_framebuffer *fb = plane_state->hw.fb; 1630 unsigned int rotation = plane_state->hw.rotation; 1631 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1632 u32 dvscntr; 1633 1634 dvscntr = DVS_ENABLE; 1635 1636 if (IS_GEN(dev_priv, 6)) 1637 dvscntr |= DVS_TRICKLE_FEED_DISABLE; 1638 1639 switch (fb->format->format) { 1640 case DRM_FORMAT_XBGR8888: 1641 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 1642 break; 1643 case DRM_FORMAT_XRGB8888: 1644 dvscntr |= DVS_FORMAT_RGBX888; 1645 break; 1646 case DRM_FORMAT_XBGR2101010: 1647 dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR; 1648 break; 1649 case DRM_FORMAT_XRGB2101010: 1650 dvscntr |= DVS_FORMAT_RGBX101010; 1651 break; 1652 case DRM_FORMAT_XBGR16161616F: 1653 dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR; 1654 break; 1655 case DRM_FORMAT_XRGB16161616F: 1656 dvscntr |= DVS_FORMAT_RGBX161616; 1657 break; 1658 case DRM_FORMAT_YUYV: 1659 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 1660 break; 1661 case DRM_FORMAT_YVYU: 1662 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 1663 break; 1664 case DRM_FORMAT_UYVY: 1665 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 1666 break; 1667 case DRM_FORMAT_VYUY: 1668 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 1669 break; 1670 default: 1671 MISSING_CASE(fb->format->format); 1672 return 0; 1673 } 1674 1675 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 1676 dvscntr |= DVS_YUV_FORMAT_BT709; 1677 1678 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1679 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE; 1680 1681 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1682 dvscntr |= DVS_TILED; 1683 1684 if (rotation & DRM_MODE_ROTATE_180) 1685 dvscntr |= DVS_ROTATE_180; 1686 1687 if (key->flags & I915_SET_COLORKEY_DESTINATION) 1688 dvscntr |= DVS_DEST_KEY; 1689 else if (key->flags & I915_SET_COLORKEY_SOURCE) 1690 dvscntr |= DVS_SOURCE_KEY; 1691 1692 return dvscntr; 1693 } 1694 1695 static void g4x_update_gamma(const struct intel_plane_state *plane_state) 1696 { 1697 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1698 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1699 const struct drm_framebuffer *fb = plane_state->hw.fb; 1700 enum pipe pipe = plane->pipe; 1701 u16 gamma[8]; 1702 int i; 1703 1704 /* Seems RGB data bypasses the gamma always */ 1705 if (!fb->format->is_yuv) 1706 return; 1707 1708 i9xx_plane_linear_gamma(gamma); 1709 1710 /* FIXME these register are single buffered :( */ 1711 /* The two end points are implicit (0.0 and 1.0) */ 1712 for (i = 1; i < 8 - 1; i++) 1713 I915_WRITE_FW(DVSGAMC_G4X(pipe, i - 1), 1714 gamma[i] << 16 | 1715 gamma[i] << 8 | 1716 gamma[i]); 1717 } 1718 1719 static void ilk_sprite_linear_gamma(u16 gamma[17]) 1720 { 1721 int i; 1722 1723 for (i = 0; i < 17; i++) 1724 gamma[i] = (i << 10) / 16; 1725 } 1726 1727 static void ilk_update_gamma(const struct intel_plane_state *plane_state) 1728 { 1729 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1730 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1731 const struct drm_framebuffer *fb = plane_state->hw.fb; 1732 enum pipe pipe = plane->pipe; 1733 u16 gamma[17]; 1734 int i; 1735 1736 /* Seems RGB data bypasses the gamma always */ 1737 if (!fb->format->is_yuv) 1738 return; 1739 1740 ilk_sprite_linear_gamma(gamma); 1741 1742 /* FIXME these register are single buffered :( */ 1743 for (i = 0; i < 16; i++) 1744 I915_WRITE_FW(DVSGAMC_ILK(pipe, i), 1745 gamma[i] << 20 | 1746 gamma[i] << 10 | 1747 gamma[i]); 1748 1749 I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 0), gamma[i]); 1750 I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 1), gamma[i]); 1751 I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 2), gamma[i]); 1752 i++; 1753 } 1754 1755 static void 1756 g4x_update_plane(struct intel_plane *plane, 1757 const struct intel_crtc_state *crtc_state, 1758 const struct intel_plane_state *plane_state) 1759 { 1760 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1761 enum pipe pipe = plane->pipe; 1762 u32 dvssurf_offset = plane_state->color_plane[0].offset; 1763 u32 linear_offset; 1764 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1765 int crtc_x = plane_state->uapi.dst.x1; 1766 int crtc_y = plane_state->uapi.dst.y1; 1767 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1768 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1769 u32 x = plane_state->color_plane[0].x; 1770 u32 y = plane_state->color_plane[0].y; 1771 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1772 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 1773 u32 dvscntr, dvsscale = 0; 1774 unsigned long irqflags; 1775 1776 dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state); 1777 1778 /* Sizes are 0 based */ 1779 src_w--; 1780 src_h--; 1781 crtc_w--; 1782 crtc_h--; 1783 1784 if (crtc_w != src_w || crtc_h != src_h) 1785 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 1786 1787 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1788 1789 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1790 1791 I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride); 1792 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 1793 I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 1794 I915_WRITE_FW(DVSSCALE(pipe), dvsscale); 1795 1796 if (key->flags) { 1797 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value); 1798 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 1799 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value); 1800 } 1801 1802 I915_WRITE_FW(DVSLINOFF(pipe), linear_offset); 1803 I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x); 1804 1805 /* 1806 * The control register self-arms if the plane was previously 1807 * disabled. Try to make the plane enable atomic by writing 1808 * the control register just before the surface register. 1809 */ 1810 I915_WRITE_FW(DVSCNTR(pipe), dvscntr); 1811 I915_WRITE_FW(DVSSURF(pipe), 1812 intel_plane_ggtt_offset(plane_state) + dvssurf_offset); 1813 1814 if (IS_G4X(dev_priv)) 1815 g4x_update_gamma(plane_state); 1816 else 1817 ilk_update_gamma(plane_state); 1818 1819 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1820 } 1821 1822 static void 1823 g4x_disable_plane(struct intel_plane *plane, 1824 const struct intel_crtc_state *crtc_state) 1825 { 1826 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1827 enum pipe pipe = plane->pipe; 1828 unsigned long irqflags; 1829 1830 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1831 1832 I915_WRITE_FW(DVSCNTR(pipe), 0); 1833 /* Disable the scaler */ 1834 I915_WRITE_FW(DVSSCALE(pipe), 0); 1835 I915_WRITE_FW(DVSSURF(pipe), 0); 1836 1837 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1838 } 1839 1840 static bool 1841 g4x_plane_get_hw_state(struct intel_plane *plane, 1842 enum pipe *pipe) 1843 { 1844 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1845 enum intel_display_power_domain power_domain; 1846 intel_wakeref_t wakeref; 1847 bool ret; 1848 1849 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1850 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1851 if (!wakeref) 1852 return false; 1853 1854 ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE; 1855 1856 *pipe = plane->pipe; 1857 1858 intel_display_power_put(dev_priv, power_domain, wakeref); 1859 1860 return ret; 1861 } 1862 1863 static bool intel_fb_scalable(const struct drm_framebuffer *fb) 1864 { 1865 if (!fb) 1866 return false; 1867 1868 switch (fb->format->format) { 1869 case DRM_FORMAT_C8: 1870 return false; 1871 case DRM_FORMAT_XRGB16161616F: 1872 case DRM_FORMAT_ARGB16161616F: 1873 case DRM_FORMAT_XBGR16161616F: 1874 case DRM_FORMAT_ABGR16161616F: 1875 return INTEL_GEN(to_i915(fb->dev)) >= 11; 1876 default: 1877 return true; 1878 } 1879 } 1880 1881 static int 1882 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state, 1883 struct intel_plane_state *plane_state) 1884 { 1885 const struct drm_framebuffer *fb = plane_state->hw.fb; 1886 const struct drm_rect *src = &plane_state->uapi.src; 1887 const struct drm_rect *dst = &plane_state->uapi.dst; 1888 int src_x, src_w, src_h, crtc_w, crtc_h; 1889 const struct drm_display_mode *adjusted_mode = 1890 &crtc_state->hw.adjusted_mode; 1891 unsigned int stride = plane_state->color_plane[0].stride; 1892 unsigned int cpp = fb->format->cpp[0]; 1893 unsigned int width_bytes; 1894 int min_width, min_height; 1895 1896 crtc_w = drm_rect_width(dst); 1897 crtc_h = drm_rect_height(dst); 1898 1899 src_x = src->x1 >> 16; 1900 src_w = drm_rect_width(src) >> 16; 1901 src_h = drm_rect_height(src) >> 16; 1902 1903 if (src_w == crtc_w && src_h == crtc_h) 1904 return 0; 1905 1906 min_width = 3; 1907 1908 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 1909 if (src_h & 1) { 1910 DRM_DEBUG_KMS("Source height must be even with interlaced modes\n"); 1911 return -EINVAL; 1912 } 1913 min_height = 6; 1914 } else { 1915 min_height = 3; 1916 } 1917 1918 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1919 1920 if (src_w < min_width || src_h < min_height || 1921 src_w > 2048 || src_h > 2048) { 1922 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n", 1923 src_w, src_h, min_width, min_height, 2048, 2048); 1924 return -EINVAL; 1925 } 1926 1927 if (width_bytes > 4096) { 1928 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n", 1929 width_bytes, 4096); 1930 return -EINVAL; 1931 } 1932 1933 if (stride > 4096) { 1934 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n", 1935 stride, 4096); 1936 return -EINVAL; 1937 } 1938 1939 return 0; 1940 } 1941 1942 static int 1943 g4x_sprite_check(struct intel_crtc_state *crtc_state, 1944 struct intel_plane_state *plane_state) 1945 { 1946 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1947 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1948 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1949 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1950 int ret; 1951 1952 if (intel_fb_scalable(plane_state->hw.fb)) { 1953 if (INTEL_GEN(dev_priv) < 7) { 1954 min_scale = 1; 1955 max_scale = 16 << 16; 1956 } else if (IS_IVYBRIDGE(dev_priv)) { 1957 min_scale = 1; 1958 max_scale = 2 << 16; 1959 } 1960 } 1961 1962 ret = drm_atomic_helper_check_plane_state(&plane_state->uapi, 1963 &crtc_state->uapi, 1964 min_scale, max_scale, 1965 true, true); 1966 if (ret) 1967 return ret; 1968 1969 ret = i9xx_check_plane_surface(plane_state); 1970 if (ret) 1971 return ret; 1972 1973 if (!plane_state->uapi.visible) 1974 return 0; 1975 1976 ret = intel_plane_check_src_coordinates(plane_state); 1977 if (ret) 1978 return ret; 1979 1980 ret = g4x_sprite_check_scaling(crtc_state, plane_state); 1981 if (ret) 1982 return ret; 1983 1984 if (INTEL_GEN(dev_priv) >= 7) 1985 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state); 1986 else 1987 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state); 1988 1989 return 0; 1990 } 1991 1992 int chv_plane_check_rotation(const struct intel_plane_state *plane_state) 1993 { 1994 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1995 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1996 unsigned int rotation = plane_state->hw.rotation; 1997 1998 /* CHV ignores the mirror bit when the rotate bit is set :( */ 1999 if (IS_CHERRYVIEW(dev_priv) && 2000 rotation & DRM_MODE_ROTATE_180 && 2001 rotation & DRM_MODE_REFLECT_X) { 2002 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n"); 2003 return -EINVAL; 2004 } 2005 2006 return 0; 2007 } 2008 2009 static int 2010 vlv_sprite_check(struct intel_crtc_state *crtc_state, 2011 struct intel_plane_state *plane_state) 2012 { 2013 int ret; 2014 2015 ret = chv_plane_check_rotation(plane_state); 2016 if (ret) 2017 return ret; 2018 2019 ret = drm_atomic_helper_check_plane_state(&plane_state->uapi, 2020 &crtc_state->uapi, 2021 DRM_PLANE_HELPER_NO_SCALING, 2022 DRM_PLANE_HELPER_NO_SCALING, 2023 true, true); 2024 if (ret) 2025 return ret; 2026 2027 ret = i9xx_check_plane_surface(plane_state); 2028 if (ret) 2029 return ret; 2030 2031 if (!plane_state->uapi.visible) 2032 return 0; 2033 2034 ret = intel_plane_check_src_coordinates(plane_state); 2035 if (ret) 2036 return ret; 2037 2038 plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state); 2039 2040 return 0; 2041 } 2042 2043 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, 2044 const struct intel_plane_state *plane_state) 2045 { 2046 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 2047 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 2048 const struct drm_framebuffer *fb = plane_state->hw.fb; 2049 unsigned int rotation = plane_state->hw.rotation; 2050 struct drm_format_name_buf format_name; 2051 2052 if (!fb) 2053 return 0; 2054 2055 if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) && 2056 is_ccs_modifier(fb->modifier)) { 2057 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n", 2058 rotation); 2059 return -EINVAL; 2060 } 2061 2062 if (rotation & DRM_MODE_REFLECT_X && 2063 fb->modifier == DRM_FORMAT_MOD_LINEAR) { 2064 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n"); 2065 return -EINVAL; 2066 } 2067 2068 if (drm_rotation_90_or_270(rotation)) { 2069 if (fb->modifier != I915_FORMAT_MOD_Y_TILED && 2070 fb->modifier != I915_FORMAT_MOD_Yf_TILED) { 2071 DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); 2072 return -EINVAL; 2073 } 2074 2075 /* 2076 * 90/270 is not allowed with RGB64 16:16:16:16 and 2077 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards. 2078 */ 2079 switch (fb->format->format) { 2080 case DRM_FORMAT_RGB565: 2081 if (INTEL_GEN(dev_priv) >= 11) 2082 break; 2083 /* fall through */ 2084 case DRM_FORMAT_C8: 2085 case DRM_FORMAT_XRGB16161616F: 2086 case DRM_FORMAT_XBGR16161616F: 2087 case DRM_FORMAT_ARGB16161616F: 2088 case DRM_FORMAT_ABGR16161616F: 2089 case DRM_FORMAT_Y210: 2090 case DRM_FORMAT_Y212: 2091 case DRM_FORMAT_Y216: 2092 case DRM_FORMAT_XVYU12_16161616: 2093 case DRM_FORMAT_XVYU16161616: 2094 DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", 2095 drm_get_format_name(fb->format->format, 2096 &format_name)); 2097 return -EINVAL; 2098 default: 2099 break; 2100 } 2101 } 2102 2103 /* Y-tiling is not supported in IF-ID Interlace mode */ 2104 if (crtc_state->hw.enable && 2105 crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE && 2106 (fb->modifier == I915_FORMAT_MOD_Y_TILED || 2107 fb->modifier == I915_FORMAT_MOD_Yf_TILED || 2108 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 2109 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS || 2110 fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || 2111 fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)) { 2112 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n"); 2113 return -EINVAL; 2114 } 2115 2116 return 0; 2117 } 2118 2119 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state, 2120 const struct intel_plane_state *plane_state) 2121 { 2122 struct drm_i915_private *dev_priv = 2123 to_i915(plane_state->uapi.plane->dev); 2124 int crtc_x = plane_state->uapi.dst.x1; 2125 int crtc_w = drm_rect_width(&plane_state->uapi.dst); 2126 int pipe_src_w = crtc_state->pipe_src_w; 2127 2128 /* 2129 * Display WA #1175: cnl,glk 2130 * Planes other than the cursor may cause FIFO underflow and display 2131 * corruption if starting less than 4 pixels from the right edge of 2132 * the screen. 2133 * Besides the above WA fix the similar problem, where planes other 2134 * than the cursor ending less than 4 pixels from the left edge of the 2135 * screen may cause FIFO underflow and display corruption. 2136 */ 2137 if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) && 2138 (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { 2139 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n", 2140 crtc_x + crtc_w < 4 ? "end" : "start", 2141 crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x, 2142 4, pipe_src_w - 4); 2143 return -ERANGE; 2144 } 2145 2146 return 0; 2147 } 2148 2149 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) 2150 { 2151 const struct drm_framebuffer *fb = plane_state->hw.fb; 2152 unsigned int rotation = plane_state->hw.rotation; 2153 int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 2154 2155 /* Display WA #1106 */ 2156 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 2157 src_w & 3 && 2158 (rotation == DRM_MODE_ROTATE_270 || 2159 rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { 2160 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); 2161 return -EINVAL; 2162 } 2163 2164 return 0; 2165 } 2166 2167 static int skl_plane_max_scale(struct drm_i915_private *dev_priv, 2168 const struct drm_framebuffer *fb) 2169 { 2170 /* 2171 * We don't yet know the final source width nor 2172 * whether we can use the HQ scaler mode. Assume 2173 * the best case. 2174 * FIXME need to properly check this later. 2175 */ 2176 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) || 2177 !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) 2178 return 0x30000 - 1; 2179 else 2180 return 0x20000 - 1; 2181 } 2182 2183 static int skl_plane_check(struct intel_crtc_state *crtc_state, 2184 struct intel_plane_state *plane_state) 2185 { 2186 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 2187 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 2188 const struct drm_framebuffer *fb = plane_state->hw.fb; 2189 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 2190 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 2191 int ret; 2192 2193 ret = skl_plane_check_fb(crtc_state, plane_state); 2194 if (ret) 2195 return ret; 2196 2197 /* use scaler when colorkey is not required */ 2198 if (!plane_state->ckey.flags && intel_fb_scalable(fb)) { 2199 min_scale = 1; 2200 max_scale = skl_plane_max_scale(dev_priv, fb); 2201 } 2202 2203 ret = drm_atomic_helper_check_plane_state(&plane_state->uapi, 2204 &crtc_state->uapi, 2205 min_scale, max_scale, 2206 true, true); 2207 if (ret) 2208 return ret; 2209 2210 ret = skl_check_plane_surface(plane_state); 2211 if (ret) 2212 return ret; 2213 2214 if (!plane_state->uapi.visible) 2215 return 0; 2216 2217 ret = skl_plane_check_dst_coordinates(crtc_state, plane_state); 2218 if (ret) 2219 return ret; 2220 2221 ret = intel_plane_check_src_coordinates(plane_state); 2222 if (ret) 2223 return ret; 2224 2225 ret = skl_plane_check_nv12_rotation(plane_state); 2226 if (ret) 2227 return ret; 2228 2229 /* HW only has 8 bits pixel precision, disable plane if invisible */ 2230 if (!(plane_state->hw.alpha >> 8)) 2231 plane_state->uapi.visible = false; 2232 2233 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); 2234 2235 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 2236 plane_state->color_ctl = glk_plane_color_ctl(crtc_state, 2237 plane_state); 2238 2239 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 2240 icl_is_hdr_plane(dev_priv, plane->id)) 2241 /* Enable and use MPEG-2 chroma siting */ 2242 plane_state->cus_ctl = PLANE_CUS_ENABLE | 2243 PLANE_CUS_HPHASE_0 | 2244 PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25; 2245 else 2246 plane_state->cus_ctl = 0; 2247 2248 return 0; 2249 } 2250 2251 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv) 2252 { 2253 return INTEL_GEN(dev_priv) >= 9; 2254 } 2255 2256 static void intel_plane_set_ckey(struct intel_plane_state *plane_state, 2257 const struct drm_intel_sprite_colorkey *set) 2258 { 2259 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 2260 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 2261 struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 2262 2263 *key = *set; 2264 2265 /* 2266 * We want src key enabled on the 2267 * sprite and not on the primary. 2268 */ 2269 if (plane->id == PLANE_PRIMARY && 2270 set->flags & I915_SET_COLORKEY_SOURCE) 2271 key->flags = 0; 2272 2273 /* 2274 * On SKL+ we want dst key enabled on 2275 * the primary and not on the sprite. 2276 */ 2277 if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY && 2278 set->flags & I915_SET_COLORKEY_DESTINATION) 2279 key->flags = 0; 2280 } 2281 2282 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, 2283 struct drm_file *file_priv) 2284 { 2285 struct drm_i915_private *dev_priv = to_i915(dev); 2286 struct drm_intel_sprite_colorkey *set = data; 2287 struct drm_plane *plane; 2288 struct drm_plane_state *plane_state; 2289 struct drm_atomic_state *state; 2290 struct drm_modeset_acquire_ctx ctx; 2291 int ret = 0; 2292 2293 /* ignore the pointless "none" flag */ 2294 set->flags &= ~I915_SET_COLORKEY_NONE; 2295 2296 if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 2297 return -EINVAL; 2298 2299 /* Make sure we don't try to enable both src & dest simultaneously */ 2300 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 2301 return -EINVAL; 2302 2303 if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 2304 set->flags & I915_SET_COLORKEY_DESTINATION) 2305 return -EINVAL; 2306 2307 plane = drm_plane_find(dev, file_priv, set->plane_id); 2308 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) 2309 return -ENOENT; 2310 2311 /* 2312 * SKL+ only plane 2 can do destination keying against plane 1. 2313 * Also multiple planes can't do destination keying on the same 2314 * pipe simultaneously. 2315 */ 2316 if (INTEL_GEN(dev_priv) >= 9 && 2317 to_intel_plane(plane)->id >= PLANE_SPRITE1 && 2318 set->flags & I915_SET_COLORKEY_DESTINATION) 2319 return -EINVAL; 2320 2321 drm_modeset_acquire_init(&ctx, 0); 2322 2323 state = drm_atomic_state_alloc(plane->dev); 2324 if (!state) { 2325 ret = -ENOMEM; 2326 goto out; 2327 } 2328 state->acquire_ctx = &ctx; 2329 2330 while (1) { 2331 plane_state = drm_atomic_get_plane_state(state, plane); 2332 ret = PTR_ERR_OR_ZERO(plane_state); 2333 if (!ret) 2334 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 2335 2336 /* 2337 * On some platforms we have to configure 2338 * the dst colorkey on the primary plane. 2339 */ 2340 if (!ret && has_dst_key_in_primary_plane(dev_priv)) { 2341 struct intel_crtc *crtc = 2342 intel_get_crtc_for_pipe(dev_priv, 2343 to_intel_plane(plane)->pipe); 2344 2345 plane_state = drm_atomic_get_plane_state(state, 2346 crtc->base.primary); 2347 ret = PTR_ERR_OR_ZERO(plane_state); 2348 if (!ret) 2349 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 2350 } 2351 2352 if (!ret) 2353 ret = drm_atomic_commit(state); 2354 2355 if (ret != -EDEADLK) 2356 break; 2357 2358 drm_atomic_state_clear(state); 2359 drm_modeset_backoff(&ctx); 2360 } 2361 2362 drm_atomic_state_put(state); 2363 out: 2364 drm_modeset_drop_locks(&ctx); 2365 drm_modeset_acquire_fini(&ctx); 2366 return ret; 2367 } 2368 2369 static const u32 g4x_plane_formats[] = { 2370 DRM_FORMAT_XRGB8888, 2371 DRM_FORMAT_YUYV, 2372 DRM_FORMAT_YVYU, 2373 DRM_FORMAT_UYVY, 2374 DRM_FORMAT_VYUY, 2375 }; 2376 2377 static const u64 i9xx_plane_format_modifiers[] = { 2378 I915_FORMAT_MOD_X_TILED, 2379 DRM_FORMAT_MOD_LINEAR, 2380 DRM_FORMAT_MOD_INVALID 2381 }; 2382 2383 static const u32 snb_plane_formats[] = { 2384 DRM_FORMAT_XRGB8888, 2385 DRM_FORMAT_XBGR8888, 2386 DRM_FORMAT_XRGB2101010, 2387 DRM_FORMAT_XBGR2101010, 2388 DRM_FORMAT_XRGB16161616F, 2389 DRM_FORMAT_XBGR16161616F, 2390 DRM_FORMAT_YUYV, 2391 DRM_FORMAT_YVYU, 2392 DRM_FORMAT_UYVY, 2393 DRM_FORMAT_VYUY, 2394 }; 2395 2396 static const u32 vlv_plane_formats[] = { 2397 DRM_FORMAT_C8, 2398 DRM_FORMAT_RGB565, 2399 DRM_FORMAT_XRGB8888, 2400 DRM_FORMAT_XBGR8888, 2401 DRM_FORMAT_ARGB8888, 2402 DRM_FORMAT_ABGR8888, 2403 DRM_FORMAT_XBGR2101010, 2404 DRM_FORMAT_ABGR2101010, 2405 DRM_FORMAT_YUYV, 2406 DRM_FORMAT_YVYU, 2407 DRM_FORMAT_UYVY, 2408 DRM_FORMAT_VYUY, 2409 }; 2410 2411 static const u32 chv_pipe_b_sprite_formats[] = { 2412 DRM_FORMAT_C8, 2413 DRM_FORMAT_RGB565, 2414 DRM_FORMAT_XRGB8888, 2415 DRM_FORMAT_XBGR8888, 2416 DRM_FORMAT_ARGB8888, 2417 DRM_FORMAT_ABGR8888, 2418 DRM_FORMAT_XRGB2101010, 2419 DRM_FORMAT_XBGR2101010, 2420 DRM_FORMAT_ARGB2101010, 2421 DRM_FORMAT_ABGR2101010, 2422 DRM_FORMAT_YUYV, 2423 DRM_FORMAT_YVYU, 2424 DRM_FORMAT_UYVY, 2425 DRM_FORMAT_VYUY, 2426 }; 2427 2428 static const u32 skl_plane_formats[] = { 2429 DRM_FORMAT_C8, 2430 DRM_FORMAT_RGB565, 2431 DRM_FORMAT_XRGB8888, 2432 DRM_FORMAT_XBGR8888, 2433 DRM_FORMAT_ARGB8888, 2434 DRM_FORMAT_ABGR8888, 2435 DRM_FORMAT_XRGB2101010, 2436 DRM_FORMAT_XBGR2101010, 2437 DRM_FORMAT_XRGB16161616F, 2438 DRM_FORMAT_XBGR16161616F, 2439 DRM_FORMAT_YUYV, 2440 DRM_FORMAT_YVYU, 2441 DRM_FORMAT_UYVY, 2442 DRM_FORMAT_VYUY, 2443 }; 2444 2445 static const u32 skl_planar_formats[] = { 2446 DRM_FORMAT_C8, 2447 DRM_FORMAT_RGB565, 2448 DRM_FORMAT_XRGB8888, 2449 DRM_FORMAT_XBGR8888, 2450 DRM_FORMAT_ARGB8888, 2451 DRM_FORMAT_ABGR8888, 2452 DRM_FORMAT_XRGB2101010, 2453 DRM_FORMAT_XBGR2101010, 2454 DRM_FORMAT_XRGB16161616F, 2455 DRM_FORMAT_XBGR16161616F, 2456 DRM_FORMAT_YUYV, 2457 DRM_FORMAT_YVYU, 2458 DRM_FORMAT_UYVY, 2459 DRM_FORMAT_VYUY, 2460 DRM_FORMAT_NV12, 2461 }; 2462 2463 static const u32 glk_planar_formats[] = { 2464 DRM_FORMAT_C8, 2465 DRM_FORMAT_RGB565, 2466 DRM_FORMAT_XRGB8888, 2467 DRM_FORMAT_XBGR8888, 2468 DRM_FORMAT_ARGB8888, 2469 DRM_FORMAT_ABGR8888, 2470 DRM_FORMAT_XRGB2101010, 2471 DRM_FORMAT_XBGR2101010, 2472 DRM_FORMAT_XRGB16161616F, 2473 DRM_FORMAT_XBGR16161616F, 2474 DRM_FORMAT_YUYV, 2475 DRM_FORMAT_YVYU, 2476 DRM_FORMAT_UYVY, 2477 DRM_FORMAT_VYUY, 2478 DRM_FORMAT_NV12, 2479 DRM_FORMAT_P010, 2480 DRM_FORMAT_P012, 2481 DRM_FORMAT_P016, 2482 }; 2483 2484 static const u32 icl_sdr_y_plane_formats[] = { 2485 DRM_FORMAT_C8, 2486 DRM_FORMAT_RGB565, 2487 DRM_FORMAT_XRGB8888, 2488 DRM_FORMAT_XBGR8888, 2489 DRM_FORMAT_ARGB8888, 2490 DRM_FORMAT_ABGR8888, 2491 DRM_FORMAT_XRGB2101010, 2492 DRM_FORMAT_XBGR2101010, 2493 DRM_FORMAT_ARGB2101010, 2494 DRM_FORMAT_ABGR2101010, 2495 DRM_FORMAT_YUYV, 2496 DRM_FORMAT_YVYU, 2497 DRM_FORMAT_UYVY, 2498 DRM_FORMAT_VYUY, 2499 DRM_FORMAT_Y210, 2500 DRM_FORMAT_Y212, 2501 DRM_FORMAT_Y216, 2502 DRM_FORMAT_XVYU2101010, 2503 DRM_FORMAT_XVYU12_16161616, 2504 DRM_FORMAT_XVYU16161616, 2505 }; 2506 2507 static const u32 icl_sdr_uv_plane_formats[] = { 2508 DRM_FORMAT_C8, 2509 DRM_FORMAT_RGB565, 2510 DRM_FORMAT_XRGB8888, 2511 DRM_FORMAT_XBGR8888, 2512 DRM_FORMAT_ARGB8888, 2513 DRM_FORMAT_ABGR8888, 2514 DRM_FORMAT_XRGB2101010, 2515 DRM_FORMAT_XBGR2101010, 2516 DRM_FORMAT_ARGB2101010, 2517 DRM_FORMAT_ABGR2101010, 2518 DRM_FORMAT_YUYV, 2519 DRM_FORMAT_YVYU, 2520 DRM_FORMAT_UYVY, 2521 DRM_FORMAT_VYUY, 2522 DRM_FORMAT_NV12, 2523 DRM_FORMAT_P010, 2524 DRM_FORMAT_P012, 2525 DRM_FORMAT_P016, 2526 DRM_FORMAT_Y210, 2527 DRM_FORMAT_Y212, 2528 DRM_FORMAT_Y216, 2529 DRM_FORMAT_XVYU2101010, 2530 DRM_FORMAT_XVYU12_16161616, 2531 DRM_FORMAT_XVYU16161616, 2532 }; 2533 2534 static const u32 icl_hdr_plane_formats[] = { 2535 DRM_FORMAT_C8, 2536 DRM_FORMAT_RGB565, 2537 DRM_FORMAT_XRGB8888, 2538 DRM_FORMAT_XBGR8888, 2539 DRM_FORMAT_ARGB8888, 2540 DRM_FORMAT_ABGR8888, 2541 DRM_FORMAT_XRGB2101010, 2542 DRM_FORMAT_XBGR2101010, 2543 DRM_FORMAT_ARGB2101010, 2544 DRM_FORMAT_ABGR2101010, 2545 DRM_FORMAT_XRGB16161616F, 2546 DRM_FORMAT_XBGR16161616F, 2547 DRM_FORMAT_ARGB16161616F, 2548 DRM_FORMAT_ABGR16161616F, 2549 DRM_FORMAT_YUYV, 2550 DRM_FORMAT_YVYU, 2551 DRM_FORMAT_UYVY, 2552 DRM_FORMAT_VYUY, 2553 DRM_FORMAT_NV12, 2554 DRM_FORMAT_P010, 2555 DRM_FORMAT_P012, 2556 DRM_FORMAT_P016, 2557 DRM_FORMAT_Y210, 2558 DRM_FORMAT_Y212, 2559 DRM_FORMAT_Y216, 2560 DRM_FORMAT_XVYU2101010, 2561 DRM_FORMAT_XVYU12_16161616, 2562 DRM_FORMAT_XVYU16161616, 2563 }; 2564 2565 static const u64 skl_plane_format_modifiers_noccs[] = { 2566 I915_FORMAT_MOD_Yf_TILED, 2567 I915_FORMAT_MOD_Y_TILED, 2568 I915_FORMAT_MOD_X_TILED, 2569 DRM_FORMAT_MOD_LINEAR, 2570 DRM_FORMAT_MOD_INVALID 2571 }; 2572 2573 static const u64 skl_plane_format_modifiers_ccs[] = { 2574 I915_FORMAT_MOD_Yf_TILED_CCS, 2575 I915_FORMAT_MOD_Y_TILED_CCS, 2576 I915_FORMAT_MOD_Yf_TILED, 2577 I915_FORMAT_MOD_Y_TILED, 2578 I915_FORMAT_MOD_X_TILED, 2579 DRM_FORMAT_MOD_LINEAR, 2580 DRM_FORMAT_MOD_INVALID 2581 }; 2582 2583 static const u64 gen12_plane_format_modifiers_mc_ccs[] = { 2584 I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS, 2585 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, 2586 I915_FORMAT_MOD_Y_TILED, 2587 I915_FORMAT_MOD_X_TILED, 2588 DRM_FORMAT_MOD_LINEAR, 2589 DRM_FORMAT_MOD_INVALID 2590 }; 2591 2592 static const u64 gen12_plane_format_modifiers_rc_ccs[] = { 2593 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, 2594 I915_FORMAT_MOD_Y_TILED, 2595 I915_FORMAT_MOD_X_TILED, 2596 DRM_FORMAT_MOD_LINEAR, 2597 DRM_FORMAT_MOD_INVALID 2598 }; 2599 2600 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane, 2601 u32 format, u64 modifier) 2602 { 2603 switch (modifier) { 2604 case DRM_FORMAT_MOD_LINEAR: 2605 case I915_FORMAT_MOD_X_TILED: 2606 break; 2607 default: 2608 return false; 2609 } 2610 2611 switch (format) { 2612 case DRM_FORMAT_XRGB8888: 2613 case DRM_FORMAT_YUYV: 2614 case DRM_FORMAT_YVYU: 2615 case DRM_FORMAT_UYVY: 2616 case DRM_FORMAT_VYUY: 2617 if (modifier == DRM_FORMAT_MOD_LINEAR || 2618 modifier == I915_FORMAT_MOD_X_TILED) 2619 return true; 2620 /* fall through */ 2621 default: 2622 return false; 2623 } 2624 } 2625 2626 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane, 2627 u32 format, u64 modifier) 2628 { 2629 switch (modifier) { 2630 case DRM_FORMAT_MOD_LINEAR: 2631 case I915_FORMAT_MOD_X_TILED: 2632 break; 2633 default: 2634 return false; 2635 } 2636 2637 switch (format) { 2638 case DRM_FORMAT_XRGB8888: 2639 case DRM_FORMAT_XBGR8888: 2640 case DRM_FORMAT_XRGB2101010: 2641 case DRM_FORMAT_XBGR2101010: 2642 case DRM_FORMAT_XRGB16161616F: 2643 case DRM_FORMAT_XBGR16161616F: 2644 case DRM_FORMAT_YUYV: 2645 case DRM_FORMAT_YVYU: 2646 case DRM_FORMAT_UYVY: 2647 case DRM_FORMAT_VYUY: 2648 if (modifier == DRM_FORMAT_MOD_LINEAR || 2649 modifier == I915_FORMAT_MOD_X_TILED) 2650 return true; 2651 /* fall through */ 2652 default: 2653 return false; 2654 } 2655 } 2656 2657 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane, 2658 u32 format, u64 modifier) 2659 { 2660 switch (modifier) { 2661 case DRM_FORMAT_MOD_LINEAR: 2662 case I915_FORMAT_MOD_X_TILED: 2663 break; 2664 default: 2665 return false; 2666 } 2667 2668 switch (format) { 2669 case DRM_FORMAT_C8: 2670 case DRM_FORMAT_RGB565: 2671 case DRM_FORMAT_ABGR8888: 2672 case DRM_FORMAT_ARGB8888: 2673 case DRM_FORMAT_XBGR8888: 2674 case DRM_FORMAT_XRGB8888: 2675 case DRM_FORMAT_XBGR2101010: 2676 case DRM_FORMAT_ABGR2101010: 2677 case DRM_FORMAT_XRGB2101010: 2678 case DRM_FORMAT_ARGB2101010: 2679 case DRM_FORMAT_YUYV: 2680 case DRM_FORMAT_YVYU: 2681 case DRM_FORMAT_UYVY: 2682 case DRM_FORMAT_VYUY: 2683 if (modifier == DRM_FORMAT_MOD_LINEAR || 2684 modifier == I915_FORMAT_MOD_X_TILED) 2685 return true; 2686 /* fall through */ 2687 default: 2688 return false; 2689 } 2690 } 2691 2692 static bool skl_plane_format_mod_supported(struct drm_plane *_plane, 2693 u32 format, u64 modifier) 2694 { 2695 struct intel_plane *plane = to_intel_plane(_plane); 2696 2697 switch (modifier) { 2698 case DRM_FORMAT_MOD_LINEAR: 2699 case I915_FORMAT_MOD_X_TILED: 2700 case I915_FORMAT_MOD_Y_TILED: 2701 case I915_FORMAT_MOD_Yf_TILED: 2702 break; 2703 case I915_FORMAT_MOD_Y_TILED_CCS: 2704 case I915_FORMAT_MOD_Yf_TILED_CCS: 2705 if (!plane->has_ccs) 2706 return false; 2707 break; 2708 default: 2709 return false; 2710 } 2711 2712 switch (format) { 2713 case DRM_FORMAT_XRGB8888: 2714 case DRM_FORMAT_XBGR8888: 2715 case DRM_FORMAT_ARGB8888: 2716 case DRM_FORMAT_ABGR8888: 2717 if (is_ccs_modifier(modifier)) 2718 return true; 2719 /* fall through */ 2720 case DRM_FORMAT_RGB565: 2721 case DRM_FORMAT_XRGB2101010: 2722 case DRM_FORMAT_XBGR2101010: 2723 case DRM_FORMAT_ARGB2101010: 2724 case DRM_FORMAT_ABGR2101010: 2725 case DRM_FORMAT_YUYV: 2726 case DRM_FORMAT_YVYU: 2727 case DRM_FORMAT_UYVY: 2728 case DRM_FORMAT_VYUY: 2729 case DRM_FORMAT_NV12: 2730 case DRM_FORMAT_P010: 2731 case DRM_FORMAT_P012: 2732 case DRM_FORMAT_P016: 2733 case DRM_FORMAT_XVYU2101010: 2734 if (modifier == I915_FORMAT_MOD_Yf_TILED) 2735 return true; 2736 /* fall through */ 2737 case DRM_FORMAT_C8: 2738 case DRM_FORMAT_XBGR16161616F: 2739 case DRM_FORMAT_ABGR16161616F: 2740 case DRM_FORMAT_XRGB16161616F: 2741 case DRM_FORMAT_ARGB16161616F: 2742 case DRM_FORMAT_Y210: 2743 case DRM_FORMAT_Y212: 2744 case DRM_FORMAT_Y216: 2745 case DRM_FORMAT_XVYU12_16161616: 2746 case DRM_FORMAT_XVYU16161616: 2747 if (modifier == DRM_FORMAT_MOD_LINEAR || 2748 modifier == I915_FORMAT_MOD_X_TILED || 2749 modifier == I915_FORMAT_MOD_Y_TILED) 2750 return true; 2751 /* fall through */ 2752 default: 2753 return false; 2754 } 2755 } 2756 2757 static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id) 2758 { 2759 return plane_id < PLANE_SPRITE4; 2760 } 2761 2762 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, 2763 u32 format, u64 modifier) 2764 { 2765 struct intel_plane *plane = to_intel_plane(_plane); 2766 2767 switch (modifier) { 2768 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: 2769 if (!gen12_plane_supports_mc_ccs(plane->id)) 2770 return false; 2771 /* fall through */ 2772 case DRM_FORMAT_MOD_LINEAR: 2773 case I915_FORMAT_MOD_X_TILED: 2774 case I915_FORMAT_MOD_Y_TILED: 2775 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: 2776 break; 2777 default: 2778 return false; 2779 } 2780 2781 switch (format) { 2782 case DRM_FORMAT_XRGB8888: 2783 case DRM_FORMAT_XBGR8888: 2784 case DRM_FORMAT_ARGB8888: 2785 case DRM_FORMAT_ABGR8888: 2786 if (is_ccs_modifier(modifier)) 2787 return true; 2788 /* fall through */ 2789 case DRM_FORMAT_YUYV: 2790 case DRM_FORMAT_YVYU: 2791 case DRM_FORMAT_UYVY: 2792 case DRM_FORMAT_VYUY: 2793 case DRM_FORMAT_NV12: 2794 case DRM_FORMAT_P010: 2795 case DRM_FORMAT_P012: 2796 case DRM_FORMAT_P016: 2797 if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) 2798 return true; 2799 /* fall through */ 2800 case DRM_FORMAT_RGB565: 2801 case DRM_FORMAT_XRGB2101010: 2802 case DRM_FORMAT_XBGR2101010: 2803 case DRM_FORMAT_ARGB2101010: 2804 case DRM_FORMAT_ABGR2101010: 2805 case DRM_FORMAT_XVYU2101010: 2806 case DRM_FORMAT_C8: 2807 case DRM_FORMAT_XBGR16161616F: 2808 case DRM_FORMAT_ABGR16161616F: 2809 case DRM_FORMAT_XRGB16161616F: 2810 case DRM_FORMAT_ARGB16161616F: 2811 case DRM_FORMAT_Y210: 2812 case DRM_FORMAT_Y212: 2813 case DRM_FORMAT_Y216: 2814 case DRM_FORMAT_XVYU12_16161616: 2815 case DRM_FORMAT_XVYU16161616: 2816 if (modifier == DRM_FORMAT_MOD_LINEAR || 2817 modifier == I915_FORMAT_MOD_X_TILED || 2818 modifier == I915_FORMAT_MOD_Y_TILED) 2819 return true; 2820 /* fall through */ 2821 default: 2822 return false; 2823 } 2824 } 2825 2826 static const struct drm_plane_funcs g4x_sprite_funcs = { 2827 .update_plane = drm_atomic_helper_update_plane, 2828 .disable_plane = drm_atomic_helper_disable_plane, 2829 .destroy = intel_plane_destroy, 2830 .atomic_duplicate_state = intel_plane_duplicate_state, 2831 .atomic_destroy_state = intel_plane_destroy_state, 2832 .format_mod_supported = g4x_sprite_format_mod_supported, 2833 }; 2834 2835 static const struct drm_plane_funcs snb_sprite_funcs = { 2836 .update_plane = drm_atomic_helper_update_plane, 2837 .disable_plane = drm_atomic_helper_disable_plane, 2838 .destroy = intel_plane_destroy, 2839 .atomic_duplicate_state = intel_plane_duplicate_state, 2840 .atomic_destroy_state = intel_plane_destroy_state, 2841 .format_mod_supported = snb_sprite_format_mod_supported, 2842 }; 2843 2844 static const struct drm_plane_funcs vlv_sprite_funcs = { 2845 .update_plane = drm_atomic_helper_update_plane, 2846 .disable_plane = drm_atomic_helper_disable_plane, 2847 .destroy = intel_plane_destroy, 2848 .atomic_duplicate_state = intel_plane_duplicate_state, 2849 .atomic_destroy_state = intel_plane_destroy_state, 2850 .format_mod_supported = vlv_sprite_format_mod_supported, 2851 }; 2852 2853 static const struct drm_plane_funcs skl_plane_funcs = { 2854 .update_plane = drm_atomic_helper_update_plane, 2855 .disable_plane = drm_atomic_helper_disable_plane, 2856 .destroy = intel_plane_destroy, 2857 .atomic_duplicate_state = intel_plane_duplicate_state, 2858 .atomic_destroy_state = intel_plane_destroy_state, 2859 .format_mod_supported = skl_plane_format_mod_supported, 2860 }; 2861 2862 static const struct drm_plane_funcs gen12_plane_funcs = { 2863 .update_plane = drm_atomic_helper_update_plane, 2864 .disable_plane = drm_atomic_helper_disable_plane, 2865 .destroy = intel_plane_destroy, 2866 .atomic_duplicate_state = intel_plane_duplicate_state, 2867 .atomic_destroy_state = intel_plane_destroy_state, 2868 .format_mod_supported = gen12_plane_format_mod_supported, 2869 }; 2870 2871 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, 2872 enum pipe pipe, enum plane_id plane_id) 2873 { 2874 if (!HAS_FBC(dev_priv)) 2875 return false; 2876 2877 return pipe == PIPE_A && plane_id == PLANE_PRIMARY; 2878 } 2879 2880 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, 2881 enum pipe pipe, enum plane_id plane_id) 2882 { 2883 /* Display WA #0870: skl, bxt */ 2884 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) 2885 return false; 2886 2887 if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C) 2888 return false; 2889 2890 if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) 2891 return false; 2892 2893 return true; 2894 } 2895 2896 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, 2897 enum pipe pipe, enum plane_id plane_id, 2898 int *num_formats) 2899 { 2900 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2901 *num_formats = ARRAY_SIZE(skl_planar_formats); 2902 return skl_planar_formats; 2903 } else { 2904 *num_formats = ARRAY_SIZE(skl_plane_formats); 2905 return skl_plane_formats; 2906 } 2907 } 2908 2909 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, 2910 enum pipe pipe, enum plane_id plane_id, 2911 int *num_formats) 2912 { 2913 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2914 *num_formats = ARRAY_SIZE(glk_planar_formats); 2915 return glk_planar_formats; 2916 } else { 2917 *num_formats = ARRAY_SIZE(skl_plane_formats); 2918 return skl_plane_formats; 2919 } 2920 } 2921 2922 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv, 2923 enum pipe pipe, enum plane_id plane_id, 2924 int *num_formats) 2925 { 2926 if (icl_is_hdr_plane(dev_priv, plane_id)) { 2927 *num_formats = ARRAY_SIZE(icl_hdr_plane_formats); 2928 return icl_hdr_plane_formats; 2929 } else if (icl_is_nv12_y_plane(plane_id)) { 2930 *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats); 2931 return icl_sdr_y_plane_formats; 2932 } else { 2933 *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats); 2934 return icl_sdr_uv_plane_formats; 2935 } 2936 } 2937 2938 static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id) 2939 { 2940 if (gen12_plane_supports_mc_ccs(plane_id)) 2941 return gen12_plane_format_modifiers_mc_ccs; 2942 else 2943 return gen12_plane_format_modifiers_rc_ccs; 2944 } 2945 2946 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 2947 enum pipe pipe, enum plane_id plane_id) 2948 { 2949 if (plane_id == PLANE_CURSOR) 2950 return false; 2951 2952 if (INTEL_GEN(dev_priv) >= 10) 2953 return true; 2954 2955 if (IS_GEMINILAKE(dev_priv)) 2956 return pipe != PIPE_C; 2957 2958 return pipe != PIPE_C && 2959 (plane_id == PLANE_PRIMARY || 2960 plane_id == PLANE_SPRITE0); 2961 } 2962 2963 struct intel_plane * 2964 skl_universal_plane_create(struct drm_i915_private *dev_priv, 2965 enum pipe pipe, enum plane_id plane_id) 2966 { 2967 const struct drm_plane_funcs *plane_funcs; 2968 struct intel_plane *plane; 2969 enum drm_plane_type plane_type; 2970 unsigned int supported_rotations; 2971 unsigned int possible_crtcs; 2972 const u64 *modifiers; 2973 const u32 *formats; 2974 int num_formats; 2975 int ret; 2976 2977 plane = intel_plane_alloc(); 2978 if (IS_ERR(plane)) 2979 return plane; 2980 2981 plane->pipe = pipe; 2982 plane->id = plane_id; 2983 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id); 2984 2985 plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id); 2986 if (plane->has_fbc) { 2987 struct intel_fbc *fbc = &dev_priv->fbc; 2988 2989 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; 2990 } 2991 2992 plane->max_stride = skl_plane_max_stride; 2993 plane->update_plane = skl_update_plane; 2994 plane->disable_plane = skl_disable_plane; 2995 plane->get_hw_state = skl_plane_get_hw_state; 2996 plane->check_plane = skl_plane_check; 2997 plane->min_cdclk = skl_plane_min_cdclk; 2998 2999 if (INTEL_GEN(dev_priv) >= 11) 3000 formats = icl_get_plane_formats(dev_priv, pipe, 3001 plane_id, &num_formats); 3002 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 3003 formats = glk_get_plane_formats(dev_priv, pipe, 3004 plane_id, &num_formats); 3005 else 3006 formats = skl_get_plane_formats(dev_priv, pipe, 3007 plane_id, &num_formats); 3008 3009 plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id); 3010 if (INTEL_GEN(dev_priv) >= 12) { 3011 modifiers = gen12_get_plane_modifiers(plane_id); 3012 plane_funcs = &gen12_plane_funcs; 3013 } else { 3014 if (plane->has_ccs) 3015 modifiers = skl_plane_format_modifiers_ccs; 3016 else 3017 modifiers = skl_plane_format_modifiers_noccs; 3018 plane_funcs = &skl_plane_funcs; 3019 } 3020 3021 if (plane_id == PLANE_PRIMARY) 3022 plane_type = DRM_PLANE_TYPE_PRIMARY; 3023 else 3024 plane_type = DRM_PLANE_TYPE_OVERLAY; 3025 3026 possible_crtcs = BIT(pipe); 3027 3028 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 3029 possible_crtcs, plane_funcs, 3030 formats, num_formats, modifiers, 3031 plane_type, 3032 "plane %d%c", plane_id + 1, 3033 pipe_name(pipe)); 3034 if (ret) 3035 goto fail; 3036 3037 supported_rotations = 3038 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | 3039 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; 3040 3041 if (INTEL_GEN(dev_priv) >= 10) 3042 supported_rotations |= DRM_MODE_REFLECT_X; 3043 3044 drm_plane_create_rotation_property(&plane->base, 3045 DRM_MODE_ROTATE_0, 3046 supported_rotations); 3047 3048 drm_plane_create_color_properties(&plane->base, 3049 BIT(DRM_COLOR_YCBCR_BT601) | 3050 BIT(DRM_COLOR_YCBCR_BT709), 3051 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 3052 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 3053 DRM_COLOR_YCBCR_BT709, 3054 DRM_COLOR_YCBCR_LIMITED_RANGE); 3055 3056 drm_plane_create_alpha_property(&plane->base); 3057 drm_plane_create_blend_mode_property(&plane->base, 3058 BIT(DRM_MODE_BLEND_PIXEL_NONE) | 3059 BIT(DRM_MODE_BLEND_PREMULTI) | 3060 BIT(DRM_MODE_BLEND_COVERAGE)); 3061 3062 drm_plane_create_zpos_immutable_property(&plane->base, plane_id); 3063 3064 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 3065 3066 return plane; 3067 3068 fail: 3069 intel_plane_free(plane); 3070 3071 return ERR_PTR(ret); 3072 } 3073 3074 struct intel_plane * 3075 intel_sprite_plane_create(struct drm_i915_private *dev_priv, 3076 enum pipe pipe, int sprite) 3077 { 3078 struct intel_plane *plane; 3079 const struct drm_plane_funcs *plane_funcs; 3080 unsigned long possible_crtcs; 3081 unsigned int supported_rotations; 3082 const u64 *modifiers; 3083 const u32 *formats; 3084 int num_formats; 3085 int ret, zpos; 3086 3087 if (INTEL_GEN(dev_priv) >= 9) 3088 return skl_universal_plane_create(dev_priv, pipe, 3089 PLANE_SPRITE0 + sprite); 3090 3091 plane = intel_plane_alloc(); 3092 if (IS_ERR(plane)) 3093 return plane; 3094 3095 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 3096 plane->max_stride = i9xx_plane_max_stride; 3097 plane->update_plane = vlv_update_plane; 3098 plane->disable_plane = vlv_disable_plane; 3099 plane->get_hw_state = vlv_plane_get_hw_state; 3100 plane->check_plane = vlv_sprite_check; 3101 plane->min_cdclk = vlv_plane_min_cdclk; 3102 3103 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 3104 formats = chv_pipe_b_sprite_formats; 3105 num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats); 3106 } else { 3107 formats = vlv_plane_formats; 3108 num_formats = ARRAY_SIZE(vlv_plane_formats); 3109 } 3110 modifiers = i9xx_plane_format_modifiers; 3111 3112 plane_funcs = &vlv_sprite_funcs; 3113 } else if (INTEL_GEN(dev_priv) >= 7) { 3114 plane->max_stride = g4x_sprite_max_stride; 3115 plane->update_plane = ivb_update_plane; 3116 plane->disable_plane = ivb_disable_plane; 3117 plane->get_hw_state = ivb_plane_get_hw_state; 3118 plane->check_plane = g4x_sprite_check; 3119 3120 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) 3121 plane->min_cdclk = hsw_plane_min_cdclk; 3122 else 3123 plane->min_cdclk = ivb_sprite_min_cdclk; 3124 3125 formats = snb_plane_formats; 3126 num_formats = ARRAY_SIZE(snb_plane_formats); 3127 modifiers = i9xx_plane_format_modifiers; 3128 3129 plane_funcs = &snb_sprite_funcs; 3130 } else { 3131 plane->max_stride = g4x_sprite_max_stride; 3132 plane->update_plane = g4x_update_plane; 3133 plane->disable_plane = g4x_disable_plane; 3134 plane->get_hw_state = g4x_plane_get_hw_state; 3135 plane->check_plane = g4x_sprite_check; 3136 plane->min_cdclk = g4x_sprite_min_cdclk; 3137 3138 modifiers = i9xx_plane_format_modifiers; 3139 if (IS_GEN(dev_priv, 6)) { 3140 formats = snb_plane_formats; 3141 num_formats = ARRAY_SIZE(snb_plane_formats); 3142 3143 plane_funcs = &snb_sprite_funcs; 3144 } else { 3145 formats = g4x_plane_formats; 3146 num_formats = ARRAY_SIZE(g4x_plane_formats); 3147 3148 plane_funcs = &g4x_sprite_funcs; 3149 } 3150 } 3151 3152 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 3153 supported_rotations = 3154 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 3155 DRM_MODE_REFLECT_X; 3156 } else { 3157 supported_rotations = 3158 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 3159 } 3160 3161 plane->pipe = pipe; 3162 plane->id = PLANE_SPRITE0 + sprite; 3163 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 3164 3165 possible_crtcs = BIT(pipe); 3166 3167 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 3168 possible_crtcs, plane_funcs, 3169 formats, num_formats, modifiers, 3170 DRM_PLANE_TYPE_OVERLAY, 3171 "sprite %c", sprite_name(pipe, sprite)); 3172 if (ret) 3173 goto fail; 3174 3175 drm_plane_create_rotation_property(&plane->base, 3176 DRM_MODE_ROTATE_0, 3177 supported_rotations); 3178 3179 drm_plane_create_color_properties(&plane->base, 3180 BIT(DRM_COLOR_YCBCR_BT601) | 3181 BIT(DRM_COLOR_YCBCR_BT709), 3182 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 3183 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 3184 DRM_COLOR_YCBCR_BT709, 3185 DRM_COLOR_YCBCR_LIMITED_RANGE); 3186 3187 zpos = sprite + 1; 3188 drm_plane_create_zpos_immutable_property(&plane->base, zpos); 3189 3190 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 3191 3192 return plane; 3193 3194 fail: 3195 intel_plane_free(plane); 3196 3197 return ERR_PTR(ret); 3198 } 3199