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