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