1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2020 Intel Corporation 4 */ 5 #include <linux/kernel.h> 6 7 #include <drm/drm_atomic_helper.h> 8 #include <drm/drm_fourcc.h> 9 #include <drm/drm_plane_helper.h> 10 11 #include "intel_atomic.h" 12 #include "intel_atomic_plane.h" 13 #include "intel_de.h" 14 #include "intel_display_types.h" 15 #include "intel_fb.h" 16 #include "intel_sprite.h" 17 #include "i9xx_plane.h" 18 19 /* Primary plane formats for gen <= 3 */ 20 static const u32 i8xx_primary_formats[] = { 21 DRM_FORMAT_C8, 22 DRM_FORMAT_XRGB1555, 23 DRM_FORMAT_RGB565, 24 DRM_FORMAT_XRGB8888, 25 }; 26 27 /* Primary plane formats for ivb (no fp16 due to hw issue) */ 28 static const u32 ivb_primary_formats[] = { 29 DRM_FORMAT_C8, 30 DRM_FORMAT_RGB565, 31 DRM_FORMAT_XRGB8888, 32 DRM_FORMAT_XBGR8888, 33 DRM_FORMAT_XRGB2101010, 34 DRM_FORMAT_XBGR2101010, 35 }; 36 37 /* Primary plane formats for gen >= 4, except ivb */ 38 static const u32 i965_primary_formats[] = { 39 DRM_FORMAT_C8, 40 DRM_FORMAT_RGB565, 41 DRM_FORMAT_XRGB8888, 42 DRM_FORMAT_XBGR8888, 43 DRM_FORMAT_XRGB2101010, 44 DRM_FORMAT_XBGR2101010, 45 DRM_FORMAT_XBGR16161616F, 46 }; 47 48 /* Primary plane formats for vlv/chv */ 49 static const u32 vlv_primary_formats[] = { 50 DRM_FORMAT_C8, 51 DRM_FORMAT_RGB565, 52 DRM_FORMAT_XRGB8888, 53 DRM_FORMAT_XBGR8888, 54 DRM_FORMAT_ARGB8888, 55 DRM_FORMAT_ABGR8888, 56 DRM_FORMAT_XRGB2101010, 57 DRM_FORMAT_XBGR2101010, 58 DRM_FORMAT_ARGB2101010, 59 DRM_FORMAT_ABGR2101010, 60 DRM_FORMAT_XBGR16161616F, 61 }; 62 63 static const u64 i9xx_format_modifiers[] = { 64 I915_FORMAT_MOD_X_TILED, 65 DRM_FORMAT_MOD_LINEAR, 66 DRM_FORMAT_MOD_INVALID 67 }; 68 69 static bool i8xx_plane_format_mod_supported(struct drm_plane *_plane, 70 u32 format, u64 modifier) 71 { 72 switch (modifier) { 73 case DRM_FORMAT_MOD_LINEAR: 74 case I915_FORMAT_MOD_X_TILED: 75 break; 76 default: 77 return false; 78 } 79 80 switch (format) { 81 case DRM_FORMAT_C8: 82 case DRM_FORMAT_RGB565: 83 case DRM_FORMAT_XRGB1555: 84 case DRM_FORMAT_XRGB8888: 85 return modifier == DRM_FORMAT_MOD_LINEAR || 86 modifier == I915_FORMAT_MOD_X_TILED; 87 default: 88 return false; 89 } 90 } 91 92 static bool i965_plane_format_mod_supported(struct drm_plane *_plane, 93 u32 format, u64 modifier) 94 { 95 switch (modifier) { 96 case DRM_FORMAT_MOD_LINEAR: 97 case I915_FORMAT_MOD_X_TILED: 98 break; 99 default: 100 return false; 101 } 102 103 switch (format) { 104 case DRM_FORMAT_C8: 105 case DRM_FORMAT_RGB565: 106 case DRM_FORMAT_XRGB8888: 107 case DRM_FORMAT_XBGR8888: 108 case DRM_FORMAT_ARGB8888: 109 case DRM_FORMAT_ABGR8888: 110 case DRM_FORMAT_XRGB2101010: 111 case DRM_FORMAT_XBGR2101010: 112 case DRM_FORMAT_ARGB2101010: 113 case DRM_FORMAT_ABGR2101010: 114 case DRM_FORMAT_XBGR16161616F: 115 return modifier == DRM_FORMAT_MOD_LINEAR || 116 modifier == I915_FORMAT_MOD_X_TILED; 117 default: 118 return false; 119 } 120 } 121 122 static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv, 123 enum i9xx_plane_id i9xx_plane) 124 { 125 if (!HAS_FBC(dev_priv)) 126 return false; 127 128 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) 129 return i9xx_plane == PLANE_A; /* tied to pipe A */ 130 else if (IS_IVYBRIDGE(dev_priv)) 131 return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B || 132 i9xx_plane == PLANE_C; 133 else if (DISPLAY_VER(dev_priv) >= 4) 134 return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B; 135 else 136 return i9xx_plane == PLANE_A; 137 } 138 139 static bool i9xx_plane_has_windowing(struct intel_plane *plane) 140 { 141 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 142 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 143 144 if (IS_CHERRYVIEW(dev_priv)) 145 return i9xx_plane == PLANE_B; 146 else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) 147 return false; 148 else if (DISPLAY_VER(dev_priv) == 4) 149 return i9xx_plane == PLANE_C; 150 else 151 return i9xx_plane == PLANE_B || 152 i9xx_plane == PLANE_C; 153 } 154 155 static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, 156 const struct intel_plane_state *plane_state) 157 { 158 struct drm_i915_private *dev_priv = 159 to_i915(plane_state->uapi.plane->dev); 160 const struct drm_framebuffer *fb = plane_state->hw.fb; 161 unsigned int rotation = plane_state->hw.rotation; 162 u32 dspcntr; 163 164 dspcntr = DISPLAY_PLANE_ENABLE; 165 166 if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) || 167 IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) 168 dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; 169 170 switch (fb->format->format) { 171 case DRM_FORMAT_C8: 172 dspcntr |= DISPPLANE_8BPP; 173 break; 174 case DRM_FORMAT_XRGB1555: 175 dspcntr |= DISPPLANE_BGRX555; 176 break; 177 case DRM_FORMAT_ARGB1555: 178 dspcntr |= DISPPLANE_BGRA555; 179 break; 180 case DRM_FORMAT_RGB565: 181 dspcntr |= DISPPLANE_BGRX565; 182 break; 183 case DRM_FORMAT_XRGB8888: 184 dspcntr |= DISPPLANE_BGRX888; 185 break; 186 case DRM_FORMAT_XBGR8888: 187 dspcntr |= DISPPLANE_RGBX888; 188 break; 189 case DRM_FORMAT_ARGB8888: 190 dspcntr |= DISPPLANE_BGRA888; 191 break; 192 case DRM_FORMAT_ABGR8888: 193 dspcntr |= DISPPLANE_RGBA888; 194 break; 195 case DRM_FORMAT_XRGB2101010: 196 dspcntr |= DISPPLANE_BGRX101010; 197 break; 198 case DRM_FORMAT_XBGR2101010: 199 dspcntr |= DISPPLANE_RGBX101010; 200 break; 201 case DRM_FORMAT_ARGB2101010: 202 dspcntr |= DISPPLANE_BGRA101010; 203 break; 204 case DRM_FORMAT_ABGR2101010: 205 dspcntr |= DISPPLANE_RGBA101010; 206 break; 207 case DRM_FORMAT_XBGR16161616F: 208 dspcntr |= DISPPLANE_RGBX161616; 209 break; 210 default: 211 MISSING_CASE(fb->format->format); 212 return 0; 213 } 214 215 if (DISPLAY_VER(dev_priv) >= 4 && 216 fb->modifier == I915_FORMAT_MOD_X_TILED) 217 dspcntr |= DISPPLANE_TILED; 218 219 if (rotation & DRM_MODE_ROTATE_180) 220 dspcntr |= DISPPLANE_ROTATE_180; 221 222 if (rotation & DRM_MODE_REFLECT_X) 223 dspcntr |= DISPPLANE_MIRROR; 224 225 return dspcntr; 226 } 227 228 int i9xx_check_plane_surface(struct intel_plane_state *plane_state) 229 { 230 struct drm_i915_private *dev_priv = 231 to_i915(plane_state->uapi.plane->dev); 232 const struct drm_framebuffer *fb = plane_state->hw.fb; 233 int src_x, src_y, src_w; 234 u32 offset; 235 int ret; 236 237 ret = intel_plane_compute_gtt(plane_state); 238 if (ret) 239 return ret; 240 241 if (!plane_state->uapi.visible) 242 return 0; 243 244 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 245 src_x = plane_state->uapi.src.x1 >> 16; 246 src_y = plane_state->uapi.src.y1 >> 16; 247 248 /* Undocumented hardware limit on i965/g4x/vlv/chv */ 249 if (HAS_GMCH(dev_priv) && fb->format->cpp[0] == 8 && src_w > 2048) 250 return -EINVAL; 251 252 intel_add_fb_offsets(&src_x, &src_y, plane_state, 0); 253 254 if (DISPLAY_VER(dev_priv) >= 4) 255 offset = intel_plane_compute_aligned_offset(&src_x, &src_y, 256 plane_state, 0); 257 else 258 offset = 0; 259 260 /* 261 * When using an X-tiled surface the plane starts to 262 * misbehave if the x offset + width exceeds the stride. 263 * hsw/bdw: underrun galore 264 * ilk/snb/ivb: wrap to the next tile row mid scanout 265 * i965/g4x: so far appear immune to this 266 * vlv/chv: TODO check 267 * 268 * Linear surfaces seem to work just fine, even on hsw/bdw 269 * despite them not using the linear offset anymore. 270 */ 271 if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) { 272 u32 alignment = intel_surf_alignment(fb, 0); 273 int cpp = fb->format->cpp[0]; 274 275 while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].stride) { 276 if (offset == 0) { 277 drm_dbg_kms(&dev_priv->drm, 278 "Unable to find suitable display surface offset due to X-tiling\n"); 279 return -EINVAL; 280 } 281 282 offset = intel_plane_adjust_aligned_offset(&src_x, &src_y, plane_state, 0, 283 offset, offset - alignment); 284 } 285 } 286 287 /* 288 * Put the final coordinates back so that the src 289 * coordinate checks will see the right values. 290 */ 291 drm_rect_translate_to(&plane_state->uapi.src, 292 src_x << 16, src_y << 16); 293 294 /* HSW/BDW do this automagically in hardware */ 295 if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { 296 unsigned int rotation = plane_state->hw.rotation; 297 int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 298 int src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 299 300 if (rotation & DRM_MODE_ROTATE_180) { 301 src_x += src_w - 1; 302 src_y += src_h - 1; 303 } else if (rotation & DRM_MODE_REFLECT_X) { 304 src_x += src_w - 1; 305 } 306 } 307 308 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 309 drm_WARN_ON(&dev_priv->drm, src_x > 8191 || src_y > 4095); 310 } else if (DISPLAY_VER(dev_priv) >= 4 && 311 fb->modifier == I915_FORMAT_MOD_X_TILED) { 312 drm_WARN_ON(&dev_priv->drm, src_x > 4095 || src_y > 4095); 313 } 314 315 plane_state->view.color_plane[0].offset = offset; 316 plane_state->view.color_plane[0].x = src_x; 317 plane_state->view.color_plane[0].y = src_y; 318 319 return 0; 320 } 321 322 static int 323 i9xx_plane_check(struct intel_crtc_state *crtc_state, 324 struct intel_plane_state *plane_state) 325 { 326 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 327 int ret; 328 329 ret = chv_plane_check_rotation(plane_state); 330 if (ret) 331 return ret; 332 333 ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 334 DRM_PLANE_HELPER_NO_SCALING, 335 DRM_PLANE_HELPER_NO_SCALING, 336 i9xx_plane_has_windowing(plane)); 337 if (ret) 338 return ret; 339 340 ret = i9xx_check_plane_surface(plane_state); 341 if (ret) 342 return ret; 343 344 if (!plane_state->uapi.visible) 345 return 0; 346 347 ret = intel_plane_check_src_coordinates(plane_state); 348 if (ret) 349 return ret; 350 351 plane_state->ctl = i9xx_plane_ctl(crtc_state, plane_state); 352 353 return 0; 354 } 355 356 static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) 357 { 358 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 359 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 360 u32 dspcntr = 0; 361 362 if (crtc_state->gamma_enable) 363 dspcntr |= DISPPLANE_GAMMA_ENABLE; 364 365 if (crtc_state->csc_enable) 366 dspcntr |= DISPPLANE_PIPE_CSC_ENABLE; 367 368 if (DISPLAY_VER(dev_priv) < 5) 369 dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe); 370 371 return dspcntr; 372 } 373 374 static void i9xx_plane_ratio(const struct intel_crtc_state *crtc_state, 375 const struct intel_plane_state *plane_state, 376 unsigned int *num, unsigned int *den) 377 { 378 const struct drm_framebuffer *fb = plane_state->hw.fb; 379 unsigned int cpp = fb->format->cpp[0]; 380 381 /* 382 * g4x bspec says 64bpp pixel rate can't exceed 80% 383 * of cdclk when the sprite plane is enabled on the 384 * same pipe. ilk/snb bspec says 64bpp pixel rate is 385 * never allowed to exceed 80% of cdclk. Let's just go 386 * with the ilk/snb limit always. 387 */ 388 if (cpp == 8) { 389 *num = 10; 390 *den = 8; 391 } else { 392 *num = 1; 393 *den = 1; 394 } 395 } 396 397 static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 398 const struct intel_plane_state *plane_state) 399 { 400 unsigned int pixel_rate; 401 unsigned int num, den; 402 403 /* 404 * Note that crtc_state->pixel_rate accounts for both 405 * horizontal and vertical panel fitter downscaling factors. 406 * Pre-HSW bspec tells us to only consider the horizontal 407 * downscaling factor here. We ignore that and just consider 408 * both for simplicity. 409 */ 410 pixel_rate = crtc_state->pixel_rate; 411 412 i9xx_plane_ratio(crtc_state, plane_state, &num, &den); 413 414 /* two pixels per clock with double wide pipe */ 415 if (crtc_state->double_wide) 416 den *= 2; 417 418 return DIV_ROUND_UP(pixel_rate * num, den); 419 } 420 421 static void i9xx_update_plane(struct intel_plane *plane, 422 const struct intel_crtc_state *crtc_state, 423 const struct intel_plane_state *plane_state) 424 { 425 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 426 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 427 u32 linear_offset; 428 int x = plane_state->view.color_plane[0].x; 429 int y = plane_state->view.color_plane[0].y; 430 int crtc_x = plane_state->uapi.dst.x1; 431 int crtc_y = plane_state->uapi.dst.y1; 432 int crtc_w = drm_rect_width(&plane_state->uapi.dst); 433 int crtc_h = drm_rect_height(&plane_state->uapi.dst); 434 unsigned long irqflags; 435 u32 dspaddr_offset; 436 u32 dspcntr; 437 438 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state); 439 440 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 441 442 if (DISPLAY_VER(dev_priv) >= 4) 443 dspaddr_offset = plane_state->view.color_plane[0].offset; 444 else 445 dspaddr_offset = linear_offset; 446 447 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 448 449 intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane), 450 plane_state->view.color_plane[0].stride); 451 452 if (DISPLAY_VER(dev_priv) < 4) { 453 /* 454 * PLANE_A doesn't actually have a full window 455 * generator but let's assume we still need to 456 * program whatever is there. 457 */ 458 intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane), 459 (crtc_y << 16) | crtc_x); 460 intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane), 461 ((crtc_h - 1) << 16) | (crtc_w - 1)); 462 } else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) { 463 intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane), 464 (crtc_y << 16) | crtc_x); 465 intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane), 466 ((crtc_h - 1) << 16) | (crtc_w - 1)); 467 intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0); 468 } 469 470 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 471 intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane), 472 (y << 16) | x); 473 } else if (DISPLAY_VER(dev_priv) >= 4) { 474 intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane), 475 linear_offset); 476 intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane), 477 (y << 16) | x); 478 } 479 480 /* 481 * The control register self-arms if the plane was previously 482 * disabled. Try to make the plane enable atomic by writing 483 * the control register just before the surface register. 484 */ 485 intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr); 486 if (DISPLAY_VER(dev_priv) >= 4) 487 intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 488 intel_plane_ggtt_offset(plane_state) + dspaddr_offset); 489 else 490 intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 491 intel_plane_ggtt_offset(plane_state) + dspaddr_offset); 492 493 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 494 } 495 496 static void i9xx_disable_plane(struct intel_plane *plane, 497 const struct intel_crtc_state *crtc_state) 498 { 499 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 500 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 501 unsigned long irqflags; 502 u32 dspcntr; 503 504 /* 505 * DSPCNTR pipe gamma enable on g4x+ and pipe csc 506 * enable on ilk+ affect the pipe bottom color as 507 * well, so we must configure them even if the plane 508 * is disabled. 509 * 510 * On pre-g4x there is no way to gamma correct the 511 * pipe bottom color but we'll keep on doing this 512 * anyway so that the crtc state readout works correctly. 513 */ 514 dspcntr = i9xx_plane_ctl_crtc(crtc_state); 515 516 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 517 518 intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr); 519 if (DISPLAY_VER(dev_priv) >= 4) 520 intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 0); 521 else 522 intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0); 523 524 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 525 } 526 527 static void 528 g4x_primary_async_flip(struct intel_plane *plane, 529 const struct intel_crtc_state *crtc_state, 530 const struct intel_plane_state *plane_state, 531 bool async_flip) 532 { 533 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 534 u32 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state); 535 u32 dspaddr_offset = plane_state->view.color_plane[0].offset; 536 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 537 unsigned long irqflags; 538 539 if (async_flip) 540 dspcntr |= DISPPLANE_ASYNC_FLIP; 541 542 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 543 intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr); 544 intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 545 intel_plane_ggtt_offset(plane_state) + dspaddr_offset); 546 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 547 } 548 549 static void 550 vlv_primary_async_flip(struct intel_plane *plane, 551 const struct intel_crtc_state *crtc_state, 552 const struct intel_plane_state *plane_state, 553 bool async_flip) 554 { 555 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 556 u32 dspaddr_offset = plane_state->view.color_plane[0].offset; 557 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 558 unsigned long irqflags; 559 560 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 561 intel_de_write_fw(dev_priv, DSPADDR_VLV(i9xx_plane), 562 intel_plane_ggtt_offset(plane_state) + dspaddr_offset); 563 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 564 } 565 566 static void 567 bdw_primary_enable_flip_done(struct intel_plane *plane) 568 { 569 struct drm_i915_private *i915 = to_i915(plane->base.dev); 570 enum pipe pipe = plane->pipe; 571 572 spin_lock_irq(&i915->irq_lock); 573 bdw_enable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); 574 spin_unlock_irq(&i915->irq_lock); 575 } 576 577 static void 578 bdw_primary_disable_flip_done(struct intel_plane *plane) 579 { 580 struct drm_i915_private *i915 = to_i915(plane->base.dev); 581 enum pipe pipe = plane->pipe; 582 583 spin_lock_irq(&i915->irq_lock); 584 bdw_disable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); 585 spin_unlock_irq(&i915->irq_lock); 586 } 587 588 static void 589 ivb_primary_enable_flip_done(struct intel_plane *plane) 590 { 591 struct drm_i915_private *i915 = to_i915(plane->base.dev); 592 593 spin_lock_irq(&i915->irq_lock); 594 ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); 595 spin_unlock_irq(&i915->irq_lock); 596 } 597 598 static void 599 ivb_primary_disable_flip_done(struct intel_plane *plane) 600 { 601 struct drm_i915_private *i915 = to_i915(plane->base.dev); 602 603 spin_lock_irq(&i915->irq_lock); 604 ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); 605 spin_unlock_irq(&i915->irq_lock); 606 } 607 608 static void 609 ilk_primary_enable_flip_done(struct intel_plane *plane) 610 { 611 struct drm_i915_private *i915 = to_i915(plane->base.dev); 612 613 spin_lock_irq(&i915->irq_lock); 614 ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); 615 spin_unlock_irq(&i915->irq_lock); 616 } 617 618 static void 619 ilk_primary_disable_flip_done(struct intel_plane *plane) 620 { 621 struct drm_i915_private *i915 = to_i915(plane->base.dev); 622 623 spin_lock_irq(&i915->irq_lock); 624 ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); 625 spin_unlock_irq(&i915->irq_lock); 626 } 627 628 static void 629 vlv_primary_enable_flip_done(struct intel_plane *plane) 630 { 631 struct drm_i915_private *i915 = to_i915(plane->base.dev); 632 enum pipe pipe = plane->pipe; 633 634 spin_lock_irq(&i915->irq_lock); 635 i915_enable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); 636 spin_unlock_irq(&i915->irq_lock); 637 } 638 639 static void 640 vlv_primary_disable_flip_done(struct intel_plane *plane) 641 { 642 struct drm_i915_private *i915 = to_i915(plane->base.dev); 643 enum pipe pipe = plane->pipe; 644 645 spin_lock_irq(&i915->irq_lock); 646 i915_disable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); 647 spin_unlock_irq(&i915->irq_lock); 648 } 649 650 static bool i9xx_plane_get_hw_state(struct intel_plane *plane, 651 enum pipe *pipe) 652 { 653 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 654 enum intel_display_power_domain power_domain; 655 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 656 intel_wakeref_t wakeref; 657 bool ret; 658 u32 val; 659 660 /* 661 * Not 100% correct for planes that can move between pipes, 662 * but that's only the case for gen2-4 which don't have any 663 * display power wells. 664 */ 665 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 666 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 667 if (!wakeref) 668 return false; 669 670 val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane)); 671 672 ret = val & DISPLAY_PLANE_ENABLE; 673 674 if (DISPLAY_VER(dev_priv) >= 5) 675 *pipe = plane->pipe; 676 else 677 *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> 678 DISPPLANE_SEL_PIPE_SHIFT; 679 680 intel_display_power_put(dev_priv, power_domain, wakeref); 681 682 return ret; 683 } 684 685 static unsigned int 686 hsw_primary_max_stride(struct intel_plane *plane, 687 u32 pixel_format, u64 modifier, 688 unsigned int rotation) 689 { 690 const struct drm_format_info *info = drm_format_info(pixel_format); 691 int cpp = info->cpp[0]; 692 693 /* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */ 694 return min(8192 * cpp, 32 * 1024); 695 } 696 697 static unsigned int 698 ilk_primary_max_stride(struct intel_plane *plane, 699 u32 pixel_format, u64 modifier, 700 unsigned int rotation) 701 { 702 const struct drm_format_info *info = drm_format_info(pixel_format); 703 int cpp = info->cpp[0]; 704 705 /* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */ 706 if (modifier == I915_FORMAT_MOD_X_TILED) 707 return min(4096 * cpp, 32 * 1024); 708 else 709 return 32 * 1024; 710 } 711 712 unsigned int 713 i965_plane_max_stride(struct intel_plane *plane, 714 u32 pixel_format, u64 modifier, 715 unsigned int rotation) 716 { 717 const struct drm_format_info *info = drm_format_info(pixel_format); 718 int cpp = info->cpp[0]; 719 720 /* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */ 721 if (modifier == I915_FORMAT_MOD_X_TILED) 722 return min(4096 * cpp, 16 * 1024); 723 else 724 return 32 * 1024; 725 } 726 727 static unsigned int 728 i9xx_plane_max_stride(struct intel_plane *plane, 729 u32 pixel_format, u64 modifier, 730 unsigned int rotation) 731 { 732 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 733 734 if (DISPLAY_VER(dev_priv) >= 3) { 735 if (modifier == I915_FORMAT_MOD_X_TILED) 736 return 8*1024; 737 else 738 return 16*1024; 739 } else { 740 if (plane->i9xx_plane == PLANE_C) 741 return 4*1024; 742 else 743 return 8*1024; 744 } 745 } 746 747 static const struct drm_plane_funcs i965_plane_funcs = { 748 .update_plane = drm_atomic_helper_update_plane, 749 .disable_plane = drm_atomic_helper_disable_plane, 750 .destroy = intel_plane_destroy, 751 .atomic_duplicate_state = intel_plane_duplicate_state, 752 .atomic_destroy_state = intel_plane_destroy_state, 753 .format_mod_supported = i965_plane_format_mod_supported, 754 }; 755 756 static const struct drm_plane_funcs i8xx_plane_funcs = { 757 .update_plane = drm_atomic_helper_update_plane, 758 .disable_plane = drm_atomic_helper_disable_plane, 759 .destroy = intel_plane_destroy, 760 .atomic_duplicate_state = intel_plane_duplicate_state, 761 .atomic_destroy_state = intel_plane_destroy_state, 762 .format_mod_supported = i8xx_plane_format_mod_supported, 763 }; 764 765 struct intel_plane * 766 intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) 767 { 768 struct intel_plane *plane; 769 const struct drm_plane_funcs *plane_funcs; 770 unsigned int supported_rotations; 771 const u32 *formats; 772 int num_formats; 773 int ret, zpos; 774 775 plane = intel_plane_alloc(); 776 if (IS_ERR(plane)) 777 return plane; 778 779 plane->pipe = pipe; 780 /* 781 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS 782 * port is hooked to pipe B. Hence we want plane A feeding pipe B. 783 */ 784 if (HAS_FBC(dev_priv) && DISPLAY_VER(dev_priv) < 4 && 785 INTEL_NUM_PIPES(dev_priv) == 2) 786 plane->i9xx_plane = (enum i9xx_plane_id) !pipe; 787 else 788 plane->i9xx_plane = (enum i9xx_plane_id) pipe; 789 plane->id = PLANE_PRIMARY; 790 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 791 792 plane->has_fbc = i9xx_plane_has_fbc(dev_priv, plane->i9xx_plane); 793 if (plane->has_fbc) { 794 struct intel_fbc *fbc = &dev_priv->fbc; 795 796 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; 797 } 798 799 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 800 formats = vlv_primary_formats; 801 num_formats = ARRAY_SIZE(vlv_primary_formats); 802 } else if (DISPLAY_VER(dev_priv) >= 4) { 803 /* 804 * WaFP16GammaEnabling:ivb 805 * "Workaround : When using the 64-bit format, the plane 806 * output on each color channel has one quarter amplitude. 807 * It can be brought up to full amplitude by using pipe 808 * gamma correction or pipe color space conversion to 809 * multiply the plane output by four." 810 * 811 * There is no dedicated plane gamma for the primary plane, 812 * and using the pipe gamma/csc could conflict with other 813 * planes, so we choose not to expose fp16 on IVB primary 814 * planes. HSW primary planes no longer have this problem. 815 */ 816 if (IS_IVYBRIDGE(dev_priv)) { 817 formats = ivb_primary_formats; 818 num_formats = ARRAY_SIZE(ivb_primary_formats); 819 } else { 820 formats = i965_primary_formats; 821 num_formats = ARRAY_SIZE(i965_primary_formats); 822 } 823 } else { 824 formats = i8xx_primary_formats; 825 num_formats = ARRAY_SIZE(i8xx_primary_formats); 826 } 827 828 if (DISPLAY_VER(dev_priv) >= 4) 829 plane_funcs = &i965_plane_funcs; 830 else 831 plane_funcs = &i8xx_plane_funcs; 832 833 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) 834 plane->min_cdclk = vlv_plane_min_cdclk; 835 else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) 836 plane->min_cdclk = hsw_plane_min_cdclk; 837 else if (IS_IVYBRIDGE(dev_priv)) 838 plane->min_cdclk = ivb_plane_min_cdclk; 839 else 840 plane->min_cdclk = i9xx_plane_min_cdclk; 841 842 if (HAS_GMCH(dev_priv)) { 843 if (DISPLAY_VER(dev_priv) >= 4) 844 plane->max_stride = i965_plane_max_stride; 845 else 846 plane->max_stride = i9xx_plane_max_stride; 847 } else { 848 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) 849 plane->max_stride = hsw_primary_max_stride; 850 else 851 plane->max_stride = ilk_primary_max_stride; 852 } 853 854 plane->update_plane = i9xx_update_plane; 855 plane->disable_plane = i9xx_disable_plane; 856 plane->get_hw_state = i9xx_plane_get_hw_state; 857 plane->check_plane = i9xx_plane_check; 858 859 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 860 plane->async_flip = vlv_primary_async_flip; 861 plane->enable_flip_done = vlv_primary_enable_flip_done; 862 plane->disable_flip_done = vlv_primary_disable_flip_done; 863 } else if (IS_BROADWELL(dev_priv)) { 864 plane->need_async_flip_disable_wa = true; 865 plane->async_flip = g4x_primary_async_flip; 866 plane->enable_flip_done = bdw_primary_enable_flip_done; 867 plane->disable_flip_done = bdw_primary_disable_flip_done; 868 } else if (DISPLAY_VER(dev_priv) >= 7) { 869 plane->async_flip = g4x_primary_async_flip; 870 plane->enable_flip_done = ivb_primary_enable_flip_done; 871 plane->disable_flip_done = ivb_primary_disable_flip_done; 872 } else if (DISPLAY_VER(dev_priv) >= 5) { 873 plane->async_flip = g4x_primary_async_flip; 874 plane->enable_flip_done = ilk_primary_enable_flip_done; 875 plane->disable_flip_done = ilk_primary_disable_flip_done; 876 } 877 878 if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) 879 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 880 0, plane_funcs, 881 formats, num_formats, 882 i9xx_format_modifiers, 883 DRM_PLANE_TYPE_PRIMARY, 884 "primary %c", pipe_name(pipe)); 885 else 886 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 887 0, plane_funcs, 888 formats, num_formats, 889 i9xx_format_modifiers, 890 DRM_PLANE_TYPE_PRIMARY, 891 "plane %c", 892 plane_name(plane->i9xx_plane)); 893 if (ret) 894 goto fail; 895 896 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 897 supported_rotations = 898 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 899 DRM_MODE_REFLECT_X; 900 } else if (DISPLAY_VER(dev_priv) >= 4) { 901 supported_rotations = 902 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 903 } else { 904 supported_rotations = DRM_MODE_ROTATE_0; 905 } 906 907 if (DISPLAY_VER(dev_priv) >= 4) 908 drm_plane_create_rotation_property(&plane->base, 909 DRM_MODE_ROTATE_0, 910 supported_rotations); 911 912 zpos = 0; 913 drm_plane_create_zpos_immutable_property(&plane->base, zpos); 914 915 intel_plane_helper_add(plane); 916 917 return plane; 918 919 fail: 920 intel_plane_free(plane); 921 922 return ERR_PTR(ret); 923 } 924 925 static int i9xx_format_to_fourcc(int format) 926 { 927 switch (format) { 928 case DISPPLANE_8BPP: 929 return DRM_FORMAT_C8; 930 case DISPPLANE_BGRA555: 931 return DRM_FORMAT_ARGB1555; 932 case DISPPLANE_BGRX555: 933 return DRM_FORMAT_XRGB1555; 934 case DISPPLANE_BGRX565: 935 return DRM_FORMAT_RGB565; 936 default: 937 case DISPPLANE_BGRX888: 938 return DRM_FORMAT_XRGB8888; 939 case DISPPLANE_RGBX888: 940 return DRM_FORMAT_XBGR8888; 941 case DISPPLANE_BGRA888: 942 return DRM_FORMAT_ARGB8888; 943 case DISPPLANE_RGBA888: 944 return DRM_FORMAT_ABGR8888; 945 case DISPPLANE_BGRX101010: 946 return DRM_FORMAT_XRGB2101010; 947 case DISPPLANE_RGBX101010: 948 return DRM_FORMAT_XBGR2101010; 949 case DISPPLANE_BGRA101010: 950 return DRM_FORMAT_ARGB2101010; 951 case DISPPLANE_RGBA101010: 952 return DRM_FORMAT_ABGR2101010; 953 case DISPPLANE_RGBX161616: 954 return DRM_FORMAT_XBGR16161616F; 955 } 956 } 957 958 void 959 i9xx_get_initial_plane_config(struct intel_crtc *crtc, 960 struct intel_initial_plane_config *plane_config) 961 { 962 struct drm_device *dev = crtc->base.dev; 963 struct drm_i915_private *dev_priv = to_i915(dev); 964 struct intel_plane *plane = to_intel_plane(crtc->base.primary); 965 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 966 enum pipe pipe; 967 u32 val, base, offset; 968 int fourcc, pixel_format; 969 unsigned int aligned_height; 970 struct drm_framebuffer *fb; 971 struct intel_framebuffer *intel_fb; 972 973 if (!plane->get_hw_state(plane, &pipe)) 974 return; 975 976 drm_WARN_ON(dev, pipe != crtc->pipe); 977 978 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 979 if (!intel_fb) { 980 drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n"); 981 return; 982 } 983 984 fb = &intel_fb->base; 985 986 fb->dev = dev; 987 988 val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane)); 989 990 if (DISPLAY_VER(dev_priv) >= 4) { 991 if (val & DISPPLANE_TILED) { 992 plane_config->tiling = I915_TILING_X; 993 fb->modifier = I915_FORMAT_MOD_X_TILED; 994 } 995 996 if (val & DISPPLANE_ROTATE_180) 997 plane_config->rotation = DRM_MODE_ROTATE_180; 998 } 999 1000 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B && 1001 val & DISPPLANE_MIRROR) 1002 plane_config->rotation |= DRM_MODE_REFLECT_X; 1003 1004 pixel_format = val & DISPPLANE_PIXFORMAT_MASK; 1005 fourcc = i9xx_format_to_fourcc(pixel_format); 1006 fb->format = drm_format_info(fourcc); 1007 1008 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 1009 offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane)); 1010 base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000; 1011 } else if (DISPLAY_VER(dev_priv) >= 4) { 1012 if (plane_config->tiling) 1013 offset = intel_de_read(dev_priv, 1014 DSPTILEOFF(i9xx_plane)); 1015 else 1016 offset = intel_de_read(dev_priv, 1017 DSPLINOFF(i9xx_plane)); 1018 base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000; 1019 } else { 1020 base = intel_de_read(dev_priv, DSPADDR(i9xx_plane)); 1021 } 1022 plane_config->base = base; 1023 1024 val = intel_de_read(dev_priv, PIPESRC(pipe)); 1025 fb->width = ((val >> 16) & 0xfff) + 1; 1026 fb->height = ((val >> 0) & 0xfff) + 1; 1027 1028 val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane)); 1029 fb->pitches[0] = val & 0xffffffc0; 1030 1031 aligned_height = intel_fb_align_height(fb, 0, fb->height); 1032 1033 plane_config->size = fb->pitches[0] * aligned_height; 1034 1035 drm_dbg_kms(&dev_priv->drm, 1036 "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", 1037 crtc->base.name, plane->base.name, fb->width, fb->height, 1038 fb->format->cpp[0] * 8, base, fb->pitches[0], 1039 plane_config->size); 1040 1041 plane_config->fb = intel_fb; 1042 } 1043