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