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