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