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