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