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