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