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