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