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