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