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