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