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 cpp = fb->format->cpp[0]; 1532 unsigned int width_bytes; 1533 int min_width, min_height; 1534 1535 crtc_w = drm_rect_width(dst); 1536 crtc_h = drm_rect_height(dst); 1537 1538 src_x = src->x1 >> 16; 1539 src_w = drm_rect_width(src) >> 16; 1540 src_h = drm_rect_height(src) >> 16; 1541 1542 if (src_w == crtc_w && src_h == crtc_h) 1543 return 0; 1544 1545 min_width = 3; 1546 1547 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 1548 if (src_h & 1) { 1549 DRM_DEBUG_KMS("Source height must be even with interlaced modes\n"); 1550 return -EINVAL; 1551 } 1552 min_height = 6; 1553 } else { 1554 min_height = 3; 1555 } 1556 1557 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1558 1559 if (src_w < min_width || src_h < min_height || 1560 src_w > 2048 || src_h > 2048) { 1561 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n", 1562 src_w, src_h, min_width, min_height, 2048, 2048); 1563 return -EINVAL; 1564 } 1565 1566 if (width_bytes > 4096) { 1567 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n", 1568 width_bytes, 4096); 1569 return -EINVAL; 1570 } 1571 1572 if (width_bytes > 4096 || fb->pitches[0] > 4096) { 1573 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n", 1574 fb->pitches[0], 4096); 1575 return -EINVAL; 1576 } 1577 1578 return 0; 1579 } 1580 1581 static int 1582 g4x_sprite_check(struct intel_crtc_state *crtc_state, 1583 struct intel_plane_state *plane_state) 1584 { 1585 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1586 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1587 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1588 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1589 int ret; 1590 1591 if (intel_fb_scalable(plane_state->base.fb)) { 1592 if (INTEL_GEN(dev_priv) < 7) { 1593 min_scale = 1; 1594 max_scale = 16 << 16; 1595 } else if (IS_IVYBRIDGE(dev_priv)) { 1596 min_scale = 1; 1597 max_scale = 2 << 16; 1598 } 1599 } 1600 1601 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1602 &crtc_state->base, 1603 min_scale, max_scale, 1604 true, true); 1605 if (ret) 1606 return ret; 1607 1608 ret = i9xx_check_plane_surface(plane_state); 1609 if (ret) 1610 return ret; 1611 1612 if (!plane_state->base.visible) 1613 return 0; 1614 1615 ret = intel_plane_check_src_coordinates(plane_state); 1616 if (ret) 1617 return ret; 1618 1619 ret = g4x_sprite_check_scaling(crtc_state, plane_state); 1620 if (ret) 1621 return ret; 1622 1623 if (INTEL_GEN(dev_priv) >= 7) 1624 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state); 1625 else 1626 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state); 1627 1628 return 0; 1629 } 1630 1631 int chv_plane_check_rotation(const struct intel_plane_state *plane_state) 1632 { 1633 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1634 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1635 unsigned int rotation = plane_state->base.rotation; 1636 1637 /* CHV ignores the mirror bit when the rotate bit is set :( */ 1638 if (IS_CHERRYVIEW(dev_priv) && 1639 rotation & DRM_MODE_ROTATE_180 && 1640 rotation & DRM_MODE_REFLECT_X) { 1641 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n"); 1642 return -EINVAL; 1643 } 1644 1645 return 0; 1646 } 1647 1648 static int 1649 vlv_sprite_check(struct intel_crtc_state *crtc_state, 1650 struct intel_plane_state *plane_state) 1651 { 1652 int ret; 1653 1654 ret = chv_plane_check_rotation(plane_state); 1655 if (ret) 1656 return ret; 1657 1658 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1659 &crtc_state->base, 1660 DRM_PLANE_HELPER_NO_SCALING, 1661 DRM_PLANE_HELPER_NO_SCALING, 1662 true, true); 1663 if (ret) 1664 return ret; 1665 1666 ret = i9xx_check_plane_surface(plane_state); 1667 if (ret) 1668 return ret; 1669 1670 if (!plane_state->base.visible) 1671 return 0; 1672 1673 ret = intel_plane_check_src_coordinates(plane_state); 1674 if (ret) 1675 return ret; 1676 1677 plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state); 1678 1679 return 0; 1680 } 1681 1682 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, 1683 const struct intel_plane_state *plane_state) 1684 { 1685 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1686 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1687 const struct drm_framebuffer *fb = plane_state->base.fb; 1688 unsigned int rotation = plane_state->base.rotation; 1689 struct drm_format_name_buf format_name; 1690 1691 if (!fb) 1692 return 0; 1693 1694 if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) && 1695 is_ccs_modifier(fb->modifier)) { 1696 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n", 1697 rotation); 1698 return -EINVAL; 1699 } 1700 1701 if (rotation & DRM_MODE_REFLECT_X && 1702 fb->modifier == DRM_FORMAT_MOD_LINEAR) { 1703 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n"); 1704 return -EINVAL; 1705 } 1706 1707 if (drm_rotation_90_or_270(rotation)) { 1708 if (fb->modifier != I915_FORMAT_MOD_Y_TILED && 1709 fb->modifier != I915_FORMAT_MOD_Yf_TILED) { 1710 DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); 1711 return -EINVAL; 1712 } 1713 1714 /* 1715 * 90/270 is not allowed with RGB64 16:16:16:16 and 1716 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards. 1717 */ 1718 switch (fb->format->format) { 1719 case DRM_FORMAT_RGB565: 1720 if (INTEL_GEN(dev_priv) >= 11) 1721 break; 1722 /* fall through */ 1723 case DRM_FORMAT_C8: 1724 case DRM_FORMAT_XRGB16161616F: 1725 case DRM_FORMAT_XBGR16161616F: 1726 case DRM_FORMAT_ARGB16161616F: 1727 case DRM_FORMAT_ABGR16161616F: 1728 case DRM_FORMAT_Y210: 1729 case DRM_FORMAT_Y212: 1730 case DRM_FORMAT_Y216: 1731 case DRM_FORMAT_XVYU12_16161616: 1732 case DRM_FORMAT_XVYU16161616: 1733 DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", 1734 drm_get_format_name(fb->format->format, 1735 &format_name)); 1736 return -EINVAL; 1737 default: 1738 break; 1739 } 1740 } 1741 1742 /* Y-tiling is not supported in IF-ID Interlace mode */ 1743 if (crtc_state->base.enable && 1744 crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE && 1745 (fb->modifier == I915_FORMAT_MOD_Y_TILED || 1746 fb->modifier == I915_FORMAT_MOD_Yf_TILED || 1747 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 1748 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) { 1749 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n"); 1750 return -EINVAL; 1751 } 1752 1753 return 0; 1754 } 1755 1756 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state, 1757 const struct intel_plane_state *plane_state) 1758 { 1759 struct drm_i915_private *dev_priv = 1760 to_i915(plane_state->base.plane->dev); 1761 int crtc_x = plane_state->base.dst.x1; 1762 int crtc_w = drm_rect_width(&plane_state->base.dst); 1763 int pipe_src_w = crtc_state->pipe_src_w; 1764 1765 /* 1766 * Display WA #1175: cnl,glk 1767 * Planes other than the cursor may cause FIFO underflow and display 1768 * corruption if starting less than 4 pixels from the right edge of 1769 * the screen. 1770 * Besides the above WA fix the similar problem, where planes other 1771 * than the cursor ending less than 4 pixels from the left edge of the 1772 * screen may cause FIFO underflow and display corruption. 1773 */ 1774 if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) && 1775 (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { 1776 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n", 1777 crtc_x + crtc_w < 4 ? "end" : "start", 1778 crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x, 1779 4, pipe_src_w - 4); 1780 return -ERANGE; 1781 } 1782 1783 return 0; 1784 } 1785 1786 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) 1787 { 1788 const struct drm_framebuffer *fb = plane_state->base.fb; 1789 unsigned int rotation = plane_state->base.rotation; 1790 int src_w = drm_rect_width(&plane_state->base.src) >> 16; 1791 1792 /* Display WA #1106 */ 1793 if (is_planar_yuv_format(fb->format->format) && src_w & 3 && 1794 (rotation == DRM_MODE_ROTATE_270 || 1795 rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { 1796 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); 1797 return -EINVAL; 1798 } 1799 1800 return 0; 1801 } 1802 1803 static int skl_plane_check(struct intel_crtc_state *crtc_state, 1804 struct intel_plane_state *plane_state) 1805 { 1806 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1807 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1808 const struct drm_framebuffer *fb = plane_state->base.fb; 1809 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1810 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1811 int ret; 1812 1813 ret = skl_plane_check_fb(crtc_state, plane_state); 1814 if (ret) 1815 return ret; 1816 1817 /* use scaler when colorkey is not required */ 1818 if (!plane_state->ckey.flags && intel_fb_scalable(fb)) { 1819 min_scale = 1; 1820 max_scale = skl_max_scale(crtc_state, fb->format->format); 1821 } 1822 1823 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1824 &crtc_state->base, 1825 min_scale, max_scale, 1826 true, true); 1827 if (ret) 1828 return ret; 1829 1830 ret = skl_check_plane_surface(plane_state); 1831 if (ret) 1832 return ret; 1833 1834 if (!plane_state->base.visible) 1835 return 0; 1836 1837 ret = skl_plane_check_dst_coordinates(crtc_state, plane_state); 1838 if (ret) 1839 return ret; 1840 1841 ret = intel_plane_check_src_coordinates(plane_state); 1842 if (ret) 1843 return ret; 1844 1845 ret = skl_plane_check_nv12_rotation(plane_state); 1846 if (ret) 1847 return ret; 1848 1849 /* HW only has 8 bits pixel precision, disable plane if invisible */ 1850 if (!(plane_state->base.alpha >> 8)) 1851 plane_state->base.visible = false; 1852 1853 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); 1854 1855 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 1856 plane_state->color_ctl = glk_plane_color_ctl(crtc_state, 1857 plane_state); 1858 1859 return 0; 1860 } 1861 1862 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv) 1863 { 1864 return INTEL_GEN(dev_priv) >= 9; 1865 } 1866 1867 static void intel_plane_set_ckey(struct intel_plane_state *plane_state, 1868 const struct drm_intel_sprite_colorkey *set) 1869 { 1870 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1871 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1872 struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1873 1874 *key = *set; 1875 1876 /* 1877 * We want src key enabled on the 1878 * sprite and not on the primary. 1879 */ 1880 if (plane->id == PLANE_PRIMARY && 1881 set->flags & I915_SET_COLORKEY_SOURCE) 1882 key->flags = 0; 1883 1884 /* 1885 * On SKL+ we want dst key enabled on 1886 * the primary and not on the sprite. 1887 */ 1888 if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY && 1889 set->flags & I915_SET_COLORKEY_DESTINATION) 1890 key->flags = 0; 1891 } 1892 1893 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, 1894 struct drm_file *file_priv) 1895 { 1896 struct drm_i915_private *dev_priv = to_i915(dev); 1897 struct drm_intel_sprite_colorkey *set = data; 1898 struct drm_plane *plane; 1899 struct drm_plane_state *plane_state; 1900 struct drm_atomic_state *state; 1901 struct drm_modeset_acquire_ctx ctx; 1902 int ret = 0; 1903 1904 /* ignore the pointless "none" flag */ 1905 set->flags &= ~I915_SET_COLORKEY_NONE; 1906 1907 if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1908 return -EINVAL; 1909 1910 /* Make sure we don't try to enable both src & dest simultaneously */ 1911 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1912 return -EINVAL; 1913 1914 if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 1915 set->flags & I915_SET_COLORKEY_DESTINATION) 1916 return -EINVAL; 1917 1918 plane = drm_plane_find(dev, file_priv, set->plane_id); 1919 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) 1920 return -ENOENT; 1921 1922 /* 1923 * SKL+ only plane 2 can do destination keying against plane 1. 1924 * Also multiple planes can't do destination keying on the same 1925 * pipe simultaneously. 1926 */ 1927 if (INTEL_GEN(dev_priv) >= 9 && 1928 to_intel_plane(plane)->id >= PLANE_SPRITE1 && 1929 set->flags & I915_SET_COLORKEY_DESTINATION) 1930 return -EINVAL; 1931 1932 drm_modeset_acquire_init(&ctx, 0); 1933 1934 state = drm_atomic_state_alloc(plane->dev); 1935 if (!state) { 1936 ret = -ENOMEM; 1937 goto out; 1938 } 1939 state->acquire_ctx = &ctx; 1940 1941 while (1) { 1942 plane_state = drm_atomic_get_plane_state(state, plane); 1943 ret = PTR_ERR_OR_ZERO(plane_state); 1944 if (!ret) 1945 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 1946 1947 /* 1948 * On some platforms we have to configure 1949 * the dst colorkey on the primary plane. 1950 */ 1951 if (!ret && has_dst_key_in_primary_plane(dev_priv)) { 1952 struct intel_crtc *crtc = 1953 intel_get_crtc_for_pipe(dev_priv, 1954 to_intel_plane(plane)->pipe); 1955 1956 plane_state = drm_atomic_get_plane_state(state, 1957 crtc->base.primary); 1958 ret = PTR_ERR_OR_ZERO(plane_state); 1959 if (!ret) 1960 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 1961 } 1962 1963 if (!ret) 1964 ret = drm_atomic_commit(state); 1965 1966 if (ret != -EDEADLK) 1967 break; 1968 1969 drm_atomic_state_clear(state); 1970 drm_modeset_backoff(&ctx); 1971 } 1972 1973 drm_atomic_state_put(state); 1974 out: 1975 drm_modeset_drop_locks(&ctx); 1976 drm_modeset_acquire_fini(&ctx); 1977 return ret; 1978 } 1979 1980 static const u32 g4x_plane_formats[] = { 1981 DRM_FORMAT_XRGB8888, 1982 DRM_FORMAT_YUYV, 1983 DRM_FORMAT_YVYU, 1984 DRM_FORMAT_UYVY, 1985 DRM_FORMAT_VYUY, 1986 }; 1987 1988 static const u64 i9xx_plane_format_modifiers[] = { 1989 I915_FORMAT_MOD_X_TILED, 1990 DRM_FORMAT_MOD_LINEAR, 1991 DRM_FORMAT_MOD_INVALID 1992 }; 1993 1994 static const u32 snb_plane_formats[] = { 1995 DRM_FORMAT_XBGR8888, 1996 DRM_FORMAT_XRGB8888, 1997 DRM_FORMAT_YUYV, 1998 DRM_FORMAT_YVYU, 1999 DRM_FORMAT_UYVY, 2000 DRM_FORMAT_VYUY, 2001 }; 2002 2003 static const u32 vlv_plane_formats[] = { 2004 DRM_FORMAT_RGB565, 2005 DRM_FORMAT_ABGR8888, 2006 DRM_FORMAT_ARGB8888, 2007 DRM_FORMAT_XBGR8888, 2008 DRM_FORMAT_XRGB8888, 2009 DRM_FORMAT_XBGR2101010, 2010 DRM_FORMAT_ABGR2101010, 2011 DRM_FORMAT_YUYV, 2012 DRM_FORMAT_YVYU, 2013 DRM_FORMAT_UYVY, 2014 DRM_FORMAT_VYUY, 2015 }; 2016 2017 static const u32 skl_plane_formats[] = { 2018 DRM_FORMAT_C8, 2019 DRM_FORMAT_RGB565, 2020 DRM_FORMAT_XRGB8888, 2021 DRM_FORMAT_XBGR8888, 2022 DRM_FORMAT_ARGB8888, 2023 DRM_FORMAT_ABGR8888, 2024 DRM_FORMAT_XRGB2101010, 2025 DRM_FORMAT_XBGR2101010, 2026 DRM_FORMAT_YUYV, 2027 DRM_FORMAT_YVYU, 2028 DRM_FORMAT_UYVY, 2029 DRM_FORMAT_VYUY, 2030 }; 2031 2032 static const u32 skl_planar_formats[] = { 2033 DRM_FORMAT_C8, 2034 DRM_FORMAT_RGB565, 2035 DRM_FORMAT_XRGB8888, 2036 DRM_FORMAT_XBGR8888, 2037 DRM_FORMAT_ARGB8888, 2038 DRM_FORMAT_ABGR8888, 2039 DRM_FORMAT_XRGB2101010, 2040 DRM_FORMAT_XBGR2101010, 2041 DRM_FORMAT_YUYV, 2042 DRM_FORMAT_YVYU, 2043 DRM_FORMAT_UYVY, 2044 DRM_FORMAT_VYUY, 2045 DRM_FORMAT_NV12, 2046 }; 2047 2048 static const u32 glk_planar_formats[] = { 2049 DRM_FORMAT_C8, 2050 DRM_FORMAT_RGB565, 2051 DRM_FORMAT_XRGB8888, 2052 DRM_FORMAT_XBGR8888, 2053 DRM_FORMAT_ARGB8888, 2054 DRM_FORMAT_ABGR8888, 2055 DRM_FORMAT_XRGB2101010, 2056 DRM_FORMAT_XBGR2101010, 2057 DRM_FORMAT_YUYV, 2058 DRM_FORMAT_YVYU, 2059 DRM_FORMAT_UYVY, 2060 DRM_FORMAT_VYUY, 2061 DRM_FORMAT_NV12, 2062 DRM_FORMAT_P010, 2063 DRM_FORMAT_P012, 2064 DRM_FORMAT_P016, 2065 }; 2066 2067 static const u32 icl_sdr_y_plane_formats[] = { 2068 DRM_FORMAT_C8, 2069 DRM_FORMAT_RGB565, 2070 DRM_FORMAT_XRGB8888, 2071 DRM_FORMAT_XBGR8888, 2072 DRM_FORMAT_ARGB8888, 2073 DRM_FORMAT_ABGR8888, 2074 DRM_FORMAT_XRGB2101010, 2075 DRM_FORMAT_XBGR2101010, 2076 DRM_FORMAT_YUYV, 2077 DRM_FORMAT_YVYU, 2078 DRM_FORMAT_UYVY, 2079 DRM_FORMAT_VYUY, 2080 DRM_FORMAT_Y210, 2081 DRM_FORMAT_Y212, 2082 DRM_FORMAT_Y216, 2083 DRM_FORMAT_XVYU2101010, 2084 DRM_FORMAT_XVYU12_16161616, 2085 DRM_FORMAT_XVYU16161616, 2086 }; 2087 2088 static const u32 icl_sdr_uv_plane_formats[] = { 2089 DRM_FORMAT_C8, 2090 DRM_FORMAT_RGB565, 2091 DRM_FORMAT_XRGB8888, 2092 DRM_FORMAT_XBGR8888, 2093 DRM_FORMAT_ARGB8888, 2094 DRM_FORMAT_ABGR8888, 2095 DRM_FORMAT_XRGB2101010, 2096 DRM_FORMAT_XBGR2101010, 2097 DRM_FORMAT_YUYV, 2098 DRM_FORMAT_YVYU, 2099 DRM_FORMAT_UYVY, 2100 DRM_FORMAT_VYUY, 2101 DRM_FORMAT_NV12, 2102 DRM_FORMAT_P010, 2103 DRM_FORMAT_P012, 2104 DRM_FORMAT_P016, 2105 DRM_FORMAT_Y210, 2106 DRM_FORMAT_Y212, 2107 DRM_FORMAT_Y216, 2108 DRM_FORMAT_XVYU2101010, 2109 DRM_FORMAT_XVYU12_16161616, 2110 DRM_FORMAT_XVYU16161616, 2111 }; 2112 2113 static const u32 icl_hdr_plane_formats[] = { 2114 DRM_FORMAT_C8, 2115 DRM_FORMAT_RGB565, 2116 DRM_FORMAT_XRGB8888, 2117 DRM_FORMAT_XBGR8888, 2118 DRM_FORMAT_ARGB8888, 2119 DRM_FORMAT_ABGR8888, 2120 DRM_FORMAT_XRGB2101010, 2121 DRM_FORMAT_XBGR2101010, 2122 DRM_FORMAT_XRGB16161616F, 2123 DRM_FORMAT_XBGR16161616F, 2124 DRM_FORMAT_ARGB16161616F, 2125 DRM_FORMAT_ABGR16161616F, 2126 DRM_FORMAT_YUYV, 2127 DRM_FORMAT_YVYU, 2128 DRM_FORMAT_UYVY, 2129 DRM_FORMAT_VYUY, 2130 DRM_FORMAT_NV12, 2131 DRM_FORMAT_P010, 2132 DRM_FORMAT_P012, 2133 DRM_FORMAT_P016, 2134 DRM_FORMAT_Y210, 2135 DRM_FORMAT_Y212, 2136 DRM_FORMAT_Y216, 2137 DRM_FORMAT_XVYU2101010, 2138 DRM_FORMAT_XVYU12_16161616, 2139 DRM_FORMAT_XVYU16161616, 2140 }; 2141 2142 static const u64 skl_plane_format_modifiers_noccs[] = { 2143 I915_FORMAT_MOD_Yf_TILED, 2144 I915_FORMAT_MOD_Y_TILED, 2145 I915_FORMAT_MOD_X_TILED, 2146 DRM_FORMAT_MOD_LINEAR, 2147 DRM_FORMAT_MOD_INVALID 2148 }; 2149 2150 static const u64 skl_plane_format_modifiers_ccs[] = { 2151 I915_FORMAT_MOD_Yf_TILED_CCS, 2152 I915_FORMAT_MOD_Y_TILED_CCS, 2153 I915_FORMAT_MOD_Yf_TILED, 2154 I915_FORMAT_MOD_Y_TILED, 2155 I915_FORMAT_MOD_X_TILED, 2156 DRM_FORMAT_MOD_LINEAR, 2157 DRM_FORMAT_MOD_INVALID 2158 }; 2159 2160 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane, 2161 u32 format, u64 modifier) 2162 { 2163 switch (modifier) { 2164 case DRM_FORMAT_MOD_LINEAR: 2165 case I915_FORMAT_MOD_X_TILED: 2166 break; 2167 default: 2168 return false; 2169 } 2170 2171 switch (format) { 2172 case DRM_FORMAT_XRGB8888: 2173 case DRM_FORMAT_YUYV: 2174 case DRM_FORMAT_YVYU: 2175 case DRM_FORMAT_UYVY: 2176 case DRM_FORMAT_VYUY: 2177 if (modifier == DRM_FORMAT_MOD_LINEAR || 2178 modifier == I915_FORMAT_MOD_X_TILED) 2179 return true; 2180 /* fall through */ 2181 default: 2182 return false; 2183 } 2184 } 2185 2186 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane, 2187 u32 format, u64 modifier) 2188 { 2189 switch (modifier) { 2190 case DRM_FORMAT_MOD_LINEAR: 2191 case I915_FORMAT_MOD_X_TILED: 2192 break; 2193 default: 2194 return false; 2195 } 2196 2197 switch (format) { 2198 case DRM_FORMAT_XRGB8888: 2199 case DRM_FORMAT_XBGR8888: 2200 case DRM_FORMAT_YUYV: 2201 case DRM_FORMAT_YVYU: 2202 case DRM_FORMAT_UYVY: 2203 case DRM_FORMAT_VYUY: 2204 if (modifier == DRM_FORMAT_MOD_LINEAR || 2205 modifier == I915_FORMAT_MOD_X_TILED) 2206 return true; 2207 /* fall through */ 2208 default: 2209 return false; 2210 } 2211 } 2212 2213 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane, 2214 u32 format, u64 modifier) 2215 { 2216 switch (modifier) { 2217 case DRM_FORMAT_MOD_LINEAR: 2218 case I915_FORMAT_MOD_X_TILED: 2219 break; 2220 default: 2221 return false; 2222 } 2223 2224 switch (format) { 2225 case DRM_FORMAT_RGB565: 2226 case DRM_FORMAT_ABGR8888: 2227 case DRM_FORMAT_ARGB8888: 2228 case DRM_FORMAT_XBGR8888: 2229 case DRM_FORMAT_XRGB8888: 2230 case DRM_FORMAT_XBGR2101010: 2231 case DRM_FORMAT_ABGR2101010: 2232 case DRM_FORMAT_YUYV: 2233 case DRM_FORMAT_YVYU: 2234 case DRM_FORMAT_UYVY: 2235 case DRM_FORMAT_VYUY: 2236 if (modifier == DRM_FORMAT_MOD_LINEAR || 2237 modifier == I915_FORMAT_MOD_X_TILED) 2238 return true; 2239 /* fall through */ 2240 default: 2241 return false; 2242 } 2243 } 2244 2245 static bool skl_plane_format_mod_supported(struct drm_plane *_plane, 2246 u32 format, u64 modifier) 2247 { 2248 struct intel_plane *plane = to_intel_plane(_plane); 2249 2250 switch (modifier) { 2251 case DRM_FORMAT_MOD_LINEAR: 2252 case I915_FORMAT_MOD_X_TILED: 2253 case I915_FORMAT_MOD_Y_TILED: 2254 case I915_FORMAT_MOD_Yf_TILED: 2255 break; 2256 case I915_FORMAT_MOD_Y_TILED_CCS: 2257 case I915_FORMAT_MOD_Yf_TILED_CCS: 2258 if (!plane->has_ccs) 2259 return false; 2260 break; 2261 default: 2262 return false; 2263 } 2264 2265 switch (format) { 2266 case DRM_FORMAT_XRGB8888: 2267 case DRM_FORMAT_XBGR8888: 2268 case DRM_FORMAT_ARGB8888: 2269 case DRM_FORMAT_ABGR8888: 2270 if (is_ccs_modifier(modifier)) 2271 return true; 2272 /* fall through */ 2273 case DRM_FORMAT_RGB565: 2274 case DRM_FORMAT_XRGB2101010: 2275 case DRM_FORMAT_XBGR2101010: 2276 case DRM_FORMAT_YUYV: 2277 case DRM_FORMAT_YVYU: 2278 case DRM_FORMAT_UYVY: 2279 case DRM_FORMAT_VYUY: 2280 case DRM_FORMAT_NV12: 2281 case DRM_FORMAT_P010: 2282 case DRM_FORMAT_P012: 2283 case DRM_FORMAT_P016: 2284 case DRM_FORMAT_XVYU2101010: 2285 if (modifier == I915_FORMAT_MOD_Yf_TILED) 2286 return true; 2287 /* fall through */ 2288 case DRM_FORMAT_C8: 2289 case DRM_FORMAT_XBGR16161616F: 2290 case DRM_FORMAT_ABGR16161616F: 2291 case DRM_FORMAT_XRGB16161616F: 2292 case DRM_FORMAT_ARGB16161616F: 2293 case DRM_FORMAT_Y210: 2294 case DRM_FORMAT_Y212: 2295 case DRM_FORMAT_Y216: 2296 case DRM_FORMAT_XVYU12_16161616: 2297 case DRM_FORMAT_XVYU16161616: 2298 if (modifier == DRM_FORMAT_MOD_LINEAR || 2299 modifier == I915_FORMAT_MOD_X_TILED || 2300 modifier == I915_FORMAT_MOD_Y_TILED) 2301 return true; 2302 /* fall through */ 2303 default: 2304 return false; 2305 } 2306 } 2307 2308 static const struct drm_plane_funcs g4x_sprite_funcs = { 2309 .update_plane = drm_atomic_helper_update_plane, 2310 .disable_plane = drm_atomic_helper_disable_plane, 2311 .destroy = intel_plane_destroy, 2312 .atomic_duplicate_state = intel_plane_duplicate_state, 2313 .atomic_destroy_state = intel_plane_destroy_state, 2314 .format_mod_supported = g4x_sprite_format_mod_supported, 2315 }; 2316 2317 static const struct drm_plane_funcs snb_sprite_funcs = { 2318 .update_plane = drm_atomic_helper_update_plane, 2319 .disable_plane = drm_atomic_helper_disable_plane, 2320 .destroy = intel_plane_destroy, 2321 .atomic_duplicate_state = intel_plane_duplicate_state, 2322 .atomic_destroy_state = intel_plane_destroy_state, 2323 .format_mod_supported = snb_sprite_format_mod_supported, 2324 }; 2325 2326 static const struct drm_plane_funcs vlv_sprite_funcs = { 2327 .update_plane = drm_atomic_helper_update_plane, 2328 .disable_plane = drm_atomic_helper_disable_plane, 2329 .destroy = intel_plane_destroy, 2330 .atomic_duplicate_state = intel_plane_duplicate_state, 2331 .atomic_destroy_state = intel_plane_destroy_state, 2332 .format_mod_supported = vlv_sprite_format_mod_supported, 2333 }; 2334 2335 static const struct drm_plane_funcs skl_plane_funcs = { 2336 .update_plane = drm_atomic_helper_update_plane, 2337 .disable_plane = drm_atomic_helper_disable_plane, 2338 .destroy = intel_plane_destroy, 2339 .atomic_duplicate_state = intel_plane_duplicate_state, 2340 .atomic_destroy_state = intel_plane_destroy_state, 2341 .format_mod_supported = skl_plane_format_mod_supported, 2342 }; 2343 2344 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, 2345 enum pipe pipe, enum plane_id plane_id) 2346 { 2347 if (!HAS_FBC(dev_priv)) 2348 return false; 2349 2350 return pipe == PIPE_A && plane_id == PLANE_PRIMARY; 2351 } 2352 2353 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, 2354 enum pipe pipe, enum plane_id plane_id) 2355 { 2356 /* Display WA #0870: skl, bxt */ 2357 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) 2358 return false; 2359 2360 if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C) 2361 return false; 2362 2363 if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) 2364 return false; 2365 2366 return true; 2367 } 2368 2369 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, 2370 enum pipe pipe, enum plane_id plane_id, 2371 int *num_formats) 2372 { 2373 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2374 *num_formats = ARRAY_SIZE(skl_planar_formats); 2375 return skl_planar_formats; 2376 } else { 2377 *num_formats = ARRAY_SIZE(skl_plane_formats); 2378 return skl_plane_formats; 2379 } 2380 } 2381 2382 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, 2383 enum pipe pipe, enum plane_id plane_id, 2384 int *num_formats) 2385 { 2386 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2387 *num_formats = ARRAY_SIZE(glk_planar_formats); 2388 return glk_planar_formats; 2389 } else { 2390 *num_formats = ARRAY_SIZE(skl_plane_formats); 2391 return skl_plane_formats; 2392 } 2393 } 2394 2395 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv, 2396 enum pipe pipe, enum plane_id plane_id, 2397 int *num_formats) 2398 { 2399 if (icl_is_hdr_plane(dev_priv, plane_id)) { 2400 *num_formats = ARRAY_SIZE(icl_hdr_plane_formats); 2401 return icl_hdr_plane_formats; 2402 } else if (icl_is_nv12_y_plane(plane_id)) { 2403 *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats); 2404 return icl_sdr_y_plane_formats; 2405 } else { 2406 *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats); 2407 return icl_sdr_uv_plane_formats; 2408 } 2409 } 2410 2411 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 2412 enum pipe pipe, enum plane_id plane_id) 2413 { 2414 if (plane_id == PLANE_CURSOR) 2415 return false; 2416 2417 if (INTEL_GEN(dev_priv) >= 10) 2418 return true; 2419 2420 if (IS_GEMINILAKE(dev_priv)) 2421 return pipe != PIPE_C; 2422 2423 return pipe != PIPE_C && 2424 (plane_id == PLANE_PRIMARY || 2425 plane_id == PLANE_SPRITE0); 2426 } 2427 2428 struct intel_plane * 2429 skl_universal_plane_create(struct drm_i915_private *dev_priv, 2430 enum pipe pipe, enum plane_id plane_id) 2431 { 2432 struct intel_plane *plane; 2433 enum drm_plane_type plane_type; 2434 unsigned int supported_rotations; 2435 unsigned int possible_crtcs; 2436 const u64 *modifiers; 2437 const u32 *formats; 2438 int num_formats; 2439 int ret; 2440 2441 plane = intel_plane_alloc(); 2442 if (IS_ERR(plane)) 2443 return plane; 2444 2445 plane->pipe = pipe; 2446 plane->id = plane_id; 2447 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id); 2448 2449 plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id); 2450 if (plane->has_fbc) { 2451 struct intel_fbc *fbc = &dev_priv->fbc; 2452 2453 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; 2454 } 2455 2456 plane->max_stride = skl_plane_max_stride; 2457 plane->update_plane = skl_update_plane; 2458 plane->disable_plane = skl_disable_plane; 2459 plane->get_hw_state = skl_plane_get_hw_state; 2460 plane->check_plane = skl_plane_check; 2461 if (icl_is_nv12_y_plane(plane_id)) 2462 plane->update_slave = icl_update_slave; 2463 2464 if (INTEL_GEN(dev_priv) >= 11) 2465 formats = icl_get_plane_formats(dev_priv, pipe, 2466 plane_id, &num_formats); 2467 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 2468 formats = glk_get_plane_formats(dev_priv, pipe, 2469 plane_id, &num_formats); 2470 else 2471 formats = skl_get_plane_formats(dev_priv, pipe, 2472 plane_id, &num_formats); 2473 2474 plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id); 2475 if (plane->has_ccs) 2476 modifiers = skl_plane_format_modifiers_ccs; 2477 else 2478 modifiers = skl_plane_format_modifiers_noccs; 2479 2480 if (plane_id == PLANE_PRIMARY) 2481 plane_type = DRM_PLANE_TYPE_PRIMARY; 2482 else 2483 plane_type = DRM_PLANE_TYPE_OVERLAY; 2484 2485 possible_crtcs = BIT(pipe); 2486 2487 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 2488 possible_crtcs, &skl_plane_funcs, 2489 formats, num_formats, modifiers, 2490 plane_type, 2491 "plane %d%c", plane_id + 1, 2492 pipe_name(pipe)); 2493 if (ret) 2494 goto fail; 2495 2496 supported_rotations = 2497 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | 2498 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; 2499 2500 if (INTEL_GEN(dev_priv) >= 10) 2501 supported_rotations |= DRM_MODE_REFLECT_X; 2502 2503 drm_plane_create_rotation_property(&plane->base, 2504 DRM_MODE_ROTATE_0, 2505 supported_rotations); 2506 2507 drm_plane_create_color_properties(&plane->base, 2508 BIT(DRM_COLOR_YCBCR_BT601) | 2509 BIT(DRM_COLOR_YCBCR_BT709), 2510 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 2511 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 2512 DRM_COLOR_YCBCR_BT709, 2513 DRM_COLOR_YCBCR_LIMITED_RANGE); 2514 2515 drm_plane_create_alpha_property(&plane->base); 2516 drm_plane_create_blend_mode_property(&plane->base, 2517 BIT(DRM_MODE_BLEND_PIXEL_NONE) | 2518 BIT(DRM_MODE_BLEND_PREMULTI) | 2519 BIT(DRM_MODE_BLEND_COVERAGE)); 2520 2521 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 2522 2523 return plane; 2524 2525 fail: 2526 intel_plane_free(plane); 2527 2528 return ERR_PTR(ret); 2529 } 2530 2531 struct intel_plane * 2532 intel_sprite_plane_create(struct drm_i915_private *dev_priv, 2533 enum pipe pipe, int sprite) 2534 { 2535 struct intel_plane *plane; 2536 const struct drm_plane_funcs *plane_funcs; 2537 unsigned long possible_crtcs; 2538 unsigned int supported_rotations; 2539 const u64 *modifiers; 2540 const u32 *formats; 2541 int num_formats; 2542 int ret; 2543 2544 if (INTEL_GEN(dev_priv) >= 9) 2545 return skl_universal_plane_create(dev_priv, pipe, 2546 PLANE_SPRITE0 + sprite); 2547 2548 plane = intel_plane_alloc(); 2549 if (IS_ERR(plane)) 2550 return plane; 2551 2552 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 2553 plane->max_stride = i9xx_plane_max_stride; 2554 plane->update_plane = vlv_update_plane; 2555 plane->disable_plane = vlv_disable_plane; 2556 plane->get_hw_state = vlv_plane_get_hw_state; 2557 plane->check_plane = vlv_sprite_check; 2558 2559 formats = vlv_plane_formats; 2560 num_formats = ARRAY_SIZE(vlv_plane_formats); 2561 modifiers = i9xx_plane_format_modifiers; 2562 2563 plane_funcs = &vlv_sprite_funcs; 2564 } else if (INTEL_GEN(dev_priv) >= 7) { 2565 plane->max_stride = g4x_sprite_max_stride; 2566 plane->update_plane = ivb_update_plane; 2567 plane->disable_plane = ivb_disable_plane; 2568 plane->get_hw_state = ivb_plane_get_hw_state; 2569 plane->check_plane = g4x_sprite_check; 2570 2571 formats = snb_plane_formats; 2572 num_formats = ARRAY_SIZE(snb_plane_formats); 2573 modifiers = i9xx_plane_format_modifiers; 2574 2575 plane_funcs = &snb_sprite_funcs; 2576 } else { 2577 plane->max_stride = g4x_sprite_max_stride; 2578 plane->update_plane = g4x_update_plane; 2579 plane->disable_plane = g4x_disable_plane; 2580 plane->get_hw_state = g4x_plane_get_hw_state; 2581 plane->check_plane = g4x_sprite_check; 2582 2583 modifiers = i9xx_plane_format_modifiers; 2584 if (IS_GEN(dev_priv, 6)) { 2585 formats = snb_plane_formats; 2586 num_formats = ARRAY_SIZE(snb_plane_formats); 2587 2588 plane_funcs = &snb_sprite_funcs; 2589 } else { 2590 formats = g4x_plane_formats; 2591 num_formats = ARRAY_SIZE(g4x_plane_formats); 2592 2593 plane_funcs = &g4x_sprite_funcs; 2594 } 2595 } 2596 2597 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 2598 supported_rotations = 2599 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 2600 DRM_MODE_REFLECT_X; 2601 } else { 2602 supported_rotations = 2603 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 2604 } 2605 2606 plane->pipe = pipe; 2607 plane->id = PLANE_SPRITE0 + sprite; 2608 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 2609 2610 possible_crtcs = BIT(pipe); 2611 2612 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 2613 possible_crtcs, plane_funcs, 2614 formats, num_formats, modifiers, 2615 DRM_PLANE_TYPE_OVERLAY, 2616 "sprite %c", sprite_name(pipe, sprite)); 2617 if (ret) 2618 goto fail; 2619 2620 drm_plane_create_rotation_property(&plane->base, 2621 DRM_MODE_ROTATE_0, 2622 supported_rotations); 2623 2624 drm_plane_create_color_properties(&plane->base, 2625 BIT(DRM_COLOR_YCBCR_BT601) | 2626 BIT(DRM_COLOR_YCBCR_BT709), 2627 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 2628 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 2629 DRM_COLOR_YCBCR_BT709, 2630 DRM_COLOR_YCBCR_LIMITED_RANGE); 2631 2632 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 2633 2634 return plane; 2635 2636 fail: 2637 intel_plane_free(plane); 2638 2639 return ERR_PTR(ret); 2640 } 2641