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