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