1 /* 2 * Copyright © 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Jesse Barnes <jbarnes@virtuousgeek.org> 25 * 26 * New plane/sprite handling. 27 * 28 * The older chips had a separate interface for programming plane related 29 * registers; newer ones are much simpler and we can use the new DRM plane 30 * support. 31 */ 32 33 #include <drm/drm_atomic.h> 34 #include <drm/drm_atomic_helper.h> 35 #include <drm/drm_color_mgmt.h> 36 #include <drm/drm_crtc.h> 37 #include <drm/drm_damage_helper.h> 38 #include <drm/drm_fourcc.h> 39 #include <drm/drm_plane_helper.h> 40 #include <drm/drm_rect.h> 41 42 #include "i915_drv.h" 43 #include "i915_vgpu.h" 44 #include "i9xx_plane.h" 45 #include "intel_atomic_plane.h" 46 #include "intel_crtc.h" 47 #include "intel_de.h" 48 #include "intel_display_types.h" 49 #include "intel_fb.h" 50 #include "intel_frontbuffer.h" 51 #include "intel_sprite.h" 52 #include "intel_vrr.h" 53 54 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) 55 { 56 struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); 57 const struct drm_framebuffer *fb = plane_state->hw.fb; 58 struct drm_rect *src = &plane_state->uapi.src; 59 u32 src_x, src_y, src_w, src_h, hsub, vsub; 60 bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation); 61 62 /* 63 * FIXME hsub/vsub vs. block size is a mess. Pre-tgl CCS 64 * abuses hsub/vsub so we can't use them here. But as they 65 * are limited to 32bpp RGB formats we don't actually need 66 * to check anything. 67 */ 68 if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 69 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) 70 return 0; 71 72 /* 73 * Hardware doesn't handle subpixel coordinates. 74 * Adjust to (macro)pixel boundary, but be careful not to 75 * increase the source viewport size, because that could 76 * push the downscaling factor out of bounds. 77 */ 78 src_x = src->x1 >> 16; 79 src_w = drm_rect_width(src) >> 16; 80 src_y = src->y1 >> 16; 81 src_h = drm_rect_height(src) >> 16; 82 83 drm_rect_init(src, src_x << 16, src_y << 16, 84 src_w << 16, src_h << 16); 85 86 if (fb->format->format == DRM_FORMAT_RGB565 && rotated) { 87 hsub = 2; 88 vsub = 2; 89 } else { 90 hsub = fb->format->hsub; 91 vsub = fb->format->vsub; 92 } 93 94 if (rotated) 95 hsub = vsub = max(hsub, vsub); 96 97 if (src_x % hsub || src_w % hsub) { 98 drm_dbg_kms(&i915->drm, "src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n", 99 src_x, src_w, hsub, yesno(rotated)); 100 return -EINVAL; 101 } 102 103 if (src_y % vsub || src_h % vsub) { 104 drm_dbg_kms(&i915->drm, "src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n", 105 src_y, src_h, vsub, yesno(rotated)); 106 return -EINVAL; 107 } 108 109 return 0; 110 } 111 112 static void i9xx_plane_linear_gamma(u16 gamma[8]) 113 { 114 /* The points are not evenly spaced. */ 115 static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 }; 116 int i; 117 118 for (i = 0; i < 8; i++) 119 gamma[i] = (in[i] << 8) / 32; 120 } 121 122 static void 123 chv_sprite_update_csc(const struct intel_plane_state *plane_state) 124 { 125 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 126 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 127 const struct drm_framebuffer *fb = plane_state->hw.fb; 128 enum plane_id plane_id = plane->id; 129 /* 130 * |r| | c0 c1 c2 | |cr| 131 * |g| = | c3 c4 c5 | x |y | 132 * |b| | c6 c7 c8 | |cb| 133 * 134 * Coefficients are s3.12. 135 * 136 * Cb and Cr apparently come in as signed already, and 137 * we always get full range data in on account of CLRC0/1. 138 */ 139 static const s16 csc_matrix[][9] = { 140 /* BT.601 full range YCbCr -> full range RGB */ 141 [DRM_COLOR_YCBCR_BT601] = { 142 5743, 4096, 0, 143 -2925, 4096, -1410, 144 0, 4096, 7258, 145 }, 146 /* BT.709 full range YCbCr -> full range RGB */ 147 [DRM_COLOR_YCBCR_BT709] = { 148 6450, 4096, 0, 149 -1917, 4096, -767, 150 0, 4096, 7601, 151 }, 152 }; 153 const s16 *csc = csc_matrix[plane_state->hw.color_encoding]; 154 155 /* Seems RGB data bypasses the CSC always */ 156 if (!fb->format->is_yuv) 157 return; 158 159 intel_de_write_fw(dev_priv, SPCSCYGOFF(plane_id), 160 SPCSC_OOFF(0) | SPCSC_IOFF(0)); 161 intel_de_write_fw(dev_priv, SPCSCCBOFF(plane_id), 162 SPCSC_OOFF(0) | SPCSC_IOFF(0)); 163 intel_de_write_fw(dev_priv, SPCSCCROFF(plane_id), 164 SPCSC_OOFF(0) | SPCSC_IOFF(0)); 165 166 intel_de_write_fw(dev_priv, SPCSCC01(plane_id), 167 SPCSC_C1(csc[1]) | SPCSC_C0(csc[0])); 168 intel_de_write_fw(dev_priv, SPCSCC23(plane_id), 169 SPCSC_C1(csc[3]) | SPCSC_C0(csc[2])); 170 intel_de_write_fw(dev_priv, SPCSCC45(plane_id), 171 SPCSC_C1(csc[5]) | SPCSC_C0(csc[4])); 172 intel_de_write_fw(dev_priv, SPCSCC67(plane_id), 173 SPCSC_C1(csc[7]) | SPCSC_C0(csc[6])); 174 intel_de_write_fw(dev_priv, SPCSCC8(plane_id), SPCSC_C0(csc[8])); 175 176 intel_de_write_fw(dev_priv, SPCSCYGICLAMP(plane_id), 177 SPCSC_IMAX(1023) | SPCSC_IMIN(0)); 178 intel_de_write_fw(dev_priv, SPCSCCBICLAMP(plane_id), 179 SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 180 intel_de_write_fw(dev_priv, SPCSCCRICLAMP(plane_id), 181 SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 182 183 intel_de_write_fw(dev_priv, SPCSCYGOCLAMP(plane_id), 184 SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 185 intel_de_write_fw(dev_priv, SPCSCCBOCLAMP(plane_id), 186 SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 187 intel_de_write_fw(dev_priv, SPCSCCROCLAMP(plane_id), 188 SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 189 } 190 191 #define SIN_0 0 192 #define COS_0 1 193 194 static void 195 vlv_sprite_update_clrc(const struct intel_plane_state *plane_state) 196 { 197 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 198 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 199 const struct drm_framebuffer *fb = plane_state->hw.fb; 200 enum pipe pipe = plane->pipe; 201 enum plane_id plane_id = plane->id; 202 int contrast, brightness, sh_scale, sh_sin, sh_cos; 203 204 if (fb->format->is_yuv && 205 plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) { 206 /* 207 * Expand limited range to full range: 208 * Contrast is applied first and is used to expand Y range. 209 * Brightness is applied second and is used to remove the 210 * offset from Y. Saturation/hue is used to expand CbCr range. 211 */ 212 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16); 213 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16); 214 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128); 215 sh_sin = SIN_0 * sh_scale; 216 sh_cos = COS_0 * sh_scale; 217 } else { 218 /* Pass-through everything. */ 219 contrast = 1 << 6; 220 brightness = 0; 221 sh_scale = 1 << 7; 222 sh_sin = SIN_0 * sh_scale; 223 sh_cos = COS_0 * sh_scale; 224 } 225 226 /* FIXME these register are single buffered :( */ 227 intel_de_write_fw(dev_priv, SPCLRC0(pipe, plane_id), 228 SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness)); 229 intel_de_write_fw(dev_priv, SPCLRC1(pipe, plane_id), 230 SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos)); 231 } 232 233 static void 234 vlv_plane_ratio(const struct intel_crtc_state *crtc_state, 235 const struct intel_plane_state *plane_state, 236 unsigned int *num, unsigned int *den) 237 { 238 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 239 const struct drm_framebuffer *fb = plane_state->hw.fb; 240 unsigned int cpp = fb->format->cpp[0]; 241 242 /* 243 * VLV bspec only considers cases where all three planes are 244 * enabled, and cases where the primary and one sprite is enabled. 245 * Let's assume the case with just two sprites enabled also 246 * maps to the latter case. 247 */ 248 if (hweight8(active_planes) == 3) { 249 switch (cpp) { 250 case 8: 251 *num = 11; 252 *den = 8; 253 break; 254 case 4: 255 *num = 18; 256 *den = 16; 257 break; 258 default: 259 *num = 1; 260 *den = 1; 261 break; 262 } 263 } else if (hweight8(active_planes) == 2) { 264 switch (cpp) { 265 case 8: 266 *num = 10; 267 *den = 8; 268 break; 269 case 4: 270 *num = 17; 271 *den = 16; 272 break; 273 default: 274 *num = 1; 275 *den = 1; 276 break; 277 } 278 } else { 279 switch (cpp) { 280 case 8: 281 *num = 10; 282 *den = 8; 283 break; 284 default: 285 *num = 1; 286 *den = 1; 287 break; 288 } 289 } 290 } 291 292 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 293 const struct intel_plane_state *plane_state) 294 { 295 unsigned int pixel_rate; 296 unsigned int num, den; 297 298 /* 299 * Note that crtc_state->pixel_rate accounts for both 300 * horizontal and vertical panel fitter downscaling factors. 301 * Pre-HSW bspec tells us to only consider the horizontal 302 * downscaling factor here. We ignore that and just consider 303 * both for simplicity. 304 */ 305 pixel_rate = crtc_state->pixel_rate; 306 307 vlv_plane_ratio(crtc_state, plane_state, &num, &den); 308 309 return DIV_ROUND_UP(pixel_rate * num, den); 310 } 311 312 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 313 { 314 u32 sprctl = 0; 315 316 if (crtc_state->gamma_enable) 317 sprctl |= SP_PIPE_GAMMA_ENABLE; 318 319 return sprctl; 320 } 321 322 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, 323 const struct intel_plane_state *plane_state) 324 { 325 const struct drm_framebuffer *fb = plane_state->hw.fb; 326 unsigned int rotation = plane_state->hw.rotation; 327 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 328 u32 sprctl; 329 330 sprctl = SP_ENABLE; 331 332 switch (fb->format->format) { 333 case DRM_FORMAT_YUYV: 334 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 335 break; 336 case DRM_FORMAT_YVYU: 337 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 338 break; 339 case DRM_FORMAT_UYVY: 340 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 341 break; 342 case DRM_FORMAT_VYUY: 343 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 344 break; 345 case DRM_FORMAT_C8: 346 sprctl |= SP_FORMAT_8BPP; 347 break; 348 case DRM_FORMAT_RGB565: 349 sprctl |= SP_FORMAT_BGR565; 350 break; 351 case DRM_FORMAT_XRGB8888: 352 sprctl |= SP_FORMAT_BGRX8888; 353 break; 354 case DRM_FORMAT_ARGB8888: 355 sprctl |= SP_FORMAT_BGRA8888; 356 break; 357 case DRM_FORMAT_XBGR2101010: 358 sprctl |= SP_FORMAT_RGBX1010102; 359 break; 360 case DRM_FORMAT_ABGR2101010: 361 sprctl |= SP_FORMAT_RGBA1010102; 362 break; 363 case DRM_FORMAT_XRGB2101010: 364 sprctl |= SP_FORMAT_BGRX1010102; 365 break; 366 case DRM_FORMAT_ARGB2101010: 367 sprctl |= SP_FORMAT_BGRA1010102; 368 break; 369 case DRM_FORMAT_XBGR8888: 370 sprctl |= SP_FORMAT_RGBX8888; 371 break; 372 case DRM_FORMAT_ABGR8888: 373 sprctl |= SP_FORMAT_RGBA8888; 374 break; 375 default: 376 MISSING_CASE(fb->format->format); 377 return 0; 378 } 379 380 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 381 sprctl |= SP_YUV_FORMAT_BT709; 382 383 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 384 sprctl |= SP_TILED; 385 386 if (rotation & DRM_MODE_ROTATE_180) 387 sprctl |= SP_ROTATE_180; 388 389 if (rotation & DRM_MODE_REFLECT_X) 390 sprctl |= SP_MIRROR; 391 392 if (key->flags & I915_SET_COLORKEY_SOURCE) 393 sprctl |= SP_SOURCE_KEY; 394 395 return sprctl; 396 } 397 398 static void vlv_sprite_update_gamma(const struct intel_plane_state *plane_state) 399 { 400 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 401 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 402 const struct drm_framebuffer *fb = plane_state->hw.fb; 403 enum pipe pipe = plane->pipe; 404 enum plane_id plane_id = plane->id; 405 u16 gamma[8]; 406 int i; 407 408 /* Seems RGB data bypasses the gamma always */ 409 if (!fb->format->is_yuv) 410 return; 411 412 i9xx_plane_linear_gamma(gamma); 413 414 /* FIXME these register are single buffered :( */ 415 /* The two end points are implicit (0.0 and 1.0) */ 416 for (i = 1; i < 8 - 1; i++) 417 intel_de_write_fw(dev_priv, SPGAMC(pipe, plane_id, i - 1), 418 gamma[i] << 16 | gamma[i] << 8 | gamma[i]); 419 } 420 421 static void 422 vlv_sprite_update_noarm(struct intel_plane *plane, 423 const struct intel_crtc_state *crtc_state, 424 const struct intel_plane_state *plane_state) 425 { 426 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 427 enum pipe pipe = plane->pipe; 428 enum plane_id plane_id = plane->id; 429 int crtc_x = plane_state->uapi.dst.x1; 430 int crtc_y = plane_state->uapi.dst.y1; 431 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 432 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 433 unsigned long irqflags; 434 435 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 436 437 intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id), 438 plane_state->view.color_plane[0].mapping_stride); 439 intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id), 440 SP_POS_Y(crtc_y) | SP_POS_X(crtc_x)); 441 intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id), 442 SP_HEIGHT(crtc_h - 1) | SP_WIDTH(crtc_w - 1)); 443 444 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 445 } 446 447 static void 448 vlv_sprite_update_arm(struct intel_plane *plane, 449 const struct intel_crtc_state *crtc_state, 450 const struct intel_plane_state *plane_state) 451 { 452 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 453 enum pipe pipe = plane->pipe; 454 enum plane_id plane_id = plane->id; 455 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 456 u32 sprsurf_offset = plane_state->view.color_plane[0].offset; 457 u32 x = plane_state->view.color_plane[0].x; 458 u32 y = plane_state->view.color_plane[0].y; 459 u32 sprctl, linear_offset; 460 unsigned long irqflags; 461 462 sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state); 463 464 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 465 466 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 467 468 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 469 chv_sprite_update_csc(plane_state); 470 471 if (key->flags) { 472 intel_de_write_fw(dev_priv, SPKEYMINVAL(pipe, plane_id), 473 key->min_value); 474 intel_de_write_fw(dev_priv, SPKEYMSK(pipe, plane_id), 475 key->channel_mask); 476 intel_de_write_fw(dev_priv, SPKEYMAXVAL(pipe, plane_id), 477 key->max_value); 478 } 479 480 intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0); 481 482 intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset); 483 intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id), 484 SP_OFFSET_Y(y) | SP_OFFSET_X(x)); 485 486 /* 487 * The control register self-arms if the plane was previously 488 * disabled. Try to make the plane enable atomic by writing 489 * the control register just before the surface register. 490 */ 491 intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), sprctl); 492 intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 493 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 494 495 vlv_sprite_update_clrc(plane_state); 496 vlv_sprite_update_gamma(plane_state); 497 498 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 499 } 500 501 static void 502 vlv_sprite_disable_arm(struct intel_plane *plane, 503 const struct intel_crtc_state *crtc_state) 504 { 505 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 506 enum pipe pipe = plane->pipe; 507 enum plane_id plane_id = plane->id; 508 unsigned long irqflags; 509 510 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 511 512 intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), 0); 513 intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 0); 514 515 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 516 } 517 518 static bool 519 vlv_sprite_get_hw_state(struct intel_plane *plane, 520 enum pipe *pipe) 521 { 522 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 523 enum intel_display_power_domain power_domain; 524 enum plane_id plane_id = plane->id; 525 intel_wakeref_t wakeref; 526 bool ret; 527 528 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 529 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 530 if (!wakeref) 531 return false; 532 533 ret = intel_de_read(dev_priv, SPCNTR(plane->pipe, plane_id)) & SP_ENABLE; 534 535 *pipe = plane->pipe; 536 537 intel_display_power_put(dev_priv, power_domain, wakeref); 538 539 return ret; 540 } 541 542 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state, 543 const struct intel_plane_state *plane_state, 544 unsigned int *num, unsigned int *den) 545 { 546 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 547 const struct drm_framebuffer *fb = plane_state->hw.fb; 548 unsigned int cpp = fb->format->cpp[0]; 549 550 if (hweight8(active_planes) == 2) { 551 switch (cpp) { 552 case 8: 553 *num = 10; 554 *den = 8; 555 break; 556 case 4: 557 *num = 17; 558 *den = 16; 559 break; 560 default: 561 *num = 1; 562 *den = 1; 563 break; 564 } 565 } else { 566 switch (cpp) { 567 case 8: 568 *num = 9; 569 *den = 8; 570 break; 571 default: 572 *num = 1; 573 *den = 1; 574 break; 575 } 576 } 577 } 578 579 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state, 580 const struct intel_plane_state *plane_state, 581 unsigned int *num, unsigned int *den) 582 { 583 const struct drm_framebuffer *fb = plane_state->hw.fb; 584 unsigned int cpp = fb->format->cpp[0]; 585 586 switch (cpp) { 587 case 8: 588 *num = 12; 589 *den = 8; 590 break; 591 case 4: 592 *num = 19; 593 *den = 16; 594 break; 595 case 2: 596 *num = 33; 597 *den = 32; 598 break; 599 default: 600 *num = 1; 601 *den = 1; 602 break; 603 } 604 } 605 606 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 607 const struct intel_plane_state *plane_state) 608 { 609 unsigned int pixel_rate; 610 unsigned int num, den; 611 612 /* 613 * Note that crtc_state->pixel_rate accounts for both 614 * horizontal and vertical panel fitter downscaling factors. 615 * Pre-HSW bspec tells us to only consider the horizontal 616 * downscaling factor here. We ignore that and just consider 617 * both for simplicity. 618 */ 619 pixel_rate = crtc_state->pixel_rate; 620 621 ivb_plane_ratio(crtc_state, plane_state, &num, &den); 622 623 return DIV_ROUND_UP(pixel_rate * num, den); 624 } 625 626 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 627 const struct intel_plane_state *plane_state) 628 { 629 unsigned int src_w, dst_w, pixel_rate; 630 unsigned int num, den; 631 632 /* 633 * Note that crtc_state->pixel_rate accounts for both 634 * horizontal and vertical panel fitter downscaling factors. 635 * Pre-HSW bspec tells us to only consider the horizontal 636 * downscaling factor here. We ignore that and just consider 637 * both for simplicity. 638 */ 639 pixel_rate = crtc_state->pixel_rate; 640 641 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 642 dst_w = drm_rect_width(&plane_state->uapi.dst); 643 644 if (src_w != dst_w) 645 ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den); 646 else 647 ivb_plane_ratio(crtc_state, plane_state, &num, &den); 648 649 /* Horizontal downscaling limits the maximum pixel rate */ 650 dst_w = min(src_w, dst_w); 651 652 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w), 653 den * dst_w); 654 } 655 656 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state, 657 const struct intel_plane_state *plane_state, 658 unsigned int *num, unsigned int *den) 659 { 660 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 661 const struct drm_framebuffer *fb = plane_state->hw.fb; 662 unsigned int cpp = fb->format->cpp[0]; 663 664 if (hweight8(active_planes) == 2) { 665 switch (cpp) { 666 case 8: 667 *num = 10; 668 *den = 8; 669 break; 670 default: 671 *num = 1; 672 *den = 1; 673 break; 674 } 675 } else { 676 switch (cpp) { 677 case 8: 678 *num = 9; 679 *den = 8; 680 break; 681 default: 682 *num = 1; 683 *den = 1; 684 break; 685 } 686 } 687 } 688 689 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 690 const struct intel_plane_state *plane_state) 691 { 692 unsigned int pixel_rate = crtc_state->pixel_rate; 693 unsigned int num, den; 694 695 hsw_plane_ratio(crtc_state, plane_state, &num, &den); 696 697 return DIV_ROUND_UP(pixel_rate * num, den); 698 } 699 700 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 701 { 702 u32 sprctl = 0; 703 704 if (crtc_state->gamma_enable) 705 sprctl |= SPRITE_PIPE_GAMMA_ENABLE; 706 707 if (crtc_state->csc_enable) 708 sprctl |= SPRITE_PIPE_CSC_ENABLE; 709 710 return sprctl; 711 } 712 713 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state) 714 { 715 struct drm_i915_private *dev_priv = 716 to_i915(plane_state->uapi.plane->dev); 717 const struct drm_framebuffer *fb = plane_state->hw.fb; 718 719 return fb->format->cpp[0] == 8 && 720 (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)); 721 } 722 723 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, 724 const struct intel_plane_state *plane_state) 725 { 726 struct drm_i915_private *dev_priv = 727 to_i915(plane_state->uapi.plane->dev); 728 const struct drm_framebuffer *fb = plane_state->hw.fb; 729 unsigned int rotation = plane_state->hw.rotation; 730 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 731 u32 sprctl; 732 733 sprctl = SPRITE_ENABLE; 734 735 if (IS_IVYBRIDGE(dev_priv)) 736 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 737 738 switch (fb->format->format) { 739 case DRM_FORMAT_XBGR8888: 740 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 741 break; 742 case DRM_FORMAT_XRGB8888: 743 sprctl |= SPRITE_FORMAT_RGBX888; 744 break; 745 case DRM_FORMAT_XBGR2101010: 746 sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX; 747 break; 748 case DRM_FORMAT_XRGB2101010: 749 sprctl |= SPRITE_FORMAT_RGBX101010; 750 break; 751 case DRM_FORMAT_XBGR16161616F: 752 sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX; 753 break; 754 case DRM_FORMAT_XRGB16161616F: 755 sprctl |= SPRITE_FORMAT_RGBX161616; 756 break; 757 case DRM_FORMAT_YUYV: 758 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 759 break; 760 case DRM_FORMAT_YVYU: 761 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 762 break; 763 case DRM_FORMAT_UYVY: 764 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 765 break; 766 case DRM_FORMAT_VYUY: 767 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 768 break; 769 default: 770 MISSING_CASE(fb->format->format); 771 return 0; 772 } 773 774 if (!ivb_need_sprite_gamma(plane_state)) 775 sprctl |= SPRITE_PLANE_GAMMA_DISABLE; 776 777 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 778 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; 779 780 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 781 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE; 782 783 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 784 sprctl |= SPRITE_TILED; 785 786 if (rotation & DRM_MODE_ROTATE_180) 787 sprctl |= SPRITE_ROTATE_180; 788 789 if (key->flags & I915_SET_COLORKEY_DESTINATION) 790 sprctl |= SPRITE_DEST_KEY; 791 else if (key->flags & I915_SET_COLORKEY_SOURCE) 792 sprctl |= SPRITE_SOURCE_KEY; 793 794 return sprctl; 795 } 796 797 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state, 798 u16 gamma[18]) 799 { 800 int scale, i; 801 802 /* 803 * WaFP16GammaEnabling:ivb,hsw 804 * "Workaround : When using the 64-bit format, the sprite output 805 * on each color channel has one quarter amplitude. It can be 806 * brought up to full amplitude by using sprite internal gamma 807 * correction, pipe gamma correction, or pipe color space 808 * conversion to multiply the sprite output by four." 809 */ 810 scale = 4; 811 812 for (i = 0; i < 16; i++) 813 gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1); 814 815 gamma[i] = min((scale * i << 10) / 16, 1 << 10); 816 i++; 817 818 gamma[i] = 3 << 10; 819 i++; 820 } 821 822 static void ivb_sprite_update_gamma(const struct intel_plane_state *plane_state) 823 { 824 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 825 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 826 enum pipe pipe = plane->pipe; 827 u16 gamma[18]; 828 int i; 829 830 if (!ivb_need_sprite_gamma(plane_state)) 831 return; 832 833 ivb_sprite_linear_gamma(plane_state, gamma); 834 835 /* FIXME these register are single buffered :( */ 836 for (i = 0; i < 16; i++) 837 intel_de_write_fw(dev_priv, SPRGAMC(pipe, i), 838 gamma[i] << 20 | gamma[i] << 10 | gamma[i]); 839 840 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 0), gamma[i]); 841 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 1), gamma[i]); 842 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 2), gamma[i]); 843 i++; 844 845 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 0), gamma[i]); 846 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 1), gamma[i]); 847 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 2), gamma[i]); 848 i++; 849 } 850 851 static void 852 ivb_sprite_update_noarm(struct intel_plane *plane, 853 const struct intel_crtc_state *crtc_state, 854 const struct intel_plane_state *plane_state) 855 { 856 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 857 enum pipe pipe = plane->pipe; 858 int crtc_x = plane_state->uapi.dst.x1; 859 int crtc_y = plane_state->uapi.dst.y1; 860 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 861 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 862 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 863 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 864 u32 sprscale = 0; 865 unsigned long irqflags; 866 867 if (crtc_w != src_w || crtc_h != src_h) 868 sprscale = SPRITE_SCALE_ENABLE | 869 SPRITE_SRC_WIDTH(src_w - 1) | 870 SPRITE_SRC_HEIGHT(src_h - 1); 871 872 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 873 874 intel_de_write_fw(dev_priv, SPRSTRIDE(pipe), 875 plane_state->view.color_plane[0].mapping_stride); 876 intel_de_write_fw(dev_priv, SPRPOS(pipe), 877 SPRITE_POS_Y(crtc_y) | SPRITE_POS_X(crtc_x)); 878 intel_de_write_fw(dev_priv, SPRSIZE(pipe), 879 SPRITE_HEIGHT(crtc_h - 1) | SPRITE_WIDTH(crtc_w - 1)); 880 if (IS_IVYBRIDGE(dev_priv)) 881 intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale); 882 883 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 884 } 885 886 static void 887 ivb_sprite_update_arm(struct intel_plane *plane, 888 const struct intel_crtc_state *crtc_state, 889 const struct intel_plane_state *plane_state) 890 { 891 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 892 enum pipe pipe = plane->pipe; 893 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 894 u32 sprsurf_offset = plane_state->view.color_plane[0].offset; 895 u32 x = plane_state->view.color_plane[0].x; 896 u32 y = plane_state->view.color_plane[0].y; 897 u32 sprctl, linear_offset; 898 unsigned long irqflags; 899 900 sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state); 901 902 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 903 904 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 905 906 if (key->flags) { 907 intel_de_write_fw(dev_priv, SPRKEYVAL(pipe), key->min_value); 908 intel_de_write_fw(dev_priv, SPRKEYMSK(pipe), 909 key->channel_mask); 910 intel_de_write_fw(dev_priv, SPRKEYMAX(pipe), key->max_value); 911 } 912 913 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 914 * register */ 915 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 916 intel_de_write_fw(dev_priv, SPROFFSET(pipe), 917 SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x)); 918 } else { 919 intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset); 920 intel_de_write_fw(dev_priv, SPRTILEOFF(pipe), 921 SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x)); 922 } 923 924 /* 925 * The control register self-arms if the plane was previously 926 * disabled. Try to make the plane enable atomic by writing 927 * the control register just before the surface register. 928 */ 929 intel_de_write_fw(dev_priv, SPRCTL(pipe), sprctl); 930 intel_de_write_fw(dev_priv, SPRSURF(pipe), 931 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 932 933 ivb_sprite_update_gamma(plane_state); 934 935 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 936 } 937 938 static void 939 ivb_sprite_disable_arm(struct intel_plane *plane, 940 const struct intel_crtc_state *crtc_state) 941 { 942 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 943 enum pipe pipe = plane->pipe; 944 unsigned long irqflags; 945 946 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 947 948 intel_de_write_fw(dev_priv, SPRCTL(pipe), 0); 949 /* Disable the scaler */ 950 if (IS_IVYBRIDGE(dev_priv)) 951 intel_de_write_fw(dev_priv, SPRSCALE(pipe), 0); 952 intel_de_write_fw(dev_priv, SPRSURF(pipe), 0); 953 954 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 955 } 956 957 static bool 958 ivb_sprite_get_hw_state(struct intel_plane *plane, 959 enum pipe *pipe) 960 { 961 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 962 enum intel_display_power_domain power_domain; 963 intel_wakeref_t wakeref; 964 bool ret; 965 966 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 967 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 968 if (!wakeref) 969 return false; 970 971 ret = intel_de_read(dev_priv, SPRCTL(plane->pipe)) & SPRITE_ENABLE; 972 973 *pipe = plane->pipe; 974 975 intel_display_power_put(dev_priv, power_domain, wakeref); 976 977 return ret; 978 } 979 980 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 981 const struct intel_plane_state *plane_state) 982 { 983 const struct drm_framebuffer *fb = plane_state->hw.fb; 984 unsigned int hscale, pixel_rate; 985 unsigned int limit, decimate; 986 987 /* 988 * Note that crtc_state->pixel_rate accounts for both 989 * horizontal and vertical panel fitter downscaling factors. 990 * Pre-HSW bspec tells us to only consider the horizontal 991 * downscaling factor here. We ignore that and just consider 992 * both for simplicity. 993 */ 994 pixel_rate = crtc_state->pixel_rate; 995 996 /* Horizontal downscaling limits the maximum pixel rate */ 997 hscale = drm_rect_calc_hscale(&plane_state->uapi.src, 998 &plane_state->uapi.dst, 999 0, INT_MAX); 1000 hscale = max(hscale, 0x10000u); 1001 1002 /* Decimation steps at 2x,4x,8x,16x */ 1003 decimate = ilog2(hscale >> 16); 1004 hscale >>= decimate; 1005 1006 /* Starting limit is 90% of cdclk */ 1007 limit = 9; 1008 1009 /* -10% per decimation step */ 1010 limit -= decimate; 1011 1012 /* -10% for RGB */ 1013 if (!fb->format->is_yuv) 1014 limit--; 1015 1016 /* 1017 * We should also do -10% if sprite scaling is enabled 1018 * on the other pipe, but we can't really check for that, 1019 * so we ignore it. 1020 */ 1021 1022 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale), 1023 limit << 16); 1024 } 1025 1026 static unsigned int 1027 g4x_sprite_max_stride(struct intel_plane *plane, 1028 u32 pixel_format, u64 modifier, 1029 unsigned int rotation) 1030 { 1031 const struct drm_format_info *info = drm_format_info(pixel_format); 1032 int cpp = info->cpp[0]; 1033 1034 /* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */ 1035 if (modifier == I915_FORMAT_MOD_X_TILED) 1036 return min(4096 * cpp, 16 * 1024); 1037 else 1038 return 16 * 1024; 1039 } 1040 1041 static unsigned int 1042 hsw_sprite_max_stride(struct intel_plane *plane, 1043 u32 pixel_format, u64 modifier, 1044 unsigned int rotation) 1045 { 1046 const struct drm_format_info *info = drm_format_info(pixel_format); 1047 int cpp = info->cpp[0]; 1048 1049 /* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */ 1050 return min(8192 * cpp, 16 * 1024); 1051 } 1052 1053 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1054 { 1055 u32 dvscntr = 0; 1056 1057 if (crtc_state->gamma_enable) 1058 dvscntr |= DVS_PIPE_GAMMA_ENABLE; 1059 1060 if (crtc_state->csc_enable) 1061 dvscntr |= DVS_PIPE_CSC_ENABLE; 1062 1063 return dvscntr; 1064 } 1065 1066 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, 1067 const struct intel_plane_state *plane_state) 1068 { 1069 struct drm_i915_private *dev_priv = 1070 to_i915(plane_state->uapi.plane->dev); 1071 const struct drm_framebuffer *fb = plane_state->hw.fb; 1072 unsigned int rotation = plane_state->hw.rotation; 1073 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1074 u32 dvscntr; 1075 1076 dvscntr = DVS_ENABLE; 1077 1078 if (IS_SANDYBRIDGE(dev_priv)) 1079 dvscntr |= DVS_TRICKLE_FEED_DISABLE; 1080 1081 switch (fb->format->format) { 1082 case DRM_FORMAT_XBGR8888: 1083 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 1084 break; 1085 case DRM_FORMAT_XRGB8888: 1086 dvscntr |= DVS_FORMAT_RGBX888; 1087 break; 1088 case DRM_FORMAT_XBGR2101010: 1089 dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR; 1090 break; 1091 case DRM_FORMAT_XRGB2101010: 1092 dvscntr |= DVS_FORMAT_RGBX101010; 1093 break; 1094 case DRM_FORMAT_XBGR16161616F: 1095 dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR; 1096 break; 1097 case DRM_FORMAT_XRGB16161616F: 1098 dvscntr |= DVS_FORMAT_RGBX161616; 1099 break; 1100 case DRM_FORMAT_YUYV: 1101 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 1102 break; 1103 case DRM_FORMAT_YVYU: 1104 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 1105 break; 1106 case DRM_FORMAT_UYVY: 1107 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 1108 break; 1109 case DRM_FORMAT_VYUY: 1110 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 1111 break; 1112 default: 1113 MISSING_CASE(fb->format->format); 1114 return 0; 1115 } 1116 1117 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 1118 dvscntr |= DVS_YUV_FORMAT_BT709; 1119 1120 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1121 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE; 1122 1123 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1124 dvscntr |= DVS_TILED; 1125 1126 if (rotation & DRM_MODE_ROTATE_180) 1127 dvscntr |= DVS_ROTATE_180; 1128 1129 if (key->flags & I915_SET_COLORKEY_DESTINATION) 1130 dvscntr |= DVS_DEST_KEY; 1131 else if (key->flags & I915_SET_COLORKEY_SOURCE) 1132 dvscntr |= DVS_SOURCE_KEY; 1133 1134 return dvscntr; 1135 } 1136 1137 static void g4x_sprite_update_gamma(const struct intel_plane_state *plane_state) 1138 { 1139 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1140 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1141 const struct drm_framebuffer *fb = plane_state->hw.fb; 1142 enum pipe pipe = plane->pipe; 1143 u16 gamma[8]; 1144 int i; 1145 1146 /* Seems RGB data bypasses the gamma always */ 1147 if (!fb->format->is_yuv) 1148 return; 1149 1150 i9xx_plane_linear_gamma(gamma); 1151 1152 /* FIXME these register are single buffered :( */ 1153 /* The two end points are implicit (0.0 and 1.0) */ 1154 for (i = 1; i < 8 - 1; i++) 1155 intel_de_write_fw(dev_priv, DVSGAMC_G4X(pipe, i - 1), 1156 gamma[i] << 16 | gamma[i] << 8 | gamma[i]); 1157 } 1158 1159 static void ilk_sprite_linear_gamma(u16 gamma[17]) 1160 { 1161 int i; 1162 1163 for (i = 0; i < 17; i++) 1164 gamma[i] = (i << 10) / 16; 1165 } 1166 1167 static void ilk_sprite_update_gamma(const struct intel_plane_state *plane_state) 1168 { 1169 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1170 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1171 const struct drm_framebuffer *fb = plane_state->hw.fb; 1172 enum pipe pipe = plane->pipe; 1173 u16 gamma[17]; 1174 int i; 1175 1176 /* Seems RGB data bypasses the gamma always */ 1177 if (!fb->format->is_yuv) 1178 return; 1179 1180 ilk_sprite_linear_gamma(gamma); 1181 1182 /* FIXME these register are single buffered :( */ 1183 for (i = 0; i < 16; i++) 1184 intel_de_write_fw(dev_priv, DVSGAMC_ILK(pipe, i), 1185 gamma[i] << 20 | gamma[i] << 10 | gamma[i]); 1186 1187 intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 0), gamma[i]); 1188 intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 1), gamma[i]); 1189 intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 2), gamma[i]); 1190 i++; 1191 } 1192 1193 static void 1194 g4x_sprite_update_noarm(struct intel_plane *plane, 1195 const struct intel_crtc_state *crtc_state, 1196 const struct intel_plane_state *plane_state) 1197 { 1198 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1199 enum pipe pipe = plane->pipe; 1200 int crtc_x = plane_state->uapi.dst.x1; 1201 int crtc_y = plane_state->uapi.dst.y1; 1202 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1203 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1204 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1205 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 1206 u32 dvsscale = 0; 1207 unsigned long irqflags; 1208 1209 if (crtc_w != src_w || crtc_h != src_h) 1210 dvsscale = DVS_SCALE_ENABLE | 1211 DVS_SRC_WIDTH(src_w - 1) | 1212 DVS_SRC_HEIGHT(src_h - 1); 1213 1214 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1215 1216 intel_de_write_fw(dev_priv, DVSSTRIDE(pipe), 1217 plane_state->view.color_plane[0].mapping_stride); 1218 intel_de_write_fw(dev_priv, DVSPOS(pipe), 1219 DVS_POS_Y(crtc_y) | DVS_POS_X(crtc_x)); 1220 intel_de_write_fw(dev_priv, DVSSIZE(pipe), 1221 DVS_HEIGHT(crtc_h - 1) | DVS_WIDTH(crtc_w - 1)); 1222 intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale); 1223 1224 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1225 } 1226 1227 static void 1228 g4x_sprite_update_arm(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 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1235 u32 dvssurf_offset = plane_state->view.color_plane[0].offset; 1236 u32 x = plane_state->view.color_plane[0].x; 1237 u32 y = plane_state->view.color_plane[0].y; 1238 u32 dvscntr, linear_offset; 1239 unsigned long irqflags; 1240 1241 dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state); 1242 1243 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1244 1245 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1246 1247 if (key->flags) { 1248 intel_de_write_fw(dev_priv, DVSKEYVAL(pipe), key->min_value); 1249 intel_de_write_fw(dev_priv, DVSKEYMSK(pipe), 1250 key->channel_mask); 1251 intel_de_write_fw(dev_priv, DVSKEYMAX(pipe), key->max_value); 1252 } 1253 1254 intel_de_write_fw(dev_priv, DVSLINOFF(pipe), linear_offset); 1255 intel_de_write_fw(dev_priv, DVSTILEOFF(pipe), (y << 16) | x); 1256 1257 /* 1258 * The control register self-arms if the plane was previously 1259 * disabled. Try to make the plane enable atomic by writing 1260 * the control register just before the surface register. 1261 */ 1262 intel_de_write_fw(dev_priv, DVSCNTR(pipe), dvscntr); 1263 intel_de_write_fw(dev_priv, DVSSURF(pipe), 1264 intel_plane_ggtt_offset(plane_state) + dvssurf_offset); 1265 1266 if (IS_G4X(dev_priv)) 1267 g4x_sprite_update_gamma(plane_state); 1268 else 1269 ilk_sprite_update_gamma(plane_state); 1270 1271 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1272 } 1273 1274 static void 1275 g4x_sprite_disable_arm(struct intel_plane *plane, 1276 const struct intel_crtc_state *crtc_state) 1277 { 1278 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1279 enum pipe pipe = plane->pipe; 1280 unsigned long irqflags; 1281 1282 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1283 1284 intel_de_write_fw(dev_priv, DVSCNTR(pipe), 0); 1285 /* Disable the scaler */ 1286 intel_de_write_fw(dev_priv, DVSSCALE(pipe), 0); 1287 intel_de_write_fw(dev_priv, DVSSURF(pipe), 0); 1288 1289 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1290 } 1291 1292 static bool 1293 g4x_sprite_get_hw_state(struct intel_plane *plane, 1294 enum pipe *pipe) 1295 { 1296 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1297 enum intel_display_power_domain power_domain; 1298 intel_wakeref_t wakeref; 1299 bool ret; 1300 1301 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1302 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1303 if (!wakeref) 1304 return false; 1305 1306 ret = intel_de_read(dev_priv, DVSCNTR(plane->pipe)) & DVS_ENABLE; 1307 1308 *pipe = plane->pipe; 1309 1310 intel_display_power_put(dev_priv, power_domain, wakeref); 1311 1312 return ret; 1313 } 1314 1315 static bool g4x_fb_scalable(const struct drm_framebuffer *fb) 1316 { 1317 if (!fb) 1318 return false; 1319 1320 switch (fb->format->format) { 1321 case DRM_FORMAT_C8: 1322 case DRM_FORMAT_XRGB16161616F: 1323 case DRM_FORMAT_ARGB16161616F: 1324 case DRM_FORMAT_XBGR16161616F: 1325 case DRM_FORMAT_ABGR16161616F: 1326 return false; 1327 default: 1328 return true; 1329 } 1330 } 1331 1332 static int 1333 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state, 1334 struct intel_plane_state *plane_state) 1335 { 1336 struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); 1337 const struct drm_framebuffer *fb = plane_state->hw.fb; 1338 const struct drm_rect *src = &plane_state->uapi.src; 1339 const struct drm_rect *dst = &plane_state->uapi.dst; 1340 int src_x, src_w, src_h, crtc_w, crtc_h; 1341 const struct drm_display_mode *adjusted_mode = 1342 &crtc_state->hw.adjusted_mode; 1343 unsigned int stride = plane_state->view.color_plane[0].mapping_stride; 1344 unsigned int cpp = fb->format->cpp[0]; 1345 unsigned int width_bytes; 1346 int min_width, min_height; 1347 1348 crtc_w = drm_rect_width(dst); 1349 crtc_h = drm_rect_height(dst); 1350 1351 src_x = src->x1 >> 16; 1352 src_w = drm_rect_width(src) >> 16; 1353 src_h = drm_rect_height(src) >> 16; 1354 1355 if (src_w == crtc_w && src_h == crtc_h) 1356 return 0; 1357 1358 min_width = 3; 1359 1360 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 1361 if (src_h & 1) { 1362 drm_dbg_kms(&i915->drm, "Source height must be even with interlaced modes\n"); 1363 return -EINVAL; 1364 } 1365 min_height = 6; 1366 } else { 1367 min_height = 3; 1368 } 1369 1370 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1371 1372 if (src_w < min_width || src_h < min_height || 1373 src_w > 2048 || src_h > 2048) { 1374 drm_dbg_kms(&i915->drm, "Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n", 1375 src_w, src_h, min_width, min_height, 2048, 2048); 1376 return -EINVAL; 1377 } 1378 1379 if (width_bytes > 4096) { 1380 drm_dbg_kms(&i915->drm, "Fetch width (%d) exceeds hardware max with scaling (%u)\n", 1381 width_bytes, 4096); 1382 return -EINVAL; 1383 } 1384 1385 if (stride > 4096) { 1386 drm_dbg_kms(&i915->drm, "Stride (%u) exceeds hardware max with scaling (%u)\n", 1387 stride, 4096); 1388 return -EINVAL; 1389 } 1390 1391 return 0; 1392 } 1393 1394 static int 1395 g4x_sprite_check(struct intel_crtc_state *crtc_state, 1396 struct intel_plane_state *plane_state) 1397 { 1398 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1399 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1400 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1401 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1402 int ret; 1403 1404 if (g4x_fb_scalable(plane_state->hw.fb)) { 1405 if (DISPLAY_VER(dev_priv) < 7) { 1406 min_scale = 1; 1407 max_scale = 16 << 16; 1408 } else if (IS_IVYBRIDGE(dev_priv)) { 1409 min_scale = 1; 1410 max_scale = 2 << 16; 1411 } 1412 } 1413 1414 ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 1415 min_scale, max_scale, true); 1416 if (ret) 1417 return ret; 1418 1419 ret = i9xx_check_plane_surface(plane_state); 1420 if (ret) 1421 return ret; 1422 1423 if (!plane_state->uapi.visible) 1424 return 0; 1425 1426 ret = intel_plane_check_src_coordinates(plane_state); 1427 if (ret) 1428 return ret; 1429 1430 ret = g4x_sprite_check_scaling(crtc_state, plane_state); 1431 if (ret) 1432 return ret; 1433 1434 if (DISPLAY_VER(dev_priv) >= 7) 1435 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state); 1436 else 1437 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state); 1438 1439 return 0; 1440 } 1441 1442 int chv_plane_check_rotation(const struct intel_plane_state *plane_state) 1443 { 1444 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1445 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1446 unsigned int rotation = plane_state->hw.rotation; 1447 1448 /* CHV ignores the mirror bit when the rotate bit is set :( */ 1449 if (IS_CHERRYVIEW(dev_priv) && 1450 rotation & DRM_MODE_ROTATE_180 && 1451 rotation & DRM_MODE_REFLECT_X) { 1452 drm_dbg_kms(&dev_priv->drm, 1453 "Cannot rotate and reflect at the same time\n"); 1454 return -EINVAL; 1455 } 1456 1457 return 0; 1458 } 1459 1460 static int 1461 vlv_sprite_check(struct intel_crtc_state *crtc_state, 1462 struct intel_plane_state *plane_state) 1463 { 1464 int ret; 1465 1466 ret = chv_plane_check_rotation(plane_state); 1467 if (ret) 1468 return ret; 1469 1470 ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 1471 DRM_PLANE_HELPER_NO_SCALING, 1472 DRM_PLANE_HELPER_NO_SCALING, 1473 true); 1474 if (ret) 1475 return ret; 1476 1477 ret = i9xx_check_plane_surface(plane_state); 1478 if (ret) 1479 return ret; 1480 1481 if (!plane_state->uapi.visible) 1482 return 0; 1483 1484 ret = intel_plane_check_src_coordinates(plane_state); 1485 if (ret) 1486 return ret; 1487 1488 plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state); 1489 1490 return 0; 1491 } 1492 1493 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv) 1494 { 1495 return DISPLAY_VER(dev_priv) >= 9; 1496 } 1497 1498 static void intel_plane_set_ckey(struct intel_plane_state *plane_state, 1499 const struct drm_intel_sprite_colorkey *set) 1500 { 1501 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1502 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1503 struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1504 1505 *key = *set; 1506 1507 /* 1508 * We want src key enabled on the 1509 * sprite and not on the primary. 1510 */ 1511 if (plane->id == PLANE_PRIMARY && 1512 set->flags & I915_SET_COLORKEY_SOURCE) 1513 key->flags = 0; 1514 1515 /* 1516 * On SKL+ we want dst key enabled on 1517 * the primary and not on the sprite. 1518 */ 1519 if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_PRIMARY && 1520 set->flags & I915_SET_COLORKEY_DESTINATION) 1521 key->flags = 0; 1522 } 1523 1524 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, 1525 struct drm_file *file_priv) 1526 { 1527 struct drm_i915_private *dev_priv = to_i915(dev); 1528 struct drm_intel_sprite_colorkey *set = data; 1529 struct drm_plane *plane; 1530 struct drm_plane_state *plane_state; 1531 struct drm_atomic_state *state; 1532 struct drm_modeset_acquire_ctx ctx; 1533 int ret = 0; 1534 1535 /* ignore the pointless "none" flag */ 1536 set->flags &= ~I915_SET_COLORKEY_NONE; 1537 1538 if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1539 return -EINVAL; 1540 1541 /* Make sure we don't try to enable both src & dest simultaneously */ 1542 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1543 return -EINVAL; 1544 1545 if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 1546 set->flags & I915_SET_COLORKEY_DESTINATION) 1547 return -EINVAL; 1548 1549 plane = drm_plane_find(dev, file_priv, set->plane_id); 1550 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) 1551 return -ENOENT; 1552 1553 /* 1554 * SKL+ only plane 2 can do destination keying against plane 1. 1555 * Also multiple planes can't do destination keying on the same 1556 * pipe simultaneously. 1557 */ 1558 if (DISPLAY_VER(dev_priv) >= 9 && 1559 to_intel_plane(plane)->id >= PLANE_SPRITE1 && 1560 set->flags & I915_SET_COLORKEY_DESTINATION) 1561 return -EINVAL; 1562 1563 drm_modeset_acquire_init(&ctx, 0); 1564 1565 state = drm_atomic_state_alloc(plane->dev); 1566 if (!state) { 1567 ret = -ENOMEM; 1568 goto out; 1569 } 1570 state->acquire_ctx = &ctx; 1571 1572 while (1) { 1573 plane_state = drm_atomic_get_plane_state(state, plane); 1574 ret = PTR_ERR_OR_ZERO(plane_state); 1575 if (!ret) 1576 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 1577 1578 /* 1579 * On some platforms we have to configure 1580 * the dst colorkey on the primary plane. 1581 */ 1582 if (!ret && has_dst_key_in_primary_plane(dev_priv)) { 1583 struct intel_crtc *crtc = 1584 intel_crtc_for_pipe(dev_priv, 1585 to_intel_plane(plane)->pipe); 1586 1587 plane_state = drm_atomic_get_plane_state(state, 1588 crtc->base.primary); 1589 ret = PTR_ERR_OR_ZERO(plane_state); 1590 if (!ret) 1591 intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 1592 } 1593 1594 if (!ret) 1595 ret = drm_atomic_commit(state); 1596 1597 if (ret != -EDEADLK) 1598 break; 1599 1600 drm_atomic_state_clear(state); 1601 drm_modeset_backoff(&ctx); 1602 } 1603 1604 drm_atomic_state_put(state); 1605 out: 1606 drm_modeset_drop_locks(&ctx); 1607 drm_modeset_acquire_fini(&ctx); 1608 return ret; 1609 } 1610 1611 static const u32 g4x_sprite_formats[] = { 1612 DRM_FORMAT_XRGB8888, 1613 DRM_FORMAT_YUYV, 1614 DRM_FORMAT_YVYU, 1615 DRM_FORMAT_UYVY, 1616 DRM_FORMAT_VYUY, 1617 }; 1618 1619 static const u32 snb_sprite_formats[] = { 1620 DRM_FORMAT_XRGB8888, 1621 DRM_FORMAT_XBGR8888, 1622 DRM_FORMAT_XRGB2101010, 1623 DRM_FORMAT_XBGR2101010, 1624 DRM_FORMAT_XRGB16161616F, 1625 DRM_FORMAT_XBGR16161616F, 1626 DRM_FORMAT_YUYV, 1627 DRM_FORMAT_YVYU, 1628 DRM_FORMAT_UYVY, 1629 DRM_FORMAT_VYUY, 1630 }; 1631 1632 static const u32 vlv_sprite_formats[] = { 1633 DRM_FORMAT_C8, 1634 DRM_FORMAT_RGB565, 1635 DRM_FORMAT_XRGB8888, 1636 DRM_FORMAT_XBGR8888, 1637 DRM_FORMAT_ARGB8888, 1638 DRM_FORMAT_ABGR8888, 1639 DRM_FORMAT_XBGR2101010, 1640 DRM_FORMAT_ABGR2101010, 1641 DRM_FORMAT_YUYV, 1642 DRM_FORMAT_YVYU, 1643 DRM_FORMAT_UYVY, 1644 DRM_FORMAT_VYUY, 1645 }; 1646 1647 static const u32 chv_pipe_b_sprite_formats[] = { 1648 DRM_FORMAT_C8, 1649 DRM_FORMAT_RGB565, 1650 DRM_FORMAT_XRGB8888, 1651 DRM_FORMAT_XBGR8888, 1652 DRM_FORMAT_ARGB8888, 1653 DRM_FORMAT_ABGR8888, 1654 DRM_FORMAT_XRGB2101010, 1655 DRM_FORMAT_XBGR2101010, 1656 DRM_FORMAT_ARGB2101010, 1657 DRM_FORMAT_ABGR2101010, 1658 DRM_FORMAT_YUYV, 1659 DRM_FORMAT_YVYU, 1660 DRM_FORMAT_UYVY, 1661 DRM_FORMAT_VYUY, 1662 }; 1663 1664 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane, 1665 u32 format, u64 modifier) 1666 { 1667 if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier)) 1668 return false; 1669 1670 switch (format) { 1671 case DRM_FORMAT_XRGB8888: 1672 case DRM_FORMAT_YUYV: 1673 case DRM_FORMAT_YVYU: 1674 case DRM_FORMAT_UYVY: 1675 case DRM_FORMAT_VYUY: 1676 if (modifier == DRM_FORMAT_MOD_LINEAR || 1677 modifier == I915_FORMAT_MOD_X_TILED) 1678 return true; 1679 fallthrough; 1680 default: 1681 return false; 1682 } 1683 } 1684 1685 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane, 1686 u32 format, u64 modifier) 1687 { 1688 if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier)) 1689 return false; 1690 1691 switch (format) { 1692 case DRM_FORMAT_XRGB8888: 1693 case DRM_FORMAT_XBGR8888: 1694 case DRM_FORMAT_XRGB2101010: 1695 case DRM_FORMAT_XBGR2101010: 1696 case DRM_FORMAT_XRGB16161616F: 1697 case DRM_FORMAT_XBGR16161616F: 1698 case DRM_FORMAT_YUYV: 1699 case DRM_FORMAT_YVYU: 1700 case DRM_FORMAT_UYVY: 1701 case DRM_FORMAT_VYUY: 1702 if (modifier == DRM_FORMAT_MOD_LINEAR || 1703 modifier == I915_FORMAT_MOD_X_TILED) 1704 return true; 1705 fallthrough; 1706 default: 1707 return false; 1708 } 1709 } 1710 1711 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane, 1712 u32 format, u64 modifier) 1713 { 1714 if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier)) 1715 return false; 1716 1717 switch (format) { 1718 case DRM_FORMAT_C8: 1719 case DRM_FORMAT_RGB565: 1720 case DRM_FORMAT_ABGR8888: 1721 case DRM_FORMAT_ARGB8888: 1722 case DRM_FORMAT_XBGR8888: 1723 case DRM_FORMAT_XRGB8888: 1724 case DRM_FORMAT_XBGR2101010: 1725 case DRM_FORMAT_ABGR2101010: 1726 case DRM_FORMAT_XRGB2101010: 1727 case DRM_FORMAT_ARGB2101010: 1728 case DRM_FORMAT_YUYV: 1729 case DRM_FORMAT_YVYU: 1730 case DRM_FORMAT_UYVY: 1731 case DRM_FORMAT_VYUY: 1732 if (modifier == DRM_FORMAT_MOD_LINEAR || 1733 modifier == I915_FORMAT_MOD_X_TILED) 1734 return true; 1735 fallthrough; 1736 default: 1737 return false; 1738 } 1739 } 1740 1741 static const struct drm_plane_funcs g4x_sprite_funcs = { 1742 .update_plane = drm_atomic_helper_update_plane, 1743 .disable_plane = drm_atomic_helper_disable_plane, 1744 .destroy = intel_plane_destroy, 1745 .atomic_duplicate_state = intel_plane_duplicate_state, 1746 .atomic_destroy_state = intel_plane_destroy_state, 1747 .format_mod_supported = g4x_sprite_format_mod_supported, 1748 }; 1749 1750 static const struct drm_plane_funcs snb_sprite_funcs = { 1751 .update_plane = drm_atomic_helper_update_plane, 1752 .disable_plane = drm_atomic_helper_disable_plane, 1753 .destroy = intel_plane_destroy, 1754 .atomic_duplicate_state = intel_plane_duplicate_state, 1755 .atomic_destroy_state = intel_plane_destroy_state, 1756 .format_mod_supported = snb_sprite_format_mod_supported, 1757 }; 1758 1759 static const struct drm_plane_funcs vlv_sprite_funcs = { 1760 .update_plane = drm_atomic_helper_update_plane, 1761 .disable_plane = drm_atomic_helper_disable_plane, 1762 .destroy = intel_plane_destroy, 1763 .atomic_duplicate_state = intel_plane_duplicate_state, 1764 .atomic_destroy_state = intel_plane_destroy_state, 1765 .format_mod_supported = vlv_sprite_format_mod_supported, 1766 }; 1767 1768 struct intel_plane * 1769 intel_sprite_plane_create(struct drm_i915_private *dev_priv, 1770 enum pipe pipe, int sprite) 1771 { 1772 struct intel_plane *plane; 1773 const struct drm_plane_funcs *plane_funcs; 1774 unsigned int supported_rotations; 1775 const u64 *modifiers; 1776 const u32 *formats; 1777 int num_formats; 1778 int ret, zpos; 1779 1780 plane = intel_plane_alloc(); 1781 if (IS_ERR(plane)) 1782 return plane; 1783 1784 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 1785 plane->update_noarm = vlv_sprite_update_noarm; 1786 plane->update_arm = vlv_sprite_update_arm; 1787 plane->disable_arm = vlv_sprite_disable_arm; 1788 plane->get_hw_state = vlv_sprite_get_hw_state; 1789 plane->check_plane = vlv_sprite_check; 1790 plane->max_stride = i965_plane_max_stride; 1791 plane->min_cdclk = vlv_plane_min_cdclk; 1792 1793 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 1794 formats = chv_pipe_b_sprite_formats; 1795 num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats); 1796 } else { 1797 formats = vlv_sprite_formats; 1798 num_formats = ARRAY_SIZE(vlv_sprite_formats); 1799 } 1800 1801 plane_funcs = &vlv_sprite_funcs; 1802 } else if (DISPLAY_VER(dev_priv) >= 7) { 1803 plane->update_noarm = ivb_sprite_update_noarm; 1804 plane->update_arm = ivb_sprite_update_arm; 1805 plane->disable_arm = ivb_sprite_disable_arm; 1806 plane->get_hw_state = ivb_sprite_get_hw_state; 1807 plane->check_plane = g4x_sprite_check; 1808 1809 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { 1810 plane->max_stride = hsw_sprite_max_stride; 1811 plane->min_cdclk = hsw_plane_min_cdclk; 1812 } else { 1813 plane->max_stride = g4x_sprite_max_stride; 1814 plane->min_cdclk = ivb_sprite_min_cdclk; 1815 } 1816 1817 formats = snb_sprite_formats; 1818 num_formats = ARRAY_SIZE(snb_sprite_formats); 1819 1820 plane_funcs = &snb_sprite_funcs; 1821 } else { 1822 plane->update_noarm = g4x_sprite_update_noarm; 1823 plane->update_arm = g4x_sprite_update_arm; 1824 plane->disable_arm = g4x_sprite_disable_arm; 1825 plane->get_hw_state = g4x_sprite_get_hw_state; 1826 plane->check_plane = g4x_sprite_check; 1827 plane->max_stride = g4x_sprite_max_stride; 1828 plane->min_cdclk = g4x_sprite_min_cdclk; 1829 1830 if (IS_SANDYBRIDGE(dev_priv)) { 1831 formats = snb_sprite_formats; 1832 num_formats = ARRAY_SIZE(snb_sprite_formats); 1833 1834 plane_funcs = &snb_sprite_funcs; 1835 } else { 1836 formats = g4x_sprite_formats; 1837 num_formats = ARRAY_SIZE(g4x_sprite_formats); 1838 1839 plane_funcs = &g4x_sprite_funcs; 1840 } 1841 } 1842 1843 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 1844 supported_rotations = 1845 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 1846 DRM_MODE_REFLECT_X; 1847 } else { 1848 supported_rotations = 1849 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 1850 } 1851 1852 plane->pipe = pipe; 1853 plane->id = PLANE_SPRITE0 + sprite; 1854 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 1855 1856 modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X); 1857 1858 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 1859 0, plane_funcs, 1860 formats, num_formats, modifiers, 1861 DRM_PLANE_TYPE_OVERLAY, 1862 "sprite %c", sprite_name(pipe, sprite)); 1863 kfree(modifiers); 1864 1865 if (ret) 1866 goto fail; 1867 1868 drm_plane_create_rotation_property(&plane->base, 1869 DRM_MODE_ROTATE_0, 1870 supported_rotations); 1871 1872 drm_plane_create_color_properties(&plane->base, 1873 BIT(DRM_COLOR_YCBCR_BT601) | 1874 BIT(DRM_COLOR_YCBCR_BT709), 1875 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 1876 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 1877 DRM_COLOR_YCBCR_BT709, 1878 DRM_COLOR_YCBCR_LIMITED_RANGE); 1879 1880 zpos = sprite + 1; 1881 drm_plane_create_zpos_immutable_property(&plane->base, zpos); 1882 1883 intel_plane_helper_add(plane); 1884 1885 return plane; 1886 1887 fail: 1888 intel_plane_free(plane); 1889 1890 return ERR_PTR(ret); 1891 } 1892