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