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