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