1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2020 Intel Corporation 4 */ 5 6 #include <drm/drm_atomic_helper.h> 7 #include <drm/drm_damage_helper.h> 8 #include <drm/drm_fourcc.h> 9 #include <drm/drm_plane_helper.h> 10 11 #include "i915_drv.h" 12 #include "intel_atomic_plane.h" 13 #include "intel_de.h" 14 #include "intel_display_types.h" 15 #include "intel_fb.h" 16 #include "intel_pm.h" 17 #include "intel_psr.h" 18 #include "intel_sprite.h" 19 #include "skl_scaler.h" 20 #include "skl_universal_plane.h" 21 22 static const u32 skl_plane_formats[] = { 23 DRM_FORMAT_C8, 24 DRM_FORMAT_RGB565, 25 DRM_FORMAT_XRGB8888, 26 DRM_FORMAT_XBGR8888, 27 DRM_FORMAT_ARGB8888, 28 DRM_FORMAT_ABGR8888, 29 DRM_FORMAT_XRGB2101010, 30 DRM_FORMAT_XBGR2101010, 31 DRM_FORMAT_XRGB16161616F, 32 DRM_FORMAT_XBGR16161616F, 33 DRM_FORMAT_YUYV, 34 DRM_FORMAT_YVYU, 35 DRM_FORMAT_UYVY, 36 DRM_FORMAT_VYUY, 37 DRM_FORMAT_XYUV8888, 38 }; 39 40 static const u32 skl_planar_formats[] = { 41 DRM_FORMAT_C8, 42 DRM_FORMAT_RGB565, 43 DRM_FORMAT_XRGB8888, 44 DRM_FORMAT_XBGR8888, 45 DRM_FORMAT_ARGB8888, 46 DRM_FORMAT_ABGR8888, 47 DRM_FORMAT_XRGB2101010, 48 DRM_FORMAT_XBGR2101010, 49 DRM_FORMAT_XRGB16161616F, 50 DRM_FORMAT_XBGR16161616F, 51 DRM_FORMAT_YUYV, 52 DRM_FORMAT_YVYU, 53 DRM_FORMAT_UYVY, 54 DRM_FORMAT_VYUY, 55 DRM_FORMAT_NV12, 56 DRM_FORMAT_XYUV8888, 57 }; 58 59 static const u32 glk_planar_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_XRGB16161616F, 69 DRM_FORMAT_XBGR16161616F, 70 DRM_FORMAT_YUYV, 71 DRM_FORMAT_YVYU, 72 DRM_FORMAT_UYVY, 73 DRM_FORMAT_VYUY, 74 DRM_FORMAT_NV12, 75 DRM_FORMAT_XYUV8888, 76 DRM_FORMAT_P010, 77 DRM_FORMAT_P012, 78 DRM_FORMAT_P016, 79 }; 80 81 static const u32 icl_sdr_y_plane_formats[] = { 82 DRM_FORMAT_C8, 83 DRM_FORMAT_RGB565, 84 DRM_FORMAT_XRGB8888, 85 DRM_FORMAT_XBGR8888, 86 DRM_FORMAT_ARGB8888, 87 DRM_FORMAT_ABGR8888, 88 DRM_FORMAT_XRGB2101010, 89 DRM_FORMAT_XBGR2101010, 90 DRM_FORMAT_ARGB2101010, 91 DRM_FORMAT_ABGR2101010, 92 DRM_FORMAT_YUYV, 93 DRM_FORMAT_YVYU, 94 DRM_FORMAT_UYVY, 95 DRM_FORMAT_VYUY, 96 DRM_FORMAT_Y210, 97 DRM_FORMAT_Y212, 98 DRM_FORMAT_Y216, 99 DRM_FORMAT_XYUV8888, 100 DRM_FORMAT_XVYU2101010, 101 DRM_FORMAT_XVYU12_16161616, 102 DRM_FORMAT_XVYU16161616, 103 }; 104 105 static const u32 icl_sdr_uv_plane_formats[] = { 106 DRM_FORMAT_C8, 107 DRM_FORMAT_RGB565, 108 DRM_FORMAT_XRGB8888, 109 DRM_FORMAT_XBGR8888, 110 DRM_FORMAT_ARGB8888, 111 DRM_FORMAT_ABGR8888, 112 DRM_FORMAT_XRGB2101010, 113 DRM_FORMAT_XBGR2101010, 114 DRM_FORMAT_ARGB2101010, 115 DRM_FORMAT_ABGR2101010, 116 DRM_FORMAT_YUYV, 117 DRM_FORMAT_YVYU, 118 DRM_FORMAT_UYVY, 119 DRM_FORMAT_VYUY, 120 DRM_FORMAT_NV12, 121 DRM_FORMAT_P010, 122 DRM_FORMAT_P012, 123 DRM_FORMAT_P016, 124 DRM_FORMAT_Y210, 125 DRM_FORMAT_Y212, 126 DRM_FORMAT_Y216, 127 DRM_FORMAT_XYUV8888, 128 DRM_FORMAT_XVYU2101010, 129 DRM_FORMAT_XVYU12_16161616, 130 DRM_FORMAT_XVYU16161616, 131 }; 132 133 static const u32 icl_hdr_plane_formats[] = { 134 DRM_FORMAT_C8, 135 DRM_FORMAT_RGB565, 136 DRM_FORMAT_XRGB8888, 137 DRM_FORMAT_XBGR8888, 138 DRM_FORMAT_ARGB8888, 139 DRM_FORMAT_ABGR8888, 140 DRM_FORMAT_XRGB2101010, 141 DRM_FORMAT_XBGR2101010, 142 DRM_FORMAT_ARGB2101010, 143 DRM_FORMAT_ABGR2101010, 144 DRM_FORMAT_XRGB16161616F, 145 DRM_FORMAT_XBGR16161616F, 146 DRM_FORMAT_ARGB16161616F, 147 DRM_FORMAT_ABGR16161616F, 148 DRM_FORMAT_YUYV, 149 DRM_FORMAT_YVYU, 150 DRM_FORMAT_UYVY, 151 DRM_FORMAT_VYUY, 152 DRM_FORMAT_NV12, 153 DRM_FORMAT_P010, 154 DRM_FORMAT_P012, 155 DRM_FORMAT_P016, 156 DRM_FORMAT_Y210, 157 DRM_FORMAT_Y212, 158 DRM_FORMAT_Y216, 159 DRM_FORMAT_XYUV8888, 160 DRM_FORMAT_XVYU2101010, 161 DRM_FORMAT_XVYU12_16161616, 162 DRM_FORMAT_XVYU16161616, 163 }; 164 165 static const u64 skl_plane_format_modifiers_noccs[] = { 166 I915_FORMAT_MOD_Yf_TILED, 167 I915_FORMAT_MOD_Y_TILED, 168 I915_FORMAT_MOD_X_TILED, 169 DRM_FORMAT_MOD_LINEAR, 170 DRM_FORMAT_MOD_INVALID 171 }; 172 173 static const u64 skl_plane_format_modifiers_ccs[] = { 174 I915_FORMAT_MOD_Yf_TILED_CCS, 175 I915_FORMAT_MOD_Y_TILED_CCS, 176 I915_FORMAT_MOD_Yf_TILED, 177 I915_FORMAT_MOD_Y_TILED, 178 I915_FORMAT_MOD_X_TILED, 179 DRM_FORMAT_MOD_LINEAR, 180 DRM_FORMAT_MOD_INVALID 181 }; 182 183 static const u64 gen12_plane_format_modifiers_mc_ccs[] = { 184 I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS, 185 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, 186 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC, 187 I915_FORMAT_MOD_Y_TILED, 188 I915_FORMAT_MOD_X_TILED, 189 DRM_FORMAT_MOD_LINEAR, 190 DRM_FORMAT_MOD_INVALID 191 }; 192 193 static const u64 gen12_plane_format_modifiers_rc_ccs[] = { 194 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, 195 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC, 196 I915_FORMAT_MOD_Y_TILED, 197 I915_FORMAT_MOD_X_TILED, 198 DRM_FORMAT_MOD_LINEAR, 199 DRM_FORMAT_MOD_INVALID 200 }; 201 202 static const u64 adlp_step_a_plane_format_modifiers[] = { 203 I915_FORMAT_MOD_Y_TILED, 204 I915_FORMAT_MOD_X_TILED, 205 DRM_FORMAT_MOD_LINEAR, 206 DRM_FORMAT_MOD_INVALID 207 }; 208 209 int skl_format_to_fourcc(int format, bool rgb_order, bool alpha) 210 { 211 switch (format) { 212 case PLANE_CTL_FORMAT_RGB_565: 213 return DRM_FORMAT_RGB565; 214 case PLANE_CTL_FORMAT_NV12: 215 return DRM_FORMAT_NV12; 216 case PLANE_CTL_FORMAT_XYUV: 217 return DRM_FORMAT_XYUV8888; 218 case PLANE_CTL_FORMAT_P010: 219 return DRM_FORMAT_P010; 220 case PLANE_CTL_FORMAT_P012: 221 return DRM_FORMAT_P012; 222 case PLANE_CTL_FORMAT_P016: 223 return DRM_FORMAT_P016; 224 case PLANE_CTL_FORMAT_Y210: 225 return DRM_FORMAT_Y210; 226 case PLANE_CTL_FORMAT_Y212: 227 return DRM_FORMAT_Y212; 228 case PLANE_CTL_FORMAT_Y216: 229 return DRM_FORMAT_Y216; 230 case PLANE_CTL_FORMAT_Y410: 231 return DRM_FORMAT_XVYU2101010; 232 case PLANE_CTL_FORMAT_Y412: 233 return DRM_FORMAT_XVYU12_16161616; 234 case PLANE_CTL_FORMAT_Y416: 235 return DRM_FORMAT_XVYU16161616; 236 default: 237 case PLANE_CTL_FORMAT_XRGB_8888: 238 if (rgb_order) { 239 if (alpha) 240 return DRM_FORMAT_ABGR8888; 241 else 242 return DRM_FORMAT_XBGR8888; 243 } else { 244 if (alpha) 245 return DRM_FORMAT_ARGB8888; 246 else 247 return DRM_FORMAT_XRGB8888; 248 } 249 case PLANE_CTL_FORMAT_XRGB_2101010: 250 if (rgb_order) { 251 if (alpha) 252 return DRM_FORMAT_ABGR2101010; 253 else 254 return DRM_FORMAT_XBGR2101010; 255 } else { 256 if (alpha) 257 return DRM_FORMAT_ARGB2101010; 258 else 259 return DRM_FORMAT_XRGB2101010; 260 } 261 case PLANE_CTL_FORMAT_XRGB_16161616F: 262 if (rgb_order) { 263 if (alpha) 264 return DRM_FORMAT_ABGR16161616F; 265 else 266 return DRM_FORMAT_XBGR16161616F; 267 } else { 268 if (alpha) 269 return DRM_FORMAT_ARGB16161616F; 270 else 271 return DRM_FORMAT_XRGB16161616F; 272 } 273 } 274 } 275 276 static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915) 277 { 278 if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915)) 279 return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3); 280 else 281 return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5); 282 } 283 284 bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv, 285 enum plane_id plane_id) 286 { 287 return DISPLAY_VER(dev_priv) >= 11 && 288 icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id); 289 } 290 291 bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id) 292 { 293 return DISPLAY_VER(dev_priv) >= 11 && 294 icl_hdr_plane_mask() & BIT(plane_id); 295 } 296 297 static int icl_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 298 const struct intel_plane_state *plane_state) 299 { 300 unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state); 301 302 /* two pixels per clock */ 303 return DIV_ROUND_UP(pixel_rate, 2); 304 } 305 306 static void 307 glk_plane_ratio(const struct intel_plane_state *plane_state, 308 unsigned int *num, unsigned int *den) 309 { 310 const struct drm_framebuffer *fb = plane_state->hw.fb; 311 312 if (fb->format->cpp[0] == 8) { 313 *num = 10; 314 *den = 8; 315 } else { 316 *num = 1; 317 *den = 1; 318 } 319 } 320 321 static int glk_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 322 const struct intel_plane_state *plane_state) 323 { 324 unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state); 325 unsigned int num, den; 326 327 glk_plane_ratio(plane_state, &num, &den); 328 329 /* two pixels per clock */ 330 return DIV_ROUND_UP(pixel_rate * num, 2 * den); 331 } 332 333 static void 334 skl_plane_ratio(const struct intel_plane_state *plane_state, 335 unsigned int *num, unsigned int *den) 336 { 337 const struct drm_framebuffer *fb = plane_state->hw.fb; 338 339 if (fb->format->cpp[0] == 8) { 340 *num = 9; 341 *den = 8; 342 } else { 343 *num = 1; 344 *den = 1; 345 } 346 } 347 348 static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 349 const struct intel_plane_state *plane_state) 350 { 351 unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state); 352 unsigned int num, den; 353 354 skl_plane_ratio(plane_state, &num, &den); 355 356 return DIV_ROUND_UP(pixel_rate * num, den); 357 } 358 359 static int skl_plane_max_width(const struct drm_framebuffer *fb, 360 int color_plane, 361 unsigned int rotation) 362 { 363 int cpp = fb->format->cpp[color_plane]; 364 365 switch (fb->modifier) { 366 case DRM_FORMAT_MOD_LINEAR: 367 case I915_FORMAT_MOD_X_TILED: 368 /* 369 * Validated limit is 4k, but has 5k should 370 * work apart from the following features: 371 * - Ytile (already limited to 4k) 372 * - FP16 (already limited to 4k) 373 * - render compression (already limited to 4k) 374 * - KVMR sprite and cursor (don't care) 375 * - horizontal panning (TODO verify this) 376 * - pipe and plane scaling (TODO verify this) 377 */ 378 if (cpp == 8) 379 return 4096; 380 else 381 return 5120; 382 case I915_FORMAT_MOD_Y_TILED_CCS: 383 case I915_FORMAT_MOD_Yf_TILED_CCS: 384 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: 385 /* FIXME AUX plane? */ 386 case I915_FORMAT_MOD_Y_TILED: 387 case I915_FORMAT_MOD_Yf_TILED: 388 if (cpp == 8) 389 return 2048; 390 else 391 return 4096; 392 default: 393 MISSING_CASE(fb->modifier); 394 return 2048; 395 } 396 } 397 398 static int glk_plane_max_width(const struct drm_framebuffer *fb, 399 int color_plane, 400 unsigned int rotation) 401 { 402 int cpp = fb->format->cpp[color_plane]; 403 404 switch (fb->modifier) { 405 case DRM_FORMAT_MOD_LINEAR: 406 case I915_FORMAT_MOD_X_TILED: 407 if (cpp == 8) 408 return 4096; 409 else 410 return 5120; 411 case I915_FORMAT_MOD_Y_TILED_CCS: 412 case I915_FORMAT_MOD_Yf_TILED_CCS: 413 /* FIXME AUX plane? */ 414 case I915_FORMAT_MOD_Y_TILED: 415 case I915_FORMAT_MOD_Yf_TILED: 416 if (cpp == 8) 417 return 2048; 418 else 419 return 5120; 420 default: 421 MISSING_CASE(fb->modifier); 422 return 2048; 423 } 424 } 425 426 static int icl_plane_min_width(const struct drm_framebuffer *fb, 427 int color_plane, 428 unsigned int rotation) 429 { 430 /* Wa_14011264657, Wa_14011050563: gen11+ */ 431 switch (fb->format->format) { 432 case DRM_FORMAT_C8: 433 return 18; 434 case DRM_FORMAT_RGB565: 435 return 10; 436 case DRM_FORMAT_XRGB8888: 437 case DRM_FORMAT_XBGR8888: 438 case DRM_FORMAT_ARGB8888: 439 case DRM_FORMAT_ABGR8888: 440 case DRM_FORMAT_XRGB2101010: 441 case DRM_FORMAT_XBGR2101010: 442 case DRM_FORMAT_ARGB2101010: 443 case DRM_FORMAT_ABGR2101010: 444 case DRM_FORMAT_XVYU2101010: 445 case DRM_FORMAT_Y212: 446 case DRM_FORMAT_Y216: 447 return 6; 448 case DRM_FORMAT_NV12: 449 return 20; 450 case DRM_FORMAT_P010: 451 case DRM_FORMAT_P012: 452 case DRM_FORMAT_P016: 453 return 12; 454 case DRM_FORMAT_XRGB16161616F: 455 case DRM_FORMAT_XBGR16161616F: 456 case DRM_FORMAT_ARGB16161616F: 457 case DRM_FORMAT_ABGR16161616F: 458 case DRM_FORMAT_XVYU12_16161616: 459 case DRM_FORMAT_XVYU16161616: 460 return 4; 461 default: 462 return 1; 463 } 464 } 465 466 static int icl_plane_max_width(const struct drm_framebuffer *fb, 467 int color_plane, 468 unsigned int rotation) 469 { 470 return 5120; 471 } 472 473 static int skl_plane_max_height(const struct drm_framebuffer *fb, 474 int color_plane, 475 unsigned int rotation) 476 { 477 return 4096; 478 } 479 480 static int icl_plane_max_height(const struct drm_framebuffer *fb, 481 int color_plane, 482 unsigned int rotation) 483 { 484 return 4320; 485 } 486 487 static unsigned int 488 skl_plane_max_stride(struct intel_plane *plane, 489 u32 pixel_format, u64 modifier, 490 unsigned int rotation) 491 { 492 struct drm_i915_private *i915 = to_i915(plane->base.dev); 493 const struct drm_format_info *info = drm_format_info(pixel_format); 494 int cpp = info->cpp[0]; 495 int max_horizontal_pixels = 8192; 496 int max_stride_bytes; 497 498 if (DISPLAY_VER(i915) >= 13) { 499 /* 500 * The stride in bytes must not exceed of the size 501 * of 128K bytes. For pixel formats of 64bpp will allow 502 * for a 16K pixel surface. 503 */ 504 max_stride_bytes = 131072; 505 if (cpp == 8) 506 max_horizontal_pixels = 16384; 507 else 508 max_horizontal_pixels = 65536; 509 } else { 510 /* 511 * "The stride in bytes must not exceed the 512 * of the size of 8K pixels and 32K bytes." 513 */ 514 max_stride_bytes = 32768; 515 } 516 517 if (drm_rotation_90_or_270(rotation)) 518 return min(max_horizontal_pixels, max_stride_bytes / cpp); 519 else 520 return min(max_horizontal_pixels * cpp, max_stride_bytes); 521 } 522 523 524 /* Preoffset values for YUV to RGB Conversion */ 525 #define PREOFF_YUV_TO_RGB_HI 0x1800 526 #define PREOFF_YUV_TO_RGB_ME 0x0000 527 #define PREOFF_YUV_TO_RGB_LO 0x1800 528 529 #define ROFF(x) (((x) & 0xffff) << 16) 530 #define GOFF(x) (((x) & 0xffff) << 0) 531 #define BOFF(x) (((x) & 0xffff) << 16) 532 533 /* 534 * Programs the input color space conversion stage for ICL HDR planes. 535 * Note that it is assumed that this stage always happens after YUV 536 * range correction. Thus, the input to this stage is assumed to be 537 * in full-range YCbCr. 538 */ 539 static void 540 icl_program_input_csc(struct intel_plane *plane, 541 const struct intel_crtc_state *crtc_state, 542 const struct intel_plane_state *plane_state) 543 { 544 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 545 enum pipe pipe = plane->pipe; 546 enum plane_id plane_id = plane->id; 547 548 static const u16 input_csc_matrix[][9] = { 549 /* 550 * BT.601 full range YCbCr -> full range RGB 551 * The matrix required is : 552 * [1.000, 0.000, 1.371, 553 * 1.000, -0.336, -0.698, 554 * 1.000, 1.732, 0.0000] 555 */ 556 [DRM_COLOR_YCBCR_BT601] = { 557 0x7AF8, 0x7800, 0x0, 558 0x8B28, 0x7800, 0x9AC0, 559 0x0, 0x7800, 0x7DD8, 560 }, 561 /* 562 * BT.709 full range YCbCr -> full range RGB 563 * The matrix required is : 564 * [1.000, 0.000, 1.574, 565 * 1.000, -0.187, -0.468, 566 * 1.000, 1.855, 0.0000] 567 */ 568 [DRM_COLOR_YCBCR_BT709] = { 569 0x7C98, 0x7800, 0x0, 570 0x9EF8, 0x7800, 0xAC00, 571 0x0, 0x7800, 0x7ED8, 572 }, 573 /* 574 * BT.2020 full range YCbCr -> full range RGB 575 * The matrix required is : 576 * [1.000, 0.000, 1.474, 577 * 1.000, -0.1645, -0.5713, 578 * 1.000, 1.8814, 0.0000] 579 */ 580 [DRM_COLOR_YCBCR_BT2020] = { 581 0x7BC8, 0x7800, 0x0, 582 0x8928, 0x7800, 0xAA88, 583 0x0, 0x7800, 0x7F10, 584 }, 585 }; 586 const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding]; 587 588 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), 589 ROFF(csc[0]) | GOFF(csc[1])); 590 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), 591 BOFF(csc[2])); 592 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), 593 ROFF(csc[3]) | GOFF(csc[4])); 594 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), 595 BOFF(csc[5])); 596 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), 597 ROFF(csc[6]) | GOFF(csc[7])); 598 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), 599 BOFF(csc[8])); 600 601 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), 602 PREOFF_YUV_TO_RGB_HI); 603 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 604 PREOFF_YUV_TO_RGB_ME); 605 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), 606 PREOFF_YUV_TO_RGB_LO); 607 intel_de_write_fw(dev_priv, 608 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0); 609 intel_de_write_fw(dev_priv, 610 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0); 611 intel_de_write_fw(dev_priv, 612 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0); 613 } 614 615 static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb, 616 int color_plane, unsigned int rotation) 617 { 618 /* 619 * The stride is either expressed as a multiple of 64 bytes chunks for 620 * linear buffers or in number of tiles for tiled buffers. 621 */ 622 if (is_surface_linear(fb, color_plane)) 623 return 64; 624 else if (drm_rotation_90_or_270(rotation)) 625 return intel_tile_height(fb, color_plane); 626 else 627 return intel_tile_width_bytes(fb, color_plane); 628 } 629 630 static u32 skl_plane_stride(const struct intel_plane_state *plane_state, 631 int color_plane) 632 { 633 const struct drm_framebuffer *fb = plane_state->hw.fb; 634 unsigned int rotation = plane_state->hw.rotation; 635 u32 stride = plane_state->view.color_plane[color_plane].stride; 636 637 if (color_plane >= fb->format->num_planes) 638 return 0; 639 640 return stride / skl_plane_stride_mult(fb, color_plane, rotation); 641 } 642 643 static void 644 skl_disable_plane(struct intel_plane *plane, 645 const struct intel_crtc_state *crtc_state) 646 { 647 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 648 enum plane_id plane_id = plane->id; 649 enum pipe pipe = plane->pipe; 650 unsigned long irqflags; 651 652 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 653 654 if (icl_is_hdr_plane(dev_priv, plane_id)) 655 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0); 656 657 skl_write_plane_wm(plane, crtc_state); 658 659 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0); 660 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0); 661 662 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 663 } 664 665 static bool 666 skl_plane_get_hw_state(struct intel_plane *plane, 667 enum pipe *pipe) 668 { 669 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 670 enum intel_display_power_domain power_domain; 671 enum plane_id plane_id = plane->id; 672 intel_wakeref_t wakeref; 673 bool ret; 674 675 power_domain = POWER_DOMAIN_PIPE(plane->pipe); 676 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 677 if (!wakeref) 678 return false; 679 680 ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; 681 682 *pipe = plane->pipe; 683 684 intel_display_power_put(dev_priv, power_domain, wakeref); 685 686 return ret; 687 } 688 689 static u32 skl_plane_ctl_format(u32 pixel_format) 690 { 691 switch (pixel_format) { 692 case DRM_FORMAT_C8: 693 return PLANE_CTL_FORMAT_INDEXED; 694 case DRM_FORMAT_RGB565: 695 return PLANE_CTL_FORMAT_RGB_565; 696 case DRM_FORMAT_XBGR8888: 697 case DRM_FORMAT_ABGR8888: 698 return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX; 699 case DRM_FORMAT_XRGB8888: 700 case DRM_FORMAT_ARGB8888: 701 return PLANE_CTL_FORMAT_XRGB_8888; 702 case DRM_FORMAT_XBGR2101010: 703 case DRM_FORMAT_ABGR2101010: 704 return PLANE_CTL_FORMAT_XRGB_2101010 | PLANE_CTL_ORDER_RGBX; 705 case DRM_FORMAT_XRGB2101010: 706 case DRM_FORMAT_ARGB2101010: 707 return PLANE_CTL_FORMAT_XRGB_2101010; 708 case DRM_FORMAT_XBGR16161616F: 709 case DRM_FORMAT_ABGR16161616F: 710 return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX; 711 case DRM_FORMAT_XRGB16161616F: 712 case DRM_FORMAT_ARGB16161616F: 713 return PLANE_CTL_FORMAT_XRGB_16161616F; 714 case DRM_FORMAT_XYUV8888: 715 return PLANE_CTL_FORMAT_XYUV; 716 case DRM_FORMAT_YUYV: 717 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV; 718 case DRM_FORMAT_YVYU: 719 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU; 720 case DRM_FORMAT_UYVY: 721 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY; 722 case DRM_FORMAT_VYUY: 723 return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; 724 case DRM_FORMAT_NV12: 725 return PLANE_CTL_FORMAT_NV12; 726 case DRM_FORMAT_P010: 727 return PLANE_CTL_FORMAT_P010; 728 case DRM_FORMAT_P012: 729 return PLANE_CTL_FORMAT_P012; 730 case DRM_FORMAT_P016: 731 return PLANE_CTL_FORMAT_P016; 732 case DRM_FORMAT_Y210: 733 return PLANE_CTL_FORMAT_Y210; 734 case DRM_FORMAT_Y212: 735 return PLANE_CTL_FORMAT_Y212; 736 case DRM_FORMAT_Y216: 737 return PLANE_CTL_FORMAT_Y216; 738 case DRM_FORMAT_XVYU2101010: 739 return PLANE_CTL_FORMAT_Y410; 740 case DRM_FORMAT_XVYU12_16161616: 741 return PLANE_CTL_FORMAT_Y412; 742 case DRM_FORMAT_XVYU16161616: 743 return PLANE_CTL_FORMAT_Y416; 744 default: 745 MISSING_CASE(pixel_format); 746 } 747 748 return 0; 749 } 750 751 static u32 skl_plane_ctl_alpha(const struct intel_plane_state *plane_state) 752 { 753 if (!plane_state->hw.fb->format->has_alpha) 754 return PLANE_CTL_ALPHA_DISABLE; 755 756 switch (plane_state->hw.pixel_blend_mode) { 757 case DRM_MODE_BLEND_PIXEL_NONE: 758 return PLANE_CTL_ALPHA_DISABLE; 759 case DRM_MODE_BLEND_PREMULTI: 760 return PLANE_CTL_ALPHA_SW_PREMULTIPLY; 761 case DRM_MODE_BLEND_COVERAGE: 762 return PLANE_CTL_ALPHA_HW_PREMULTIPLY; 763 default: 764 MISSING_CASE(plane_state->hw.pixel_blend_mode); 765 return PLANE_CTL_ALPHA_DISABLE; 766 } 767 } 768 769 static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state *plane_state) 770 { 771 if (!plane_state->hw.fb->format->has_alpha) 772 return PLANE_COLOR_ALPHA_DISABLE; 773 774 switch (plane_state->hw.pixel_blend_mode) { 775 case DRM_MODE_BLEND_PIXEL_NONE: 776 return PLANE_COLOR_ALPHA_DISABLE; 777 case DRM_MODE_BLEND_PREMULTI: 778 return PLANE_COLOR_ALPHA_SW_PREMULTIPLY; 779 case DRM_MODE_BLEND_COVERAGE: 780 return PLANE_COLOR_ALPHA_HW_PREMULTIPLY; 781 default: 782 MISSING_CASE(plane_state->hw.pixel_blend_mode); 783 return PLANE_COLOR_ALPHA_DISABLE; 784 } 785 } 786 787 static u32 skl_plane_ctl_tiling(u64 fb_modifier) 788 { 789 switch (fb_modifier) { 790 case DRM_FORMAT_MOD_LINEAR: 791 break; 792 case I915_FORMAT_MOD_X_TILED: 793 return PLANE_CTL_TILED_X; 794 case I915_FORMAT_MOD_Y_TILED: 795 return PLANE_CTL_TILED_Y; 796 case I915_FORMAT_MOD_Y_TILED_CCS: 797 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: 798 return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE; 799 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: 800 return PLANE_CTL_TILED_Y | 801 PLANE_CTL_RENDER_DECOMPRESSION_ENABLE | 802 PLANE_CTL_CLEAR_COLOR_DISABLE; 803 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: 804 return PLANE_CTL_TILED_Y | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE; 805 case I915_FORMAT_MOD_Yf_TILED: 806 return PLANE_CTL_TILED_YF; 807 case I915_FORMAT_MOD_Yf_TILED_CCS: 808 return PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE; 809 default: 810 MISSING_CASE(fb_modifier); 811 } 812 813 return 0; 814 } 815 816 static u32 skl_plane_ctl_rotate(unsigned int rotate) 817 { 818 switch (rotate) { 819 case DRM_MODE_ROTATE_0: 820 break; 821 /* 822 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr 823 * while i915 HW rotation is clockwise, thats why this swapping. 824 */ 825 case DRM_MODE_ROTATE_90: 826 return PLANE_CTL_ROTATE_270; 827 case DRM_MODE_ROTATE_180: 828 return PLANE_CTL_ROTATE_180; 829 case DRM_MODE_ROTATE_270: 830 return PLANE_CTL_ROTATE_90; 831 default: 832 MISSING_CASE(rotate); 833 } 834 835 return 0; 836 } 837 838 static u32 cnl_plane_ctl_flip(unsigned int reflect) 839 { 840 switch (reflect) { 841 case 0: 842 break; 843 case DRM_MODE_REFLECT_X: 844 return PLANE_CTL_FLIP_HORIZONTAL; 845 case DRM_MODE_REFLECT_Y: 846 default: 847 MISSING_CASE(reflect); 848 } 849 850 return 0; 851 } 852 853 static u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) 854 { 855 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); 856 u32 plane_ctl = 0; 857 858 if (DISPLAY_VER(dev_priv) >= 10) 859 return plane_ctl; 860 861 if (crtc_state->gamma_enable) 862 plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE; 863 864 if (crtc_state->csc_enable) 865 plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE; 866 867 return plane_ctl; 868 } 869 870 static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, 871 const struct intel_plane_state *plane_state) 872 { 873 struct drm_i915_private *dev_priv = 874 to_i915(plane_state->uapi.plane->dev); 875 const struct drm_framebuffer *fb = plane_state->hw.fb; 876 unsigned int rotation = plane_state->hw.rotation; 877 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 878 u32 plane_ctl; 879 880 plane_ctl = PLANE_CTL_ENABLE; 881 882 if (DISPLAY_VER(dev_priv) < 10) { 883 plane_ctl |= skl_plane_ctl_alpha(plane_state); 884 plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; 885 886 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 887 plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709; 888 889 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 890 plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE; 891 } 892 893 plane_ctl |= skl_plane_ctl_format(fb->format->format); 894 plane_ctl |= skl_plane_ctl_tiling(fb->modifier); 895 plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK); 896 897 if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) 898 plane_ctl |= cnl_plane_ctl_flip(rotation & 899 DRM_MODE_REFLECT_MASK); 900 901 if (key->flags & I915_SET_COLORKEY_DESTINATION) 902 plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION; 903 else if (key->flags & I915_SET_COLORKEY_SOURCE) 904 plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE; 905 906 return plane_ctl; 907 } 908 909 static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state) 910 { 911 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); 912 u32 plane_color_ctl = 0; 913 914 if (DISPLAY_VER(dev_priv) >= 11) 915 return plane_color_ctl; 916 917 if (crtc_state->gamma_enable) 918 plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE; 919 920 if (crtc_state->csc_enable) 921 plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE; 922 923 return plane_color_ctl; 924 } 925 926 static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, 927 const struct intel_plane_state *plane_state) 928 { 929 struct drm_i915_private *dev_priv = 930 to_i915(plane_state->uapi.plane->dev); 931 const struct drm_framebuffer *fb = plane_state->hw.fb; 932 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 933 u32 plane_color_ctl = 0; 934 935 plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; 936 plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state); 937 938 if (fb->format->is_yuv && !icl_is_hdr_plane(dev_priv, plane->id)) { 939 switch (plane_state->hw.color_encoding) { 940 case DRM_COLOR_YCBCR_BT709: 941 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709; 942 break; 943 case DRM_COLOR_YCBCR_BT2020: 944 plane_color_ctl |= 945 PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020; 946 break; 947 default: 948 plane_color_ctl |= 949 PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601; 950 } 951 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 952 plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; 953 } else if (fb->format->is_yuv) { 954 plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE; 955 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 956 plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; 957 } 958 959 return plane_color_ctl; 960 } 961 962 static u32 skl_surf_address(const struct intel_plane_state *plane_state, 963 int color_plane) 964 { 965 const struct drm_framebuffer *fb = plane_state->hw.fb; 966 u32 offset = plane_state->view.color_plane[color_plane].offset; 967 968 if (intel_fb_uses_dpt(fb)) { 969 WARN_ON(offset & 0x1fffff); 970 return offset >> 9; 971 } else { 972 WARN_ON(offset & 0xfff); 973 return offset; 974 } 975 } 976 977 static void 978 skl_program_plane(struct intel_plane *plane, 979 const struct intel_crtc_state *crtc_state, 980 const struct intel_plane_state *plane_state, 981 int color_plane) 982 { 983 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 984 enum plane_id plane_id = plane->id; 985 enum pipe pipe = plane->pipe; 986 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 987 u32 surf_addr = skl_surf_address(plane_state, color_plane); 988 u32 stride = skl_plane_stride(plane_state, color_plane); 989 const struct drm_framebuffer *fb = plane_state->hw.fb; 990 int aux_plane = skl_main_to_aux_plane(fb, color_plane); 991 int crtc_x = plane_state->uapi.dst.x1; 992 int crtc_y = plane_state->uapi.dst.y1; 993 u32 x = plane_state->view.color_plane[color_plane].x; 994 u32 y = plane_state->view.color_plane[color_plane].y; 995 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 996 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 997 u8 alpha = plane_state->hw.alpha >> 8; 998 u32 plane_color_ctl = 0, aux_dist = 0; 999 unsigned long irqflags; 1000 u32 keymsk, keymax; 1001 u32 plane_ctl = plane_state->ctl; 1002 1003 plane_ctl |= skl_plane_ctl_crtc(crtc_state); 1004 1005 if (DISPLAY_VER(dev_priv) >= 10) 1006 plane_color_ctl = plane_state->color_ctl | 1007 glk_plane_color_ctl_crtc(crtc_state); 1008 1009 /* Sizes are 0 based */ 1010 src_w--; 1011 src_h--; 1012 1013 keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha); 1014 1015 keymsk = key->channel_mask & 0x7ffffff; 1016 if (alpha < 0xff) 1017 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE; 1018 1019 /* The scaler will handle the output position */ 1020 if (plane_state->scaler_id >= 0) { 1021 crtc_x = 0; 1022 crtc_y = 0; 1023 } 1024 1025 if (aux_plane) { 1026 aux_dist = skl_surf_address(plane_state, aux_plane) - surf_addr; 1027 1028 if (DISPLAY_VER(dev_priv) < 12) 1029 aux_dist |= skl_plane_stride(plane_state, aux_plane); 1030 } 1031 1032 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1033 1034 intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride); 1035 intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id), 1036 (crtc_y << 16) | crtc_x); 1037 intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id), 1038 (src_h << 16) | src_w); 1039 1040 intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist); 1041 1042 if (icl_is_hdr_plane(dev_priv, plane_id)) 1043 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 1044 plane_state->cus_ctl); 1045 1046 if (DISPLAY_VER(dev_priv) >= 10) 1047 intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), 1048 plane_color_ctl); 1049 1050 if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id)) 1051 icl_program_input_csc(plane, crtc_state, plane_state); 1052 1053 if (fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC) 1054 intel_uncore_write64_fw(&dev_priv->uncore, 1055 PLANE_CC_VAL(pipe, plane_id), plane_state->ccval); 1056 1057 skl_write_plane_wm(plane, crtc_state); 1058 1059 intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), 1060 key->min_value); 1061 intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk); 1062 intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax); 1063 1064 intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id), 1065 (y << 16) | x); 1066 1067 if (DISPLAY_VER(dev_priv) < 11) 1068 intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id), 1069 (plane_state->view.color_plane[1].y << 16) | 1070 plane_state->view.color_plane[1].x); 1071 1072 if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi)) 1073 intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane); 1074 1075 /* 1076 * Enable the scaler before the plane so that we don't 1077 * get a catastrophic underrun even if the two operations 1078 * end up happening in two different frames. 1079 */ 1080 if (plane_state->scaler_id >= 0) 1081 skl_program_plane_scaler(plane, crtc_state, plane_state); 1082 1083 /* 1084 * The control register self-arms if the plane was previously 1085 * disabled. Try to make the plane enable atomic by writing 1086 * the control register just before the surface register. 1087 */ 1088 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); 1089 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 1090 intel_plane_ggtt_offset(plane_state) + surf_addr); 1091 1092 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1093 } 1094 1095 static void 1096 skl_plane_async_flip(struct intel_plane *plane, 1097 const struct intel_crtc_state *crtc_state, 1098 const struct intel_plane_state *plane_state, 1099 bool async_flip) 1100 { 1101 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1102 unsigned long irqflags; 1103 enum plane_id plane_id = plane->id; 1104 enum pipe pipe = plane->pipe; 1105 u32 surf_addr = plane_state->view.color_plane[0].offset; 1106 u32 plane_ctl = plane_state->ctl; 1107 1108 plane_ctl |= skl_plane_ctl_crtc(crtc_state); 1109 1110 if (async_flip) 1111 plane_ctl |= PLANE_CTL_ASYNC_FLIP; 1112 1113 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1114 1115 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); 1116 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 1117 intel_plane_ggtt_offset(plane_state) + surf_addr); 1118 1119 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1120 } 1121 1122 static void 1123 skl_update_plane(struct intel_plane *plane, 1124 const struct intel_crtc_state *crtc_state, 1125 const struct intel_plane_state *plane_state) 1126 { 1127 int color_plane = 0; 1128 1129 if (plane_state->planar_linked_plane && !plane_state->planar_slave) 1130 /* Program the UV plane on planar master */ 1131 color_plane = 1; 1132 1133 skl_program_plane(plane, crtc_state, plane_state, color_plane); 1134 } 1135 1136 static bool intel_format_is_p01x(u32 format) 1137 { 1138 switch (format) { 1139 case DRM_FORMAT_P010: 1140 case DRM_FORMAT_P012: 1141 case DRM_FORMAT_P016: 1142 return true; 1143 default: 1144 return false; 1145 } 1146 } 1147 1148 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, 1149 const struct intel_plane_state *plane_state) 1150 { 1151 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1152 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1153 const struct drm_framebuffer *fb = plane_state->hw.fb; 1154 unsigned int rotation = plane_state->hw.rotation; 1155 1156 if (!fb) 1157 return 0; 1158 1159 if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) && 1160 is_ccs_modifier(fb->modifier)) { 1161 drm_dbg_kms(&dev_priv->drm, 1162 "RC support only with 0/180 degree rotation (%x)\n", 1163 rotation); 1164 return -EINVAL; 1165 } 1166 1167 if (rotation & DRM_MODE_REFLECT_X && 1168 fb->modifier == DRM_FORMAT_MOD_LINEAR) { 1169 drm_dbg_kms(&dev_priv->drm, 1170 "horizontal flip is not supported with linear surface formats\n"); 1171 return -EINVAL; 1172 } 1173 1174 if (drm_rotation_90_or_270(rotation)) { 1175 if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) { 1176 drm_dbg_kms(&dev_priv->drm, 1177 "Y/Yf tiling required for 90/270!\n"); 1178 return -EINVAL; 1179 } 1180 1181 /* 1182 * 90/270 is not allowed with RGB64 16:16:16:16 and 1183 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards. 1184 */ 1185 switch (fb->format->format) { 1186 case DRM_FORMAT_RGB565: 1187 if (DISPLAY_VER(dev_priv) >= 11) 1188 break; 1189 fallthrough; 1190 case DRM_FORMAT_C8: 1191 case DRM_FORMAT_XRGB16161616F: 1192 case DRM_FORMAT_XBGR16161616F: 1193 case DRM_FORMAT_ARGB16161616F: 1194 case DRM_FORMAT_ABGR16161616F: 1195 case DRM_FORMAT_Y210: 1196 case DRM_FORMAT_Y212: 1197 case DRM_FORMAT_Y216: 1198 case DRM_FORMAT_XVYU12_16161616: 1199 case DRM_FORMAT_XVYU16161616: 1200 drm_dbg_kms(&dev_priv->drm, 1201 "Unsupported pixel format %p4cc for 90/270!\n", 1202 &fb->format->format); 1203 return -EINVAL; 1204 default: 1205 break; 1206 } 1207 } 1208 1209 /* Y-tiling is not supported in IF-ID Interlace mode */ 1210 if (crtc_state->hw.enable && 1211 crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE && 1212 (fb->modifier == I915_FORMAT_MOD_Y_TILED || 1213 fb->modifier == I915_FORMAT_MOD_Yf_TILED || 1214 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 1215 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS || 1216 fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || 1217 fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS || 1218 fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC)) { 1219 drm_dbg_kms(&dev_priv->drm, 1220 "Y/Yf tiling not supported in IF-ID mode\n"); 1221 return -EINVAL; 1222 } 1223 1224 /* Wa_1606054188:tgl,adl-s */ 1225 if ((IS_ALDERLAKE_S(dev_priv) || IS_TIGERLAKE(dev_priv)) && 1226 plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE && 1227 intel_format_is_p01x(fb->format->format)) { 1228 drm_dbg_kms(&dev_priv->drm, 1229 "Source color keying not supported with P01x formats\n"); 1230 return -EINVAL; 1231 } 1232 1233 return 0; 1234 } 1235 1236 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state, 1237 const struct intel_plane_state *plane_state) 1238 { 1239 struct drm_i915_private *dev_priv = 1240 to_i915(plane_state->uapi.plane->dev); 1241 int crtc_x = plane_state->uapi.dst.x1; 1242 int crtc_w = drm_rect_width(&plane_state->uapi.dst); 1243 int pipe_src_w = crtc_state->pipe_src_w; 1244 1245 /* 1246 * Display WA #1175: cnl,glk 1247 * Planes other than the cursor may cause FIFO underflow and display 1248 * corruption if starting less than 4 pixels from the right edge of 1249 * the screen. 1250 * Besides the above WA fix the similar problem, where planes other 1251 * than the cursor ending less than 4 pixels from the left edge of the 1252 * screen may cause FIFO underflow and display corruption. 1253 */ 1254 if (DISPLAY_VER(dev_priv) == 10 && 1255 (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { 1256 drm_dbg_kms(&dev_priv->drm, 1257 "requested plane X %s position %d invalid (valid range %d-%d)\n", 1258 crtc_x + crtc_w < 4 ? "end" : "start", 1259 crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x, 1260 4, pipe_src_w - 4); 1261 return -ERANGE; 1262 } 1263 1264 return 0; 1265 } 1266 1267 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) 1268 { 1269 const struct drm_framebuffer *fb = plane_state->hw.fb; 1270 unsigned int rotation = plane_state->hw.rotation; 1271 int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1272 1273 /* Display WA #1106 */ 1274 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 1275 src_w & 3 && 1276 (rotation == DRM_MODE_ROTATE_270 || 1277 rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { 1278 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); 1279 return -EINVAL; 1280 } 1281 1282 return 0; 1283 } 1284 1285 static int skl_plane_max_scale(struct drm_i915_private *dev_priv, 1286 const struct drm_framebuffer *fb) 1287 { 1288 /* 1289 * We don't yet know the final source width nor 1290 * whether we can use the HQ scaler mode. Assume 1291 * the best case. 1292 * FIXME need to properly check this later. 1293 */ 1294 if (DISPLAY_VER(dev_priv) >= 10 || 1295 !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) 1296 return 0x30000 - 1; 1297 else 1298 return 0x20000 - 1; 1299 } 1300 1301 static int intel_plane_min_width(struct intel_plane *plane, 1302 const struct drm_framebuffer *fb, 1303 int color_plane, 1304 unsigned int rotation) 1305 { 1306 if (plane->min_width) 1307 return plane->min_width(fb, color_plane, rotation); 1308 else 1309 return 1; 1310 } 1311 1312 static int intel_plane_max_width(struct intel_plane *plane, 1313 const struct drm_framebuffer *fb, 1314 int color_plane, 1315 unsigned int rotation) 1316 { 1317 if (plane->max_width) 1318 return plane->max_width(fb, color_plane, rotation); 1319 else 1320 return INT_MAX; 1321 } 1322 1323 static int intel_plane_max_height(struct intel_plane *plane, 1324 const struct drm_framebuffer *fb, 1325 int color_plane, 1326 unsigned int rotation) 1327 { 1328 if (plane->max_height) 1329 return plane->max_height(fb, color_plane, rotation); 1330 else 1331 return INT_MAX; 1332 } 1333 1334 static bool 1335 skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state, 1336 int main_x, int main_y, u32 main_offset, 1337 int ccs_plane) 1338 { 1339 const struct drm_framebuffer *fb = plane_state->hw.fb; 1340 int aux_x = plane_state->view.color_plane[ccs_plane].x; 1341 int aux_y = plane_state->view.color_plane[ccs_plane].y; 1342 u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset; 1343 u32 alignment = intel_surf_alignment(fb, ccs_plane); 1344 int hsub; 1345 int vsub; 1346 1347 intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane); 1348 while (aux_offset >= main_offset && aux_y <= main_y) { 1349 int x, y; 1350 1351 if (aux_x == main_x && aux_y == main_y) 1352 break; 1353 1354 if (aux_offset == 0) 1355 break; 1356 1357 x = aux_x / hsub; 1358 y = aux_y / vsub; 1359 aux_offset = intel_plane_adjust_aligned_offset(&x, &y, 1360 plane_state, 1361 ccs_plane, 1362 aux_offset, 1363 aux_offset - 1364 alignment); 1365 aux_x = x * hsub + aux_x % hsub; 1366 aux_y = y * vsub + aux_y % vsub; 1367 } 1368 1369 if (aux_x != main_x || aux_y != main_y) 1370 return false; 1371 1372 plane_state->view.color_plane[ccs_plane].offset = aux_offset; 1373 plane_state->view.color_plane[ccs_plane].x = aux_x; 1374 plane_state->view.color_plane[ccs_plane].y = aux_y; 1375 1376 return true; 1377 } 1378 1379 1380 int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state, 1381 int *x, int *y, u32 *offset) 1382 { 1383 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1384 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1385 const struct drm_framebuffer *fb = plane_state->hw.fb; 1386 const int aux_plane = skl_main_to_aux_plane(fb, 0); 1387 const u32 aux_offset = plane_state->view.color_plane[aux_plane].offset; 1388 const u32 alignment = intel_surf_alignment(fb, 0); 1389 const int w = drm_rect_width(&plane_state->uapi.src) >> 16; 1390 1391 intel_add_fb_offsets(x, y, plane_state, 0); 1392 *offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0); 1393 if (drm_WARN_ON(&dev_priv->drm, alignment && !is_power_of_2(alignment))) 1394 return -EINVAL; 1395 1396 /* 1397 * AUX surface offset is specified as the distance from the 1398 * main surface offset, and it must be non-negative. Make 1399 * sure that is what we will get. 1400 */ 1401 if (aux_plane && *offset > aux_offset) 1402 *offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0, 1403 *offset, 1404 aux_offset & ~(alignment - 1)); 1405 1406 /* 1407 * When using an X-tiled surface, the plane blows up 1408 * if the x offset + width exceed the stride. 1409 * 1410 * TODO: linear and Y-tiled seem fine, Yf untested, 1411 */ 1412 if (fb->modifier == I915_FORMAT_MOD_X_TILED) { 1413 int cpp = fb->format->cpp[0]; 1414 1415 while ((*x + w) * cpp > plane_state->view.color_plane[0].stride) { 1416 if (*offset == 0) { 1417 drm_dbg_kms(&dev_priv->drm, 1418 "Unable to find suitable display surface offset due to X-tiling\n"); 1419 return -EINVAL; 1420 } 1421 1422 *offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0, 1423 *offset, 1424 *offset - alignment); 1425 } 1426 } 1427 1428 return 0; 1429 } 1430 1431 static int skl_check_main_surface(struct intel_plane_state *plane_state) 1432 { 1433 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1434 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1435 const struct drm_framebuffer *fb = plane_state->hw.fb; 1436 const unsigned int rotation = plane_state->hw.rotation; 1437 int x = plane_state->uapi.src.x1 >> 16; 1438 int y = plane_state->uapi.src.y1 >> 16; 1439 const int w = drm_rect_width(&plane_state->uapi.src) >> 16; 1440 const int h = drm_rect_height(&plane_state->uapi.src) >> 16; 1441 const int min_width = intel_plane_min_width(plane, fb, 0, rotation); 1442 const int max_width = intel_plane_max_width(plane, fb, 0, rotation); 1443 const int max_height = intel_plane_max_height(plane, fb, 0, rotation); 1444 const int aux_plane = skl_main_to_aux_plane(fb, 0); 1445 const u32 alignment = intel_surf_alignment(fb, 0); 1446 u32 offset; 1447 int ret; 1448 1449 if (w > max_width || w < min_width || h > max_height) { 1450 drm_dbg_kms(&dev_priv->drm, 1451 "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n", 1452 w, h, min_width, max_width, max_height); 1453 return -EINVAL; 1454 } 1455 1456 ret = skl_calc_main_surface_offset(plane_state, &x, &y, &offset); 1457 if (ret) 1458 return ret; 1459 1460 /* 1461 * CCS AUX surface doesn't have its own x/y offsets, we must make sure 1462 * they match with the main surface x/y offsets. 1463 */ 1464 if (is_ccs_modifier(fb->modifier)) { 1465 while (!skl_check_main_ccs_coordinates(plane_state, x, y, 1466 offset, aux_plane)) { 1467 if (offset == 0) 1468 break; 1469 1470 offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0, 1471 offset, offset - alignment); 1472 } 1473 1474 if (x != plane_state->view.color_plane[aux_plane].x || 1475 y != plane_state->view.color_plane[aux_plane].y) { 1476 drm_dbg_kms(&dev_priv->drm, 1477 "Unable to find suitable display surface offset due to CCS\n"); 1478 return -EINVAL; 1479 } 1480 } 1481 1482 if (DISPLAY_VER(dev_priv) >= 13) 1483 drm_WARN_ON(&dev_priv->drm, x > 65535 || y > 65535); 1484 else 1485 drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191); 1486 1487 plane_state->view.color_plane[0].offset = offset; 1488 plane_state->view.color_plane[0].x = x; 1489 plane_state->view.color_plane[0].y = y; 1490 1491 /* 1492 * Put the final coordinates back so that the src 1493 * coordinate checks will see the right values. 1494 */ 1495 drm_rect_translate_to(&plane_state->uapi.src, 1496 x << 16, y << 16); 1497 1498 return 0; 1499 } 1500 1501 static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) 1502 { 1503 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1504 struct drm_i915_private *i915 = to_i915(plane->base.dev); 1505 const struct drm_framebuffer *fb = plane_state->hw.fb; 1506 unsigned int rotation = plane_state->hw.rotation; 1507 int uv_plane = 1; 1508 int max_width = intel_plane_max_width(plane, fb, uv_plane, rotation); 1509 int max_height = intel_plane_max_height(plane, fb, uv_plane, rotation); 1510 int x = plane_state->uapi.src.x1 >> 17; 1511 int y = plane_state->uapi.src.y1 >> 17; 1512 int w = drm_rect_width(&plane_state->uapi.src) >> 17; 1513 int h = drm_rect_height(&plane_state->uapi.src) >> 17; 1514 u32 offset; 1515 1516 /* FIXME not quite sure how/if these apply to the chroma plane */ 1517 if (w > max_width || h > max_height) { 1518 drm_dbg_kms(&i915->drm, 1519 "CbCr source size %dx%d too big (limit %dx%d)\n", 1520 w, h, max_width, max_height); 1521 return -EINVAL; 1522 } 1523 1524 intel_add_fb_offsets(&x, &y, plane_state, uv_plane); 1525 offset = intel_plane_compute_aligned_offset(&x, &y, 1526 plane_state, uv_plane); 1527 1528 if (is_ccs_modifier(fb->modifier)) { 1529 int ccs_plane = main_to_ccs_plane(fb, uv_plane); 1530 u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset; 1531 u32 alignment = intel_surf_alignment(fb, uv_plane); 1532 1533 if (offset > aux_offset) 1534 offset = intel_plane_adjust_aligned_offset(&x, &y, 1535 plane_state, 1536 uv_plane, 1537 offset, 1538 aux_offset & ~(alignment - 1)); 1539 1540 while (!skl_check_main_ccs_coordinates(plane_state, x, y, 1541 offset, ccs_plane)) { 1542 if (offset == 0) 1543 break; 1544 1545 offset = intel_plane_adjust_aligned_offset(&x, &y, 1546 plane_state, 1547 uv_plane, 1548 offset, offset - alignment); 1549 } 1550 1551 if (x != plane_state->view.color_plane[ccs_plane].x || 1552 y != plane_state->view.color_plane[ccs_plane].y) { 1553 drm_dbg_kms(&i915->drm, 1554 "Unable to find suitable display surface offset due to CCS\n"); 1555 return -EINVAL; 1556 } 1557 } 1558 1559 if (DISPLAY_VER(i915) >= 13) 1560 drm_WARN_ON(&i915->drm, x > 65535 || y > 65535); 1561 else 1562 drm_WARN_ON(&i915->drm, x > 8191 || y > 8191); 1563 1564 plane_state->view.color_plane[uv_plane].offset = offset; 1565 plane_state->view.color_plane[uv_plane].x = x; 1566 plane_state->view.color_plane[uv_plane].y = y; 1567 1568 return 0; 1569 } 1570 1571 static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state) 1572 { 1573 const struct drm_framebuffer *fb = plane_state->hw.fb; 1574 int src_x = plane_state->uapi.src.x1 >> 16; 1575 int src_y = plane_state->uapi.src.y1 >> 16; 1576 u32 offset; 1577 int ccs_plane; 1578 1579 for (ccs_plane = 0; ccs_plane < fb->format->num_planes; ccs_plane++) { 1580 int main_hsub, main_vsub; 1581 int hsub, vsub; 1582 int x, y; 1583 1584 if (!is_ccs_plane(fb, ccs_plane) || 1585 is_gen12_ccs_cc_plane(fb, ccs_plane)) 1586 continue; 1587 1588 intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb, 1589 skl_ccs_to_main_plane(fb, ccs_plane)); 1590 intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane); 1591 1592 hsub *= main_hsub; 1593 vsub *= main_vsub; 1594 x = src_x / hsub; 1595 y = src_y / vsub; 1596 1597 intel_add_fb_offsets(&x, &y, plane_state, ccs_plane); 1598 1599 offset = intel_plane_compute_aligned_offset(&x, &y, 1600 plane_state, 1601 ccs_plane); 1602 1603 plane_state->view.color_plane[ccs_plane].offset = offset; 1604 plane_state->view.color_plane[ccs_plane].x = (x * hsub + src_x % hsub) / main_hsub; 1605 plane_state->view.color_plane[ccs_plane].y = (y * vsub + src_y % vsub) / main_vsub; 1606 } 1607 1608 return 0; 1609 } 1610 1611 static int skl_check_plane_surface(struct intel_plane_state *plane_state) 1612 { 1613 const struct drm_framebuffer *fb = plane_state->hw.fb; 1614 int ret; 1615 1616 ret = intel_plane_compute_gtt(plane_state); 1617 if (ret) 1618 return ret; 1619 1620 if (!plane_state->uapi.visible) 1621 return 0; 1622 1623 /* 1624 * Handle the AUX surface first since the main surface setup depends on 1625 * it. 1626 */ 1627 if (is_ccs_modifier(fb->modifier)) { 1628 ret = skl_check_ccs_aux_surface(plane_state); 1629 if (ret) 1630 return ret; 1631 } 1632 1633 if (intel_format_info_is_yuv_semiplanar(fb->format, 1634 fb->modifier)) { 1635 ret = skl_check_nv12_aux_surface(plane_state); 1636 if (ret) 1637 return ret; 1638 } 1639 1640 ret = skl_check_main_surface(plane_state); 1641 if (ret) 1642 return ret; 1643 1644 return 0; 1645 } 1646 1647 static bool skl_fb_scalable(const struct drm_framebuffer *fb) 1648 { 1649 if (!fb) 1650 return false; 1651 1652 switch (fb->format->format) { 1653 case DRM_FORMAT_C8: 1654 return false; 1655 case DRM_FORMAT_XRGB16161616F: 1656 case DRM_FORMAT_ARGB16161616F: 1657 case DRM_FORMAT_XBGR16161616F: 1658 case DRM_FORMAT_ABGR16161616F: 1659 return DISPLAY_VER(to_i915(fb->dev)) >= 11; 1660 default: 1661 return true; 1662 } 1663 } 1664 1665 static int skl_plane_check(struct intel_crtc_state *crtc_state, 1666 struct intel_plane_state *plane_state) 1667 { 1668 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1669 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1670 const struct drm_framebuffer *fb = plane_state->hw.fb; 1671 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1672 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1673 int ret; 1674 1675 ret = skl_plane_check_fb(crtc_state, plane_state); 1676 if (ret) 1677 return ret; 1678 1679 /* use scaler when colorkey is not required */ 1680 if (!plane_state->ckey.flags && skl_fb_scalable(fb)) { 1681 min_scale = 1; 1682 max_scale = skl_plane_max_scale(dev_priv, fb); 1683 } 1684 1685 ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 1686 min_scale, max_scale, true); 1687 if (ret) 1688 return ret; 1689 1690 ret = skl_check_plane_surface(plane_state); 1691 if (ret) 1692 return ret; 1693 1694 if (!plane_state->uapi.visible) 1695 return 0; 1696 1697 ret = skl_plane_check_dst_coordinates(crtc_state, plane_state); 1698 if (ret) 1699 return ret; 1700 1701 ret = intel_plane_check_src_coordinates(plane_state); 1702 if (ret) 1703 return ret; 1704 1705 ret = skl_plane_check_nv12_rotation(plane_state); 1706 if (ret) 1707 return ret; 1708 1709 /* HW only has 8 bits pixel precision, disable plane if invisible */ 1710 if (!(plane_state->hw.alpha >> 8)) 1711 plane_state->uapi.visible = false; 1712 1713 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); 1714 1715 if (DISPLAY_VER(dev_priv) >= 10) 1716 plane_state->color_ctl = glk_plane_color_ctl(crtc_state, 1717 plane_state); 1718 1719 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 1720 icl_is_hdr_plane(dev_priv, plane->id)) 1721 /* Enable and use MPEG-2 chroma siting */ 1722 plane_state->cus_ctl = PLANE_CUS_ENABLE | 1723 PLANE_CUS_HPHASE_0 | 1724 PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25; 1725 else 1726 plane_state->cus_ctl = 0; 1727 1728 return 0; 1729 } 1730 1731 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, 1732 enum pipe pipe, enum plane_id plane_id) 1733 { 1734 if (!HAS_FBC(dev_priv)) 1735 return false; 1736 1737 return pipe == PIPE_A && plane_id == PLANE_PRIMARY; 1738 } 1739 1740 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, 1741 enum pipe pipe, enum plane_id plane_id) 1742 { 1743 /* Display WA #0870: skl, bxt */ 1744 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) 1745 return false; 1746 1747 if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C) 1748 return false; 1749 1750 if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) 1751 return false; 1752 1753 return true; 1754 } 1755 1756 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, 1757 enum pipe pipe, enum plane_id plane_id, 1758 int *num_formats) 1759 { 1760 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 1761 *num_formats = ARRAY_SIZE(skl_planar_formats); 1762 return skl_planar_formats; 1763 } else { 1764 *num_formats = ARRAY_SIZE(skl_plane_formats); 1765 return skl_plane_formats; 1766 } 1767 } 1768 1769 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, 1770 enum pipe pipe, enum plane_id plane_id, 1771 int *num_formats) 1772 { 1773 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 1774 *num_formats = ARRAY_SIZE(glk_planar_formats); 1775 return glk_planar_formats; 1776 } else { 1777 *num_formats = ARRAY_SIZE(skl_plane_formats); 1778 return skl_plane_formats; 1779 } 1780 } 1781 1782 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv, 1783 enum pipe pipe, enum plane_id plane_id, 1784 int *num_formats) 1785 { 1786 if (icl_is_hdr_plane(dev_priv, plane_id)) { 1787 *num_formats = ARRAY_SIZE(icl_hdr_plane_formats); 1788 return icl_hdr_plane_formats; 1789 } else if (icl_is_nv12_y_plane(dev_priv, plane_id)) { 1790 *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats); 1791 return icl_sdr_y_plane_formats; 1792 } else { 1793 *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats); 1794 return icl_sdr_uv_plane_formats; 1795 } 1796 } 1797 1798 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 1799 enum pipe pipe, enum plane_id plane_id) 1800 { 1801 if (plane_id == PLANE_CURSOR) 1802 return false; 1803 1804 if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) 1805 return true; 1806 1807 if (IS_GEMINILAKE(dev_priv)) 1808 return pipe != PIPE_C; 1809 1810 return pipe != PIPE_C && 1811 (plane_id == PLANE_PRIMARY || 1812 plane_id == PLANE_SPRITE0); 1813 } 1814 1815 static bool skl_plane_format_mod_supported(struct drm_plane *_plane, 1816 u32 format, u64 modifier) 1817 { 1818 struct intel_plane *plane = to_intel_plane(_plane); 1819 1820 switch (modifier) { 1821 case DRM_FORMAT_MOD_LINEAR: 1822 case I915_FORMAT_MOD_X_TILED: 1823 case I915_FORMAT_MOD_Y_TILED: 1824 case I915_FORMAT_MOD_Yf_TILED: 1825 break; 1826 case I915_FORMAT_MOD_Y_TILED_CCS: 1827 case I915_FORMAT_MOD_Yf_TILED_CCS: 1828 if (!plane->has_ccs) 1829 return false; 1830 break; 1831 default: 1832 return false; 1833 } 1834 1835 switch (format) { 1836 case DRM_FORMAT_XRGB8888: 1837 case DRM_FORMAT_XBGR8888: 1838 case DRM_FORMAT_ARGB8888: 1839 case DRM_FORMAT_ABGR8888: 1840 if (is_ccs_modifier(modifier)) 1841 return true; 1842 fallthrough; 1843 case DRM_FORMAT_RGB565: 1844 case DRM_FORMAT_XRGB2101010: 1845 case DRM_FORMAT_XBGR2101010: 1846 case DRM_FORMAT_ARGB2101010: 1847 case DRM_FORMAT_ABGR2101010: 1848 case DRM_FORMAT_YUYV: 1849 case DRM_FORMAT_YVYU: 1850 case DRM_FORMAT_UYVY: 1851 case DRM_FORMAT_VYUY: 1852 case DRM_FORMAT_NV12: 1853 case DRM_FORMAT_XYUV8888: 1854 case DRM_FORMAT_P010: 1855 case DRM_FORMAT_P012: 1856 case DRM_FORMAT_P016: 1857 case DRM_FORMAT_XVYU2101010: 1858 if (modifier == I915_FORMAT_MOD_Yf_TILED) 1859 return true; 1860 fallthrough; 1861 case DRM_FORMAT_C8: 1862 case DRM_FORMAT_XBGR16161616F: 1863 case DRM_FORMAT_ABGR16161616F: 1864 case DRM_FORMAT_XRGB16161616F: 1865 case DRM_FORMAT_ARGB16161616F: 1866 case DRM_FORMAT_Y210: 1867 case DRM_FORMAT_Y212: 1868 case DRM_FORMAT_Y216: 1869 case DRM_FORMAT_XVYU12_16161616: 1870 case DRM_FORMAT_XVYU16161616: 1871 if (modifier == DRM_FORMAT_MOD_LINEAR || 1872 modifier == I915_FORMAT_MOD_X_TILED || 1873 modifier == I915_FORMAT_MOD_Y_TILED) 1874 return true; 1875 fallthrough; 1876 default: 1877 return false; 1878 } 1879 } 1880 1881 static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv, 1882 enum plane_id plane_id) 1883 { 1884 /* Wa_14010477008:tgl[a0..c0],rkl[all],dg1[all] */ 1885 if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv) || 1886 IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0)) 1887 return false; 1888 1889 /* Wa_22011186057 */ 1890 if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0)) 1891 return false; 1892 1893 return plane_id < PLANE_SPRITE4; 1894 } 1895 1896 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, 1897 u32 format, u64 modifier) 1898 { 1899 struct drm_i915_private *dev_priv = to_i915(_plane->dev); 1900 struct intel_plane *plane = to_intel_plane(_plane); 1901 1902 switch (modifier) { 1903 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: 1904 if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id)) 1905 return false; 1906 fallthrough; 1907 case DRM_FORMAT_MOD_LINEAR: 1908 case I915_FORMAT_MOD_X_TILED: 1909 case I915_FORMAT_MOD_Y_TILED: 1910 break; 1911 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: 1912 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: 1913 /* Wa_22011186057 */ 1914 if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0)) 1915 return false; 1916 break; 1917 default: 1918 return false; 1919 } 1920 1921 switch (format) { 1922 case DRM_FORMAT_XRGB8888: 1923 case DRM_FORMAT_XBGR8888: 1924 case DRM_FORMAT_ARGB8888: 1925 case DRM_FORMAT_ABGR8888: 1926 if (is_ccs_modifier(modifier)) 1927 return true; 1928 fallthrough; 1929 case DRM_FORMAT_YUYV: 1930 case DRM_FORMAT_YVYU: 1931 case DRM_FORMAT_UYVY: 1932 case DRM_FORMAT_VYUY: 1933 case DRM_FORMAT_NV12: 1934 case DRM_FORMAT_XYUV8888: 1935 case DRM_FORMAT_P010: 1936 case DRM_FORMAT_P012: 1937 case DRM_FORMAT_P016: 1938 if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) 1939 return true; 1940 fallthrough; 1941 case DRM_FORMAT_RGB565: 1942 case DRM_FORMAT_XRGB2101010: 1943 case DRM_FORMAT_XBGR2101010: 1944 case DRM_FORMAT_ARGB2101010: 1945 case DRM_FORMAT_ABGR2101010: 1946 case DRM_FORMAT_XVYU2101010: 1947 case DRM_FORMAT_C8: 1948 case DRM_FORMAT_XBGR16161616F: 1949 case DRM_FORMAT_ABGR16161616F: 1950 case DRM_FORMAT_XRGB16161616F: 1951 case DRM_FORMAT_ARGB16161616F: 1952 case DRM_FORMAT_Y210: 1953 case DRM_FORMAT_Y212: 1954 case DRM_FORMAT_Y216: 1955 case DRM_FORMAT_XVYU12_16161616: 1956 case DRM_FORMAT_XVYU16161616: 1957 if (modifier == DRM_FORMAT_MOD_LINEAR || 1958 modifier == I915_FORMAT_MOD_X_TILED || 1959 modifier == I915_FORMAT_MOD_Y_TILED) 1960 return true; 1961 fallthrough; 1962 default: 1963 return false; 1964 } 1965 } 1966 1967 static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv, 1968 enum plane_id plane_id) 1969 { 1970 /* Wa_22011186057 */ 1971 if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0)) 1972 return adlp_step_a_plane_format_modifiers; 1973 else if (gen12_plane_supports_mc_ccs(dev_priv, plane_id)) 1974 return gen12_plane_format_modifiers_mc_ccs; 1975 else 1976 return gen12_plane_format_modifiers_rc_ccs; 1977 } 1978 1979 static const struct drm_plane_funcs skl_plane_funcs = { 1980 .update_plane = drm_atomic_helper_update_plane, 1981 .disable_plane = drm_atomic_helper_disable_plane, 1982 .destroy = intel_plane_destroy, 1983 .atomic_duplicate_state = intel_plane_duplicate_state, 1984 .atomic_destroy_state = intel_plane_destroy_state, 1985 .format_mod_supported = skl_plane_format_mod_supported, 1986 }; 1987 1988 static const struct drm_plane_funcs gen12_plane_funcs = { 1989 .update_plane = drm_atomic_helper_update_plane, 1990 .disable_plane = drm_atomic_helper_disable_plane, 1991 .destroy = intel_plane_destroy, 1992 .atomic_duplicate_state = intel_plane_duplicate_state, 1993 .atomic_destroy_state = intel_plane_destroy_state, 1994 .format_mod_supported = gen12_plane_format_mod_supported, 1995 }; 1996 1997 static void 1998 skl_plane_enable_flip_done(struct intel_plane *plane) 1999 { 2000 struct drm_i915_private *i915 = to_i915(plane->base.dev); 2001 enum pipe pipe = plane->pipe; 2002 2003 spin_lock_irq(&i915->irq_lock); 2004 bdw_enable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id)); 2005 spin_unlock_irq(&i915->irq_lock); 2006 } 2007 2008 static void 2009 skl_plane_disable_flip_done(struct intel_plane *plane) 2010 { 2011 struct drm_i915_private *i915 = to_i915(plane->base.dev); 2012 enum pipe pipe = plane->pipe; 2013 2014 spin_lock_irq(&i915->irq_lock); 2015 bdw_disable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id)); 2016 spin_unlock_irq(&i915->irq_lock); 2017 } 2018 2019 struct intel_plane * 2020 skl_universal_plane_create(struct drm_i915_private *dev_priv, 2021 enum pipe pipe, enum plane_id plane_id) 2022 { 2023 const struct drm_plane_funcs *plane_funcs; 2024 struct intel_plane *plane; 2025 enum drm_plane_type plane_type; 2026 unsigned int supported_rotations; 2027 unsigned int supported_csc; 2028 const u64 *modifiers; 2029 const u32 *formats; 2030 int num_formats; 2031 int ret; 2032 2033 plane = intel_plane_alloc(); 2034 if (IS_ERR(plane)) 2035 return plane; 2036 2037 plane->pipe = pipe; 2038 plane->id = plane_id; 2039 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id); 2040 2041 plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id); 2042 if (plane->has_fbc) { 2043 struct intel_fbc *fbc = &dev_priv->fbc; 2044 2045 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; 2046 } 2047 2048 if (DISPLAY_VER(dev_priv) >= 11) { 2049 plane->min_width = icl_plane_min_width; 2050 plane->max_width = icl_plane_max_width; 2051 plane->max_height = icl_plane_max_height; 2052 plane->min_cdclk = icl_plane_min_cdclk; 2053 } else if (DISPLAY_VER(dev_priv) >= 10) { 2054 plane->max_width = glk_plane_max_width; 2055 plane->max_height = skl_plane_max_height; 2056 plane->min_cdclk = glk_plane_min_cdclk; 2057 } else { 2058 plane->max_width = skl_plane_max_width; 2059 plane->max_height = skl_plane_max_height; 2060 plane->min_cdclk = skl_plane_min_cdclk; 2061 } 2062 2063 plane->max_stride = skl_plane_max_stride; 2064 plane->update_plane = skl_update_plane; 2065 plane->disable_plane = skl_disable_plane; 2066 plane->get_hw_state = skl_plane_get_hw_state; 2067 plane->check_plane = skl_plane_check; 2068 2069 if (plane_id == PLANE_PRIMARY) { 2070 plane->need_async_flip_disable_wa = IS_DISPLAY_VER(dev_priv, 2071 9, 10); 2072 plane->async_flip = skl_plane_async_flip; 2073 plane->enable_flip_done = skl_plane_enable_flip_done; 2074 plane->disable_flip_done = skl_plane_disable_flip_done; 2075 } 2076 2077 if (DISPLAY_VER(dev_priv) >= 11) 2078 formats = icl_get_plane_formats(dev_priv, pipe, 2079 plane_id, &num_formats); 2080 else if (DISPLAY_VER(dev_priv) >= 10) 2081 formats = glk_get_plane_formats(dev_priv, pipe, 2082 plane_id, &num_formats); 2083 else 2084 formats = skl_get_plane_formats(dev_priv, pipe, 2085 plane_id, &num_formats); 2086 2087 plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id); 2088 if (DISPLAY_VER(dev_priv) >= 12) { 2089 modifiers = gen12_get_plane_modifiers(dev_priv, plane_id); 2090 plane_funcs = &gen12_plane_funcs; 2091 } else { 2092 if (plane->has_ccs) 2093 modifiers = skl_plane_format_modifiers_ccs; 2094 else 2095 modifiers = skl_plane_format_modifiers_noccs; 2096 plane_funcs = &skl_plane_funcs; 2097 } 2098 2099 if (plane_id == PLANE_PRIMARY) 2100 plane_type = DRM_PLANE_TYPE_PRIMARY; 2101 else 2102 plane_type = DRM_PLANE_TYPE_OVERLAY; 2103 2104 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 2105 0, plane_funcs, 2106 formats, num_formats, modifiers, 2107 plane_type, 2108 "plane %d%c", plane_id + 1, 2109 pipe_name(pipe)); 2110 if (ret) 2111 goto fail; 2112 2113 if (DISPLAY_VER(dev_priv) >= 13) 2114 supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 2115 else 2116 supported_rotations = 2117 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | 2118 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; 2119 2120 if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) 2121 supported_rotations |= DRM_MODE_REFLECT_X; 2122 2123 drm_plane_create_rotation_property(&plane->base, 2124 DRM_MODE_ROTATE_0, 2125 supported_rotations); 2126 2127 supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709); 2128 2129 if (DISPLAY_VER(dev_priv) >= 10) 2130 supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020); 2131 2132 drm_plane_create_color_properties(&plane->base, 2133 supported_csc, 2134 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 2135 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 2136 DRM_COLOR_YCBCR_BT709, 2137 DRM_COLOR_YCBCR_LIMITED_RANGE); 2138 2139 drm_plane_create_alpha_property(&plane->base); 2140 drm_plane_create_blend_mode_property(&plane->base, 2141 BIT(DRM_MODE_BLEND_PIXEL_NONE) | 2142 BIT(DRM_MODE_BLEND_PREMULTI) | 2143 BIT(DRM_MODE_BLEND_COVERAGE)); 2144 2145 drm_plane_create_zpos_immutable_property(&plane->base, plane_id); 2146 2147 if (DISPLAY_VER(dev_priv) >= 12) 2148 drm_plane_enable_fb_damage_clips(&plane->base); 2149 2150 if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) 2151 drm_plane_create_scaling_filter_property(&plane->base, 2152 BIT(DRM_SCALING_FILTER_DEFAULT) | 2153 BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR)); 2154 2155 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 2156 2157 return plane; 2158 2159 fail: 2160 intel_plane_free(plane); 2161 2162 return ERR_PTR(ret); 2163 } 2164 2165 void 2166 skl_get_initial_plane_config(struct intel_crtc *crtc, 2167 struct intel_initial_plane_config *plane_config) 2168 { 2169 struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); 2170 struct drm_device *dev = crtc->base.dev; 2171 struct drm_i915_private *dev_priv = to_i915(dev); 2172 struct intel_plane *plane = to_intel_plane(crtc->base.primary); 2173 enum plane_id plane_id = plane->id; 2174 enum pipe pipe; 2175 u32 val, base, offset, stride_mult, tiling, alpha; 2176 int fourcc, pixel_format; 2177 unsigned int aligned_height; 2178 struct drm_framebuffer *fb; 2179 struct intel_framebuffer *intel_fb; 2180 2181 if (!plane->get_hw_state(plane, &pipe)) 2182 return; 2183 2184 drm_WARN_ON(dev, pipe != crtc->pipe); 2185 2186 if (crtc_state->bigjoiner) { 2187 drm_dbg_kms(&dev_priv->drm, 2188 "Unsupported bigjoiner configuration for initial FB\n"); 2189 return; 2190 } 2191 2192 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 2193 if (!intel_fb) { 2194 drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n"); 2195 return; 2196 } 2197 2198 fb = &intel_fb->base; 2199 2200 fb->dev = dev; 2201 2202 val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id)); 2203 2204 if (DISPLAY_VER(dev_priv) >= 11) 2205 pixel_format = val & ICL_PLANE_CTL_FORMAT_MASK; 2206 else 2207 pixel_format = val & PLANE_CTL_FORMAT_MASK; 2208 2209 if (DISPLAY_VER(dev_priv) >= 10) { 2210 alpha = intel_de_read(dev_priv, 2211 PLANE_COLOR_CTL(pipe, plane_id)); 2212 alpha &= PLANE_COLOR_ALPHA_MASK; 2213 } else { 2214 alpha = val & PLANE_CTL_ALPHA_MASK; 2215 } 2216 2217 fourcc = skl_format_to_fourcc(pixel_format, 2218 val & PLANE_CTL_ORDER_RGBX, alpha); 2219 fb->format = drm_format_info(fourcc); 2220 2221 tiling = val & PLANE_CTL_TILED_MASK; 2222 switch (tiling) { 2223 case PLANE_CTL_TILED_LINEAR: 2224 fb->modifier = DRM_FORMAT_MOD_LINEAR; 2225 break; 2226 case PLANE_CTL_TILED_X: 2227 plane_config->tiling = I915_TILING_X; 2228 fb->modifier = I915_FORMAT_MOD_X_TILED; 2229 break; 2230 case PLANE_CTL_TILED_Y: 2231 plane_config->tiling = I915_TILING_Y; 2232 if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE) 2233 fb->modifier = DISPLAY_VER(dev_priv) >= 12 ? 2234 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS : 2235 I915_FORMAT_MOD_Y_TILED_CCS; 2236 else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE) 2237 fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; 2238 else 2239 fb->modifier = I915_FORMAT_MOD_Y_TILED; 2240 break; 2241 case PLANE_CTL_TILED_YF: 2242 if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE) 2243 fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS; 2244 else 2245 fb->modifier = I915_FORMAT_MOD_Yf_TILED; 2246 break; 2247 default: 2248 MISSING_CASE(tiling); 2249 goto error; 2250 } 2251 2252 /* 2253 * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr 2254 * while i915 HW rotation is clockwise, thats why this swapping. 2255 */ 2256 switch (val & PLANE_CTL_ROTATE_MASK) { 2257 case PLANE_CTL_ROTATE_0: 2258 plane_config->rotation = DRM_MODE_ROTATE_0; 2259 break; 2260 case PLANE_CTL_ROTATE_90: 2261 plane_config->rotation = DRM_MODE_ROTATE_270; 2262 break; 2263 case PLANE_CTL_ROTATE_180: 2264 plane_config->rotation = DRM_MODE_ROTATE_180; 2265 break; 2266 case PLANE_CTL_ROTATE_270: 2267 plane_config->rotation = DRM_MODE_ROTATE_90; 2268 break; 2269 } 2270 2271 if ((DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) && val & PLANE_CTL_FLIP_HORIZONTAL) 2272 plane_config->rotation |= DRM_MODE_REFLECT_X; 2273 2274 /* 90/270 degree rotation would require extra work */ 2275 if (drm_rotation_90_or_270(plane_config->rotation)) 2276 goto error; 2277 2278 base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000; 2279 plane_config->base = base; 2280 2281 offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id)); 2282 2283 val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id)); 2284 fb->height = ((val >> 16) & 0xffff) + 1; 2285 fb->width = ((val >> 0) & 0xffff) + 1; 2286 2287 val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id)); 2288 stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0); 2289 2290 if (DISPLAY_VER(dev_priv) >= 13) 2291 fb->pitches[0] = (val & PLANE_STRIDE_MASK_XELPD) * stride_mult; 2292 else 2293 fb->pitches[0] = (val & PLANE_STRIDE_MASK) * stride_mult; 2294 2295 aligned_height = intel_fb_align_height(fb, 0, fb->height); 2296 2297 plane_config->size = fb->pitches[0] * aligned_height; 2298 2299 drm_dbg_kms(&dev_priv->drm, 2300 "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", 2301 crtc->base.name, plane->base.name, fb->width, fb->height, 2302 fb->format->cpp[0] * 8, base, fb->pitches[0], 2303 plane_config->size); 2304 2305 plane_config->fb = intel_fb; 2306 return; 2307 2308 error: 2309 kfree(intel_fb); 2310 } 2311