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