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