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 drm_i915_private *i915 = to_i915(plane->base.dev); 634 enum pipe pipe = plane->pipe; 635 636 spin_lock_irq(&i915->irq_lock); 637 bdw_enable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); 638 spin_unlock_irq(&i915->irq_lock); 639 } 640 641 static void 642 bdw_primary_disable_flip_done(struct intel_plane *plane) 643 { 644 struct drm_i915_private *i915 = to_i915(plane->base.dev); 645 enum pipe pipe = plane->pipe; 646 647 spin_lock_irq(&i915->irq_lock); 648 bdw_disable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); 649 spin_unlock_irq(&i915->irq_lock); 650 } 651 652 static void 653 ivb_primary_enable_flip_done(struct intel_plane *plane) 654 { 655 struct drm_i915_private *i915 = to_i915(plane->base.dev); 656 657 spin_lock_irq(&i915->irq_lock); 658 ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); 659 spin_unlock_irq(&i915->irq_lock); 660 } 661 662 static void 663 ivb_primary_disable_flip_done(struct intel_plane *plane) 664 { 665 struct drm_i915_private *i915 = to_i915(plane->base.dev); 666 667 spin_lock_irq(&i915->irq_lock); 668 ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); 669 spin_unlock_irq(&i915->irq_lock); 670 } 671 672 static void 673 ilk_primary_enable_flip_done(struct intel_plane *plane) 674 { 675 struct drm_i915_private *i915 = to_i915(plane->base.dev); 676 677 spin_lock_irq(&i915->irq_lock); 678 ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); 679 spin_unlock_irq(&i915->irq_lock); 680 } 681 682 static void 683 ilk_primary_disable_flip_done(struct intel_plane *plane) 684 { 685 struct drm_i915_private *i915 = to_i915(plane->base.dev); 686 687 spin_lock_irq(&i915->irq_lock); 688 ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); 689 spin_unlock_irq(&i915->irq_lock); 690 } 691 692 static void 693 vlv_primary_enable_flip_done(struct intel_plane *plane) 694 { 695 struct drm_i915_private *i915 = to_i915(plane->base.dev); 696 enum pipe pipe = plane->pipe; 697 698 spin_lock_irq(&i915->irq_lock); 699 i915_enable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); 700 spin_unlock_irq(&i915->irq_lock); 701 } 702 703 static void 704 vlv_primary_disable_flip_done(struct intel_plane *plane) 705 { 706 struct drm_i915_private *i915 = to_i915(plane->base.dev); 707 enum pipe pipe = plane->pipe; 708 709 spin_lock_irq(&i915->irq_lock); 710 i915_disable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); 711 spin_unlock_irq(&i915->irq_lock); 712 } 713 714 static bool i9xx_plane_can_async_flip(u64 modifier) 715 { 716 return modifier == I915_FORMAT_MOD_X_TILED; 717 } 718 719 static bool i9xx_plane_get_hw_state(struct intel_plane *plane, 720 enum pipe *pipe) 721 { 722 struct intel_display *display = to_intel_display(plane); 723 enum intel_display_power_domain power_domain; 724 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 725 intel_wakeref_t wakeref; 726 bool ret; 727 u32 val; 728 729 /* 730 * Not 100% correct for planes that can move between pipes, 731 * but that's only the case for gen2-4 which don't have any 732 * display power wells. 733 */ 734 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 735 wakeref = intel_display_power_get_if_enabled(display, power_domain); 736 if (!wakeref) 737 return false; 738 739 val = intel_de_read(display, DSPCNTR(display, i9xx_plane)); 740 741 ret = val & DISP_ENABLE; 742 743 if (DISPLAY_VER(display) >= 5) 744 *pipe = plane->pipe; 745 else 746 *pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val); 747 748 intel_display_power_put(display, power_domain, wakeref); 749 750 return ret; 751 } 752 753 static unsigned int 754 hsw_primary_max_stride(struct intel_plane *plane, 755 u32 pixel_format, u64 modifier, 756 unsigned int rotation) 757 { 758 const struct drm_format_info *info = drm_format_info(pixel_format); 759 int cpp = info->cpp[0]; 760 761 /* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */ 762 return min(8192 * cpp, 32 * 1024); 763 } 764 765 static unsigned int 766 ilk_primary_max_stride(struct intel_plane *plane, 767 u32 pixel_format, u64 modifier, 768 unsigned int rotation) 769 { 770 const struct drm_format_info *info = drm_format_info(pixel_format); 771 int cpp = info->cpp[0]; 772 773 /* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */ 774 if (modifier == I915_FORMAT_MOD_X_TILED) 775 return min(4096 * cpp, 32 * 1024); 776 else 777 return 32 * 1024; 778 } 779 780 unsigned int 781 i965_plane_max_stride(struct intel_plane *plane, 782 u32 pixel_format, u64 modifier, 783 unsigned int rotation) 784 { 785 const struct drm_format_info *info = drm_format_info(pixel_format); 786 int cpp = info->cpp[0]; 787 788 /* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */ 789 if (modifier == I915_FORMAT_MOD_X_TILED) 790 return min(4096 * cpp, 16 * 1024); 791 else 792 return 32 * 1024; 793 } 794 795 static unsigned int 796 i915_plane_max_stride(struct intel_plane *plane, 797 u32 pixel_format, u64 modifier, 798 unsigned int rotation) 799 { 800 if (modifier == I915_FORMAT_MOD_X_TILED) 801 return 8 * 1024; 802 else 803 return 16 * 1024; 804 } 805 806 static unsigned int 807 i8xx_plane_max_stride(struct intel_plane *plane, 808 u32 pixel_format, u64 modifier, 809 unsigned int rotation) 810 { 811 if (plane->i9xx_plane == PLANE_C) 812 return 4 * 1024; 813 else 814 return 8 * 1024; 815 } 816 817 unsigned int vlv_plane_min_alignment(struct intel_plane *plane, 818 const struct drm_framebuffer *fb, 819 int color_plane) 820 { 821 struct intel_display *display = to_intel_display(plane); 822 823 if (intel_plane_can_async_flip(plane, fb->modifier)) 824 return 256 * 1024; 825 826 /* FIXME undocumented so not sure what's actually needed */ 827 if (intel_scanout_needs_vtd_wa(display)) 828 return 256 * 1024; 829 830 switch (fb->modifier) { 831 case I915_FORMAT_MOD_X_TILED: 832 return 4 * 1024; 833 case DRM_FORMAT_MOD_LINEAR: 834 return 128 * 1024; 835 default: 836 MISSING_CASE(fb->modifier); 837 return 0; 838 } 839 } 840 841 static unsigned int g4x_primary_min_alignment(struct intel_plane *plane, 842 const struct drm_framebuffer *fb, 843 int color_plane) 844 { 845 struct intel_display *display = to_intel_display(plane); 846 847 if (intel_plane_can_async_flip(plane, fb->modifier)) 848 return 256 * 1024; 849 850 if (intel_scanout_needs_vtd_wa(display)) 851 return 256 * 1024; 852 853 switch (fb->modifier) { 854 case I915_FORMAT_MOD_X_TILED: 855 case DRM_FORMAT_MOD_LINEAR: 856 return 4 * 1024; 857 default: 858 MISSING_CASE(fb->modifier); 859 return 0; 860 } 861 } 862 863 static unsigned int i965_plane_min_alignment(struct intel_plane *plane, 864 const struct drm_framebuffer *fb, 865 int color_plane) 866 { 867 switch (fb->modifier) { 868 case I915_FORMAT_MOD_X_TILED: 869 return 4 * 1024; 870 case DRM_FORMAT_MOD_LINEAR: 871 return 128 * 1024; 872 default: 873 MISSING_CASE(fb->modifier); 874 return 0; 875 } 876 } 877 878 static unsigned int i9xx_plane_min_alignment(struct intel_plane *plane, 879 const struct drm_framebuffer *fb, 880 int color_plane) 881 { 882 return 0; 883 } 884 885 static const struct drm_plane_funcs i965_plane_funcs = { 886 .update_plane = drm_atomic_helper_update_plane, 887 .disable_plane = drm_atomic_helper_disable_plane, 888 .destroy = intel_plane_destroy, 889 .atomic_duplicate_state = intel_plane_duplicate_state, 890 .atomic_destroy_state = intel_plane_destroy_state, 891 .format_mod_supported = i965_plane_format_mod_supported, 892 }; 893 894 static const struct drm_plane_funcs i8xx_plane_funcs = { 895 .update_plane = drm_atomic_helper_update_plane, 896 .disable_plane = drm_atomic_helper_disable_plane, 897 .destroy = intel_plane_destroy, 898 .atomic_duplicate_state = intel_plane_duplicate_state, 899 .atomic_destroy_state = intel_plane_destroy_state, 900 .format_mod_supported = i8xx_plane_format_mod_supported, 901 }; 902 903 struct intel_plane * 904 intel_primary_plane_create(struct intel_display *display, enum pipe pipe) 905 { 906 struct intel_plane *plane; 907 const struct drm_plane_funcs *plane_funcs; 908 unsigned int supported_rotations; 909 const u64 *modifiers; 910 const u32 *formats; 911 int num_formats; 912 int ret, zpos; 913 914 plane = intel_plane_alloc(); 915 if (IS_ERR(plane)) 916 return plane; 917 918 plane->pipe = pipe; 919 /* 920 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS 921 * port is hooked to pipe B. Hence we want plane A feeding pipe B. 922 */ 923 if (HAS_FBC(display) && DISPLAY_VER(display) < 4 && 924 INTEL_NUM_PIPES(display) == 2) 925 plane->i9xx_plane = (enum i9xx_plane_id) !pipe; 926 else 927 plane->i9xx_plane = (enum i9xx_plane_id) pipe; 928 plane->id = PLANE_PRIMARY; 929 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 930 931 intel_fbc_add_plane(i9xx_plane_fbc(display, plane->i9xx_plane), plane); 932 933 if (display->platform.valleyview || display->platform.cherryview) { 934 formats = vlv_primary_formats; 935 num_formats = ARRAY_SIZE(vlv_primary_formats); 936 } else if (DISPLAY_VER(display) >= 4) { 937 /* 938 * WaFP16GammaEnabling:ivb 939 * "Workaround : When using the 64-bit format, the plane 940 * output on each color channel has one quarter amplitude. 941 * It can be brought up to full amplitude by using pipe 942 * gamma correction or pipe color space conversion to 943 * multiply the plane output by four." 944 * 945 * There is no dedicated plane gamma for the primary plane, 946 * and using the pipe gamma/csc could conflict with other 947 * planes, so we choose not to expose fp16 on IVB primary 948 * planes. HSW primary planes no longer have this problem. 949 */ 950 if (display->platform.ivybridge) { 951 formats = ivb_primary_formats; 952 num_formats = ARRAY_SIZE(ivb_primary_formats); 953 } else { 954 formats = i965_primary_formats; 955 num_formats = ARRAY_SIZE(i965_primary_formats); 956 } 957 } else { 958 formats = i8xx_primary_formats; 959 num_formats = ARRAY_SIZE(i8xx_primary_formats); 960 } 961 962 if (DISPLAY_VER(display) >= 4) 963 plane_funcs = &i965_plane_funcs; 964 else 965 plane_funcs = &i8xx_plane_funcs; 966 967 if (display->platform.valleyview || display->platform.cherryview) 968 plane->min_cdclk = vlv_plane_min_cdclk; 969 else if (display->platform.broadwell || display->platform.haswell) 970 plane->min_cdclk = hsw_plane_min_cdclk; 971 else if (display->platform.ivybridge) 972 plane->min_cdclk = ivb_plane_min_cdclk; 973 else 974 plane->min_cdclk = i9xx_plane_min_cdclk; 975 976 if (HAS_GMCH(display)) { 977 if (DISPLAY_VER(display) >= 4) 978 plane->max_stride = i965_plane_max_stride; 979 else if (DISPLAY_VER(display) == 3) 980 plane->max_stride = i915_plane_max_stride; 981 else 982 plane->max_stride = i8xx_plane_max_stride; 983 } else { 984 if (display->platform.broadwell || display->platform.haswell) 985 plane->max_stride = hsw_primary_max_stride; 986 else 987 plane->max_stride = ilk_primary_max_stride; 988 } 989 990 if (display->platform.valleyview || display->platform.cherryview) 991 plane->min_alignment = vlv_plane_min_alignment; 992 else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) 993 plane->min_alignment = g4x_primary_min_alignment; 994 else if (DISPLAY_VER(display) == 4) 995 plane->min_alignment = i965_plane_min_alignment; 996 else 997 plane->min_alignment = i9xx_plane_min_alignment; 998 999 /* FIXME undocumented for VLV/CHV so not sure what's actually needed */ 1000 if (intel_scanout_needs_vtd_wa(display)) 1001 plane->vtd_guard = 128; 1002 1003 if (display->platform.i830 || display->platform.i845g) { 1004 plane->update_arm = i830_plane_update_arm; 1005 } else { 1006 plane->update_noarm = i9xx_plane_update_noarm; 1007 plane->update_arm = i9xx_plane_update_arm; 1008 } 1009 plane->disable_arm = i9xx_plane_disable_arm; 1010 plane->get_hw_state = i9xx_plane_get_hw_state; 1011 plane->check_plane = i9xx_plane_check; 1012 1013 if (DISPLAY_VER(display) >= 5 || display->platform.g4x) 1014 plane->capture_error = g4x_primary_capture_error; 1015 else if (DISPLAY_VER(display) >= 4) 1016 plane->capture_error = i965_plane_capture_error; 1017 else 1018 plane->capture_error = i8xx_plane_capture_error; 1019 1020 if (HAS_ASYNC_FLIPS(display)) { 1021 if (display->platform.valleyview || display->platform.cherryview) { 1022 plane->async_flip = vlv_primary_async_flip; 1023 plane->enable_flip_done = vlv_primary_enable_flip_done; 1024 plane->disable_flip_done = vlv_primary_disable_flip_done; 1025 plane->can_async_flip = i9xx_plane_can_async_flip; 1026 } else if (display->platform.broadwell) { 1027 plane->need_async_flip_toggle_wa = true; 1028 plane->async_flip = g4x_primary_async_flip; 1029 plane->enable_flip_done = bdw_primary_enable_flip_done; 1030 plane->disable_flip_done = bdw_primary_disable_flip_done; 1031 plane->can_async_flip = i9xx_plane_can_async_flip; 1032 } else if (DISPLAY_VER(display) >= 7) { 1033 plane->async_flip = g4x_primary_async_flip; 1034 plane->enable_flip_done = ivb_primary_enable_flip_done; 1035 plane->disable_flip_done = ivb_primary_disable_flip_done; 1036 plane->can_async_flip = i9xx_plane_can_async_flip; 1037 } else if (DISPLAY_VER(display) >= 5) { 1038 plane->async_flip = g4x_primary_async_flip; 1039 plane->enable_flip_done = ilk_primary_enable_flip_done; 1040 plane->disable_flip_done = ilk_primary_disable_flip_done; 1041 plane->can_async_flip = i9xx_plane_can_async_flip; 1042 } 1043 } 1044 1045 modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X); 1046 1047 if (DISPLAY_VER(display) >= 5 || display->platform.g4x) 1048 ret = drm_universal_plane_init(display->drm, &plane->base, 1049 0, plane_funcs, 1050 formats, num_formats, 1051 modifiers, 1052 DRM_PLANE_TYPE_PRIMARY, 1053 "primary %c", pipe_name(pipe)); 1054 else 1055 ret = drm_universal_plane_init(display->drm, &plane->base, 1056 0, plane_funcs, 1057 formats, num_formats, 1058 modifiers, 1059 DRM_PLANE_TYPE_PRIMARY, 1060 "plane %c", 1061 plane_name(plane->i9xx_plane)); 1062 1063 kfree(modifiers); 1064 1065 if (ret) 1066 goto fail; 1067 1068 if (display->platform.cherryview && pipe == PIPE_B) { 1069 supported_rotations = 1070 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 1071 DRM_MODE_REFLECT_X; 1072 } else if (DISPLAY_VER(display) >= 4) { 1073 supported_rotations = 1074 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 1075 } else { 1076 supported_rotations = DRM_MODE_ROTATE_0; 1077 } 1078 1079 if (DISPLAY_VER(display) >= 4) 1080 drm_plane_create_rotation_property(&plane->base, 1081 DRM_MODE_ROTATE_0, 1082 supported_rotations); 1083 1084 zpos = 0; 1085 drm_plane_create_zpos_immutable_property(&plane->base, zpos); 1086 1087 intel_plane_helper_add(plane); 1088 1089 return plane; 1090 1091 fail: 1092 intel_plane_free(plane); 1093 1094 return ERR_PTR(ret); 1095 } 1096 1097 static int i9xx_format_to_fourcc(int format) 1098 { 1099 switch (format) { 1100 case DISP_FORMAT_8BPP: 1101 return DRM_FORMAT_C8; 1102 case DISP_FORMAT_BGRA555: 1103 return DRM_FORMAT_ARGB1555; 1104 case DISP_FORMAT_BGRX555: 1105 return DRM_FORMAT_XRGB1555; 1106 case DISP_FORMAT_BGRX565: 1107 return DRM_FORMAT_RGB565; 1108 default: 1109 case DISP_FORMAT_BGRX888: 1110 return DRM_FORMAT_XRGB8888; 1111 case DISP_FORMAT_RGBX888: 1112 return DRM_FORMAT_XBGR8888; 1113 case DISP_FORMAT_BGRA888: 1114 return DRM_FORMAT_ARGB8888; 1115 case DISP_FORMAT_RGBA888: 1116 return DRM_FORMAT_ABGR8888; 1117 case DISP_FORMAT_BGRX101010: 1118 return DRM_FORMAT_XRGB2101010; 1119 case DISP_FORMAT_RGBX101010: 1120 return DRM_FORMAT_XBGR2101010; 1121 case DISP_FORMAT_BGRA101010: 1122 return DRM_FORMAT_ARGB2101010; 1123 case DISP_FORMAT_RGBA101010: 1124 return DRM_FORMAT_ABGR2101010; 1125 case DISP_FORMAT_RGBX161616: 1126 return DRM_FORMAT_XBGR16161616F; 1127 } 1128 } 1129 1130 void 1131 i9xx_get_initial_plane_config(struct intel_crtc *crtc, 1132 struct intel_initial_plane_config *plane_config) 1133 { 1134 struct intel_display *display = to_intel_display(crtc); 1135 struct intel_plane *plane = to_intel_plane(crtc->base.primary); 1136 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 1137 enum pipe pipe; 1138 u32 val, base, offset; 1139 int fourcc, pixel_format; 1140 unsigned int aligned_height; 1141 struct drm_framebuffer *fb; 1142 struct intel_framebuffer *intel_fb; 1143 1144 if (!plane->get_hw_state(plane, &pipe)) 1145 return; 1146 1147 drm_WARN_ON(display->drm, pipe != crtc->pipe); 1148 1149 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 1150 if (!intel_fb) { 1151 drm_dbg_kms(display->drm, "failed to alloc fb\n"); 1152 return; 1153 } 1154 1155 fb = &intel_fb->base; 1156 1157 fb->dev = display->drm; 1158 1159 val = intel_de_read(display, DSPCNTR(display, i9xx_plane)); 1160 1161 if (DISPLAY_VER(display) >= 4) { 1162 if (val & DISP_TILED) { 1163 plane_config->tiling = I915_TILING_X; 1164 fb->modifier = I915_FORMAT_MOD_X_TILED; 1165 } 1166 1167 if (val & DISP_ROTATE_180) 1168 plane_config->rotation = DRM_MODE_ROTATE_180; 1169 } 1170 1171 if (display->platform.cherryview && 1172 pipe == PIPE_B && val & DISP_MIRROR) 1173 plane_config->rotation |= DRM_MODE_REFLECT_X; 1174 1175 pixel_format = val & DISP_FORMAT_MASK; 1176 fourcc = i9xx_format_to_fourcc(pixel_format); 1177 fb->format = drm_format_info(fourcc); 1178 1179 if (display->platform.haswell || display->platform.broadwell) { 1180 offset = intel_de_read(display, 1181 DSPOFFSET(display, i9xx_plane)); 1182 base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK; 1183 } else if (DISPLAY_VER(display) >= 4) { 1184 if (plane_config->tiling) 1185 offset = intel_de_read(display, 1186 DSPTILEOFF(display, i9xx_plane)); 1187 else 1188 offset = intel_de_read(display, 1189 DSPLINOFF(display, i9xx_plane)); 1190 base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK; 1191 } else { 1192 offset = 0; 1193 base = intel_de_read(display, DSPADDR(display, i9xx_plane)); 1194 } 1195 plane_config->base = base; 1196 1197 drm_WARN_ON(display->drm, offset != 0); 1198 1199 val = intel_de_read(display, PIPESRC(display, pipe)); 1200 fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1; 1201 fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1; 1202 1203 val = intel_de_read(display, DSPSTRIDE(display, i9xx_plane)); 1204 fb->pitches[0] = val & 0xffffffc0; 1205 1206 aligned_height = intel_fb_align_height(fb, 0, fb->height); 1207 1208 plane_config->size = fb->pitches[0] * aligned_height; 1209 1210 drm_dbg_kms(display->drm, 1211 "[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", 1212 crtc->base.base.id, crtc->base.name, 1213 plane->base.base.id, plane->base.name, 1214 fb->width, fb->height, fb->format->cpp[0] * 8, 1215 base, fb->pitches[0], plane_config->size); 1216 1217 plane_config->fb = intel_fb; 1218 } 1219 1220 bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc, 1221 const struct intel_initial_plane_config *plane_config) 1222 { 1223 struct intel_display *display = to_intel_display(crtc); 1224 struct intel_plane *plane = to_intel_plane(crtc->base.primary); 1225 const struct intel_plane_state *plane_state = 1226 to_intel_plane_state(plane->base.state); 1227 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 1228 u32 base; 1229 1230 if (!plane_state->uapi.visible) 1231 return false; 1232 1233 base = intel_plane_ggtt_offset(plane_state); 1234 1235 /* 1236 * We may have moved the surface to a different 1237 * part of ggtt, make the plane aware of that. 1238 */ 1239 if (plane_config->base == base) 1240 return false; 1241 1242 if (DISPLAY_VER(display) >= 4) 1243 intel_de_write(display, DSPSURF(display, i9xx_plane), base); 1244 else 1245 intel_de_write(display, DSPADDR(display, i9xx_plane), base); 1246 1247 return true; 1248 } 1249