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