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