aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sprite.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sprite.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c737
1 files changed, 516 insertions, 221 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 5fd2f7bf3927..abe193815ccc 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -40,6 +40,7 @@
40#include "intel_frontbuffer.h" 40#include "intel_frontbuffer.h"
41#include <drm/i915_drm.h> 41#include <drm/i915_drm.h>
42#include "i915_drv.h" 42#include "i915_drv.h"
43#include <drm/drm_color_mgmt.h>
43 44
44int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 45int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
45 int usecs) 46 int usecs)
@@ -275,17 +276,24 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
275 src->y2 = (src_y + src_h) << 16; 276 src->y2 = (src_y + src_h) << 16;
276 277
277 if (fb->format->is_yuv && 278 if (fb->format->is_yuv &&
278 fb->format->format != DRM_FORMAT_NV12 &&
279 (src_x & 1 || src_w & 1)) { 279 (src_x & 1 || src_w & 1)) {
280 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n", 280 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
281 src_x, src_w); 281 src_x, src_w);
282 return -EINVAL; 282 return -EINVAL;
283 } 283 }
284 284
285 if (fb->format->is_yuv &&
286 fb->format->num_planes > 1 &&
287 (src_y & 1 || src_h & 1)) {
288 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of 2 for planar YUV planes\n",
289 src_y, src_h);
290 return -EINVAL;
291 }
292
285 return 0; 293 return 0;
286} 294}
287 295
288unsigned int 296static unsigned int
289skl_plane_max_stride(struct intel_plane *plane, 297skl_plane_max_stride(struct intel_plane *plane,
290 u32 pixel_format, u64 modifier, 298 u32 pixel_format, u64 modifier,
291 unsigned int rotation) 299 unsigned int rotation)
@@ -302,35 +310,201 @@ skl_plane_max_stride(struct intel_plane *plane,
302 return min(8192 * cpp, 32768); 310 return min(8192 * cpp, 32768);
303} 311}
304 312
305void 313static void
306skl_update_plane(struct intel_plane *plane, 314skl_program_scaler(struct intel_plane *plane,
307 const struct intel_crtc_state *crtc_state, 315 const struct intel_crtc_state *crtc_state,
308 const struct intel_plane_state *plane_state) 316 const struct intel_plane_state *plane_state)
317{
318 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
319 enum pipe pipe = plane->pipe;
320 int scaler_id = plane_state->scaler_id;
321 const struct intel_scaler *scaler =
322 &crtc_state->scaler_state.scalers[scaler_id];
323 int crtc_x = plane_state->base.dst.x1;
324 int crtc_y = plane_state->base.dst.y1;
325 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
326 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
327 u16 y_hphase, uv_rgb_hphase;
328 u16 y_vphase, uv_rgb_vphase;
329 int hscale, vscale;
330
331 hscale = drm_rect_calc_hscale(&plane_state->base.src,
332 &plane_state->base.dst,
333 0, INT_MAX);
334 vscale = drm_rect_calc_vscale(&plane_state->base.src,
335 &plane_state->base.dst,
336 0, INT_MAX);
337
338 /* TODO: handle sub-pixel coordinates */
339 if (plane_state->base.fb->format->format == DRM_FORMAT_NV12 &&
340 !icl_is_hdr_plane(plane)) {
341 y_hphase = skl_scaler_calc_phase(1, hscale, false);
342 y_vphase = skl_scaler_calc_phase(1, vscale, false);
343
344 /* MPEG2 chroma siting convention */
345 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
346 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
347 } else {
348 /* not used */
349 y_hphase = 0;
350 y_vphase = 0;
351
352 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
353 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
354 }
355
356 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
357 PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
358 I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
359 PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
360 I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
361 PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
362 I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
363 I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
364}
365
366/* Preoffset values for YUV to RGB Conversion */
367#define PREOFF_YUV_TO_RGB_HI 0x1800
368#define PREOFF_YUV_TO_RGB_ME 0x1F00
369#define PREOFF_YUV_TO_RGB_LO 0x1800
370
371#define ROFF(x) (((x) & 0xffff) << 16)
372#define GOFF(x) (((x) & 0xffff) << 0)
373#define BOFF(x) (((x) & 0xffff) << 16)
374
375static void
376icl_program_input_csc_coeff(const struct intel_crtc_state *crtc_state,
377 const struct intel_plane_state *plane_state)
378{
379 struct drm_i915_private *dev_priv =
380 to_i915(plane_state->base.plane->dev);
381 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
382 enum pipe pipe = crtc->pipe;
383 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
384 enum plane_id plane_id = plane->id;
385
386 static const u16 input_csc_matrix[][9] = {
387 /*
388 * BT.601 full range YCbCr -> full range RGB
389 * The matrix required is :
390 * [1.000, 0.000, 1.371,
391 * 1.000, -0.336, -0.698,
392 * 1.000, 1.732, 0.0000]
393 */
394 [DRM_COLOR_YCBCR_BT601] = {
395 0x7AF8, 0x7800, 0x0,
396 0x8B28, 0x7800, 0x9AC0,
397 0x0, 0x7800, 0x7DD8,
398 },
399 /*
400 * BT.709 full range YCbCr -> full range RGB
401 * The matrix required is :
402 * [1.000, 0.000, 1.574,
403 * 1.000, -0.187, -0.468,
404 * 1.000, 1.855, 0.0000]
405 */
406 [DRM_COLOR_YCBCR_BT709] = {
407 0x7C98, 0x7800, 0x0,
408 0x9EF8, 0x7800, 0xABF8,
409 0x0, 0x7800, 0x7ED8,
410 },
411 };
412
413 /* Matrix for Limited Range to Full Range Conversion */
414 static const u16 input_csc_matrix_lr[][9] = {
415 /*
416 * BT.601 Limted range YCbCr -> full range RGB
417 * The matrix required is :
418 * [1.164384, 0.000, 1.596370,
419 * 1.138393, -0.382500, -0.794598,
420 * 1.138393, 1.971696, 0.0000]
421 */
422 [DRM_COLOR_YCBCR_BT601] = {
423 0x7CC8, 0x7950, 0x0,
424 0x8CB8, 0x7918, 0x9C40,
425 0x0, 0x7918, 0x7FC8,
426 },
427 /*
428 * BT.709 Limited range YCbCr -> full range RGB
429 * The matrix required is :
430 * [1.164, 0.000, 1.833671,
431 * 1.138393, -0.213249, -0.532909,
432 * 1.138393, 2.112402, 0.0000]
433 */
434 [DRM_COLOR_YCBCR_BT709] = {
435 0x7EA8, 0x7950, 0x0,
436 0x8888, 0x7918, 0xADA8,
437 0x0, 0x7918, 0x6870,
438 },
439 };
440 const u16 *csc;
441
442 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
443 csc = input_csc_matrix[plane_state->base.color_encoding];
444 else
445 csc = input_csc_matrix_lr[plane_state->base.color_encoding];
446
447 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) |
448 GOFF(csc[1]));
449 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2]));
450 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) |
451 GOFF(csc[4]));
452 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5]));
453 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) |
454 GOFF(csc[7]));
455 I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8]));
456
457 I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
458 PREOFF_YUV_TO_RGB_HI);
459 I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
460 PREOFF_YUV_TO_RGB_ME);
461 I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
462 PREOFF_YUV_TO_RGB_LO);
463 I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
464 I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
465 I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
466}
467
468static void
469skl_program_plane(struct intel_plane *plane,
470 const struct intel_crtc_state *crtc_state,
471 const struct intel_plane_state *plane_state,
472 int color_plane, bool slave, u32 plane_ctl)
309{ 473{
310 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 474 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
311 const struct drm_framebuffer *fb = plane_state->base.fb;
312 enum plane_id plane_id = plane->id; 475 enum plane_id plane_id = plane->id;
313 enum pipe pipe = plane->pipe; 476 enum pipe pipe = plane->pipe;
314 u32 plane_ctl = plane_state->ctl;
315 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 477 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
316 u32 surf_addr = plane_state->color_plane[0].offset; 478 u32 surf_addr = plane_state->color_plane[color_plane].offset;
317 u32 stride = skl_plane_stride(plane_state, 0); 479 u32 stride = skl_plane_stride(plane_state, color_plane);
318 u32 aux_stride = skl_plane_stride(plane_state, 1); 480 u32 aux_stride = skl_plane_stride(plane_state, 1);
319 int crtc_x = plane_state->base.dst.x1; 481 int crtc_x = plane_state->base.dst.x1;
320 int crtc_y = plane_state->base.dst.y1; 482 int crtc_y = plane_state->base.dst.y1;
321 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 483 uint32_t x = plane_state->color_plane[color_plane].x;
322 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 484 uint32_t y = plane_state->color_plane[color_plane].y;
323 uint32_t x = plane_state->color_plane[0].x;
324 uint32_t y = plane_state->color_plane[0].y;
325 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; 485 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
326 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; 486 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
487 struct intel_plane *linked = plane_state->linked_plane;
488 const struct drm_framebuffer *fb = plane_state->base.fb;
489 u8 alpha = plane_state->base.alpha >> 8;
327 unsigned long irqflags; 490 unsigned long irqflags;
491 u32 keymsk, keymax;
328 492
329 /* Sizes are 0 based */ 493 /* Sizes are 0 based */
330 src_w--; 494 src_w--;
331 src_h--; 495 src_h--;
332 crtc_w--; 496
333 crtc_h--; 497 keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
498
499 keymsk = key->channel_mask & 0x3ffffff;
500 if (alpha < 0xff)
501 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
502
503 /* The scaler will handle the output position */
504 if (plane_state->scaler_id >= 0) {
505 crtc_x = 0;
506 crtc_y = 0;
507 }
334 508
335 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 509 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
336 510
@@ -338,71 +512,83 @@ skl_update_plane(struct intel_plane *plane,
338 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), 512 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
339 plane_state->color_ctl); 513 plane_state->color_ctl);
340 514
341 if (key->flags) { 515 if (fb->format->is_yuv && icl_is_hdr_plane(plane))
342 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 516 icl_program_input_csc_coeff(crtc_state, plane_state);
343 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value); 517
344 I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), key->channel_mask); 518 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
345 } 519 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
520 I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
346 521
347 I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x); 522 I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
348 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); 523 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
349 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); 524 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
350 I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), 525 I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
351 (plane_state->color_plane[1].offset - surf_addr) | aux_stride); 526 (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
352 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
353 (plane_state->color_plane[1].y << 16) |
354 plane_state->color_plane[1].x);
355 527
356 /* program plane scaler */ 528 if (INTEL_GEN(dev_priv) < 11)
357 if (plane_state->scaler_id >= 0) { 529 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
358 int scaler_id = plane_state->scaler_id; 530 (plane_state->color_plane[1].y << 16) |
359 const struct intel_scaler *scaler = 531 plane_state->color_plane[1].x);
360 &crtc_state->scaler_state.scalers[scaler_id]; 532
361 u16 y_hphase, uv_rgb_hphase; 533 if (icl_is_hdr_plane(plane)) {
362 u16 y_vphase, uv_rgb_vphase; 534 u32 cus_ctl = 0;
363 535
364 /* TODO: handle sub-pixel coordinates */ 536 if (linked) {
365 if (fb->format->format == DRM_FORMAT_NV12) { 537 /* Enable and use MPEG-2 chroma siting */
366 y_hphase = skl_scaler_calc_phase(1, false); 538 cus_ctl = PLANE_CUS_ENABLE |
367 y_vphase = skl_scaler_calc_phase(1, false); 539 PLANE_CUS_HPHASE_0 |
368 540 PLANE_CUS_VPHASE_SIGN_NEGATIVE |
369 /* MPEG2 chroma siting convention */ 541 PLANE_CUS_VPHASE_0_25;
370 uv_rgb_hphase = skl_scaler_calc_phase(2, true); 542
371 uv_rgb_vphase = skl_scaler_calc_phase(2, false); 543 if (linked->id == PLANE_SPRITE5)
372 } else { 544 cus_ctl |= PLANE_CUS_PLANE_7;
373 /* not used */ 545 else if (linked->id == PLANE_SPRITE4)
374 y_hphase = 0; 546 cus_ctl |= PLANE_CUS_PLANE_6;
375 y_vphase = 0; 547 else
376 548 MISSING_CASE(linked->id);
377 uv_rgb_hphase = skl_scaler_calc_phase(1, false);
378 uv_rgb_vphase = skl_scaler_calc_phase(1, false);
379 } 549 }
380 550
381 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), 551 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
382 PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
383 I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
384 I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
385 PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
386 I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
387 PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
388 I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
389 I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
390 ((crtc_w + 1) << 16)|(crtc_h + 1));
391
392 I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
393 } else {
394 I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
395 } 552 }
396 553
554 if (!slave && plane_state->scaler_id >= 0)
555 skl_program_scaler(plane, crtc_state, plane_state);
556
557 I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
558
397 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); 559 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
398 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 560 I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
399 intel_plane_ggtt_offset(plane_state) + surf_addr); 561 intel_plane_ggtt_offset(plane_state) + surf_addr);
400 POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
401 562
402 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 563 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
403} 564}
404 565
405void 566static void
567skl_update_plane(struct intel_plane *plane,
568 const struct intel_crtc_state *crtc_state,
569 const struct intel_plane_state *plane_state)
570{
571 int color_plane = 0;
572
573 if (plane_state->linked_plane) {
574 /* Program the UV plane */
575 color_plane = 1;
576 }
577
578 skl_program_plane(plane, crtc_state, plane_state,
579 color_plane, false, plane_state->ctl);
580}
581
582static void
583icl_update_slave(struct intel_plane *plane,
584 const struct intel_crtc_state *crtc_state,
585 const struct intel_plane_state *plane_state)
586{
587 skl_program_plane(plane, crtc_state, plane_state, 0, true,
588 plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
589}
590
591static void
406skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc) 592skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
407{ 593{
408 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 594 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
@@ -413,14 +599,12 @@ skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
413 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 599 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
414 600
415 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0); 601 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
416
417 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0); 602 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
418 POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
419 603
420 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 604 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
421} 605}
422 606
423bool 607static bool
424skl_plane_get_hw_state(struct intel_plane *plane, 608skl_plane_get_hw_state(struct intel_plane *plane,
425 enum pipe *pipe) 609 enum pipe *pipe)
426{ 610{
@@ -613,7 +797,6 @@ vlv_update_plane(struct intel_plane *plane,
613 const struct intel_plane_state *plane_state) 797 const struct intel_plane_state *plane_state)
614{ 798{
615 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 799 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
616 const struct drm_framebuffer *fb = plane_state->base.fb;
617 enum pipe pipe = plane->pipe; 800 enum pipe pipe = plane->pipe;
618 enum plane_id plane_id = plane->id; 801 enum plane_id plane_id = plane->id;
619 u32 sprctl = plane_state->ctl; 802 u32 sprctl = plane_state->ctl;
@@ -650,10 +833,8 @@ vlv_update_plane(struct intel_plane *plane,
650 plane_state->color_plane[0].stride); 833 plane_state->color_plane[0].stride);
651 I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 834 I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
652 835
653 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 836 I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
654 I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x); 837 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
655 else
656 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
657 838
658 I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0); 839 I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
659 840
@@ -661,7 +842,6 @@ vlv_update_plane(struct intel_plane *plane,
661 I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl); 842 I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
662 I915_WRITE_FW(SPSURF(pipe, plane_id), 843 I915_WRITE_FW(SPSURF(pipe, plane_id),
663 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 844 intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
664 POSTING_READ_FW(SPSURF(pipe, plane_id));
665 845
666 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 846 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
667} 847}
@@ -677,9 +857,7 @@ vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
677 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 857 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
678 858
679 I915_WRITE_FW(SPCNTR(pipe, plane_id), 0); 859 I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
680
681 I915_WRITE_FW(SPSURF(pipe, plane_id), 0); 860 I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
682 POSTING_READ_FW(SPSURF(pipe, plane_id));
683 861
684 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 862 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
685} 863}
@@ -774,7 +952,6 @@ ivb_update_plane(struct intel_plane *plane,
774 const struct intel_plane_state *plane_state) 952 const struct intel_plane_state *plane_state)
775{ 953{
776 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 954 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
777 const struct drm_framebuffer *fb = plane_state->base.fb;
778 enum pipe pipe = plane->pipe; 955 enum pipe pipe = plane->pipe;
779 u32 sprctl = plane_state->ctl, sprscale = 0; 956 u32 sprctl = plane_state->ctl, sprscale = 0;
780 u32 sprsurf_offset = plane_state->color_plane[0].offset; 957 u32 sprsurf_offset = plane_state->color_plane[0].offset;
@@ -814,12 +991,12 @@ ivb_update_plane(struct intel_plane *plane,
814 991
815 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 992 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
816 * register */ 993 * register */
817 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 994 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
818 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x); 995 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
819 else if (fb->modifier == I915_FORMAT_MOD_X_TILED) 996 } else {
820 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x); 997 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
821 else
822 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset); 998 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
999 }
823 1000
824 I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 1001 I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
825 if (IS_IVYBRIDGE(dev_priv)) 1002 if (IS_IVYBRIDGE(dev_priv))
@@ -827,7 +1004,6 @@ ivb_update_plane(struct intel_plane *plane,
827 I915_WRITE_FW(SPRCTL(pipe), sprctl); 1004 I915_WRITE_FW(SPRCTL(pipe), sprctl);
828 I915_WRITE_FW(SPRSURF(pipe), 1005 I915_WRITE_FW(SPRSURF(pipe),
829 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1006 intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
830 POSTING_READ_FW(SPRSURF(pipe));
831 1007
832 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1008 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
833} 1009}
@@ -845,9 +1021,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
845 /* Can't leave the scaler enabled... */ 1021 /* Can't leave the scaler enabled... */
846 if (IS_IVYBRIDGE(dev_priv)) 1022 if (IS_IVYBRIDGE(dev_priv))
847 I915_WRITE_FW(SPRSCALE(pipe), 0); 1023 I915_WRITE_FW(SPRSCALE(pipe), 0);
848
849 I915_WRITE_FW(SPRSURF(pipe), 0); 1024 I915_WRITE_FW(SPRSURF(pipe), 0);
850 POSTING_READ_FW(SPRSURF(pipe));
851 1025
852 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1026 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
853} 1027}
@@ -946,7 +1120,6 @@ g4x_update_plane(struct intel_plane *plane,
946 const struct intel_plane_state *plane_state) 1120 const struct intel_plane_state *plane_state)
947{ 1121{
948 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1122 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
949 const struct drm_framebuffer *fb = plane_state->base.fb;
950 enum pipe pipe = plane->pipe; 1123 enum pipe pipe = plane->pipe;
951 u32 dvscntr = plane_state->ctl, dvsscale = 0; 1124 u32 dvscntr = plane_state->ctl, dvsscale = 0;
952 u32 dvssurf_offset = plane_state->color_plane[0].offset; 1125 u32 dvssurf_offset = plane_state->color_plane[0].offset;
@@ -984,17 +1157,14 @@ g4x_update_plane(struct intel_plane *plane,
984 I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride); 1157 I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
985 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 1158 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
986 1159
987 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1160 I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
988 I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x); 1161 I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
989 else
990 I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
991 1162
992 I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 1163 I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
993 I915_WRITE_FW(DVSSCALE(pipe), dvsscale); 1164 I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
994 I915_WRITE_FW(DVSCNTR(pipe), dvscntr); 1165 I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
995 I915_WRITE_FW(DVSSURF(pipe), 1166 I915_WRITE_FW(DVSSURF(pipe),
996 intel_plane_ggtt_offset(plane_state) + dvssurf_offset); 1167 intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
997 POSTING_READ_FW(DVSSURF(pipe));
998 1168
999 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1169 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1000} 1170}
@@ -1011,9 +1181,7 @@ g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
1011 I915_WRITE_FW(DVSCNTR(pipe), 0); 1181 I915_WRITE_FW(DVSCNTR(pipe), 0);
1012 /* Disable the scaler */ 1182 /* Disable the scaler */
1013 I915_WRITE_FW(DVSSCALE(pipe), 0); 1183 I915_WRITE_FW(DVSSCALE(pipe), 0);
1014
1015 I915_WRITE_FW(DVSSURF(pipe), 0); 1184 I915_WRITE_FW(DVSSURF(pipe), 0);
1016 POSTING_READ_FW(DVSSURF(pipe));
1017 1185
1018 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1186 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1019} 1187}
@@ -1039,6 +1207,19 @@ g4x_plane_get_hw_state(struct intel_plane *plane,
1039 return ret; 1207 return ret;
1040} 1208}
1041 1209
1210static bool intel_fb_scalable(const struct drm_framebuffer *fb)
1211{
1212 if (!fb)
1213 return false;
1214
1215 switch (fb->format->format) {
1216 case DRM_FORMAT_C8:
1217 return false;
1218 default:
1219 return true;
1220 }
1221}
1222
1042static int 1223static int
1043g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state, 1224g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1044 struct intel_plane_state *plane_state) 1225 struct intel_plane_state *plane_state)
@@ -1106,18 +1287,18 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
1106{ 1287{
1107 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1288 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1108 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1289 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1109 int max_scale, min_scale; 1290 int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1291 int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1110 int ret; 1292 int ret;
1111 1293
1112 if (INTEL_GEN(dev_priv) < 7) { 1294 if (intel_fb_scalable(plane_state->base.fb)) {
1113 min_scale = 1; 1295 if (INTEL_GEN(dev_priv) < 7) {
1114 max_scale = 16 << 16; 1296 min_scale = 1;
1115 } else if (IS_IVYBRIDGE(dev_priv)) { 1297 max_scale = 16 << 16;
1116 min_scale = 1; 1298 } else if (IS_IVYBRIDGE(dev_priv)) {
1117 max_scale = 2 << 16; 1299 min_scale = 1;
1118 } else { 1300 max_scale = 2 << 16;
1119 min_scale = DRM_PLANE_HELPER_NO_SCALING; 1301 }
1120 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1121 } 1302 }
1122 1303
1123 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1304 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
@@ -1204,6 +1385,8 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
1204static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, 1385static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1205 const struct intel_plane_state *plane_state) 1386 const struct intel_plane_state *plane_state)
1206{ 1387{
1388 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1389 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1207 const struct drm_framebuffer *fb = plane_state->base.fb; 1390 const struct drm_framebuffer *fb = plane_state->base.fb;
1208 unsigned int rotation = plane_state->base.rotation; 1391 unsigned int rotation = plane_state->base.rotation;
1209 struct drm_format_name_buf format_name; 1392 struct drm_format_name_buf format_name;
@@ -1232,13 +1415,17 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1232 } 1415 }
1233 1416
1234 /* 1417 /*
1235 * 90/270 is not allowed with RGB64 16:16:16:16, 1418 * 90/270 is not allowed with RGB64 16:16:16:16 and
1236 * RGB 16-bit 5:6:5, and Indexed 8-bit. 1419 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
1237 * TBD: Add RGB64 case once its added in supported format list. 1420 * TBD: Add RGB64 case once its added in supported format
1421 * list.
1238 */ 1422 */
1239 switch (fb->format->format) { 1423 switch (fb->format->format) {
1240 case DRM_FORMAT_C8:
1241 case DRM_FORMAT_RGB565: 1424 case DRM_FORMAT_RGB565:
1425 if (INTEL_GEN(dev_priv) >= 11)
1426 break;
1427 /* fall through */
1428 case DRM_FORMAT_C8:
1242 DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", 1429 DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1243 drm_get_format_name(fb->format->format, 1430 drm_get_format_name(fb->format->format,
1244 &format_name)); 1431 &format_name));
@@ -1292,12 +1479,31 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
1292 return 0; 1479 return 0;
1293} 1480}
1294 1481
1295int skl_plane_check(struct intel_crtc_state *crtc_state, 1482static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
1296 struct intel_plane_state *plane_state) 1483{
1484 const struct drm_framebuffer *fb = plane_state->base.fb;
1485 unsigned int rotation = plane_state->base.rotation;
1486 int src_w = drm_rect_width(&plane_state->base.src) >> 16;
1487
1488 /* Display WA #1106 */
1489 if (fb->format->format == DRM_FORMAT_NV12 && src_w & 3 &&
1490 (rotation == DRM_MODE_ROTATE_270 ||
1491 rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
1492 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated NV12\n");
1493 return -EINVAL;
1494 }
1495
1496 return 0;
1497}
1498
1499static int skl_plane_check(struct intel_crtc_state *crtc_state,
1500 struct intel_plane_state *plane_state)
1297{ 1501{
1298 struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 1502 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1299 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1503 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1300 int max_scale, min_scale; 1504 const struct drm_framebuffer *fb = plane_state->base.fb;
1505 int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1506 int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1301 int ret; 1507 int ret;
1302 1508
1303 ret = skl_plane_check_fb(crtc_state, plane_state); 1509 ret = skl_plane_check_fb(crtc_state, plane_state);
@@ -1305,15 +1511,9 @@ int skl_plane_check(struct intel_crtc_state *crtc_state,
1305 return ret; 1511 return ret;
1306 1512
1307 /* use scaler when colorkey is not required */ 1513 /* use scaler when colorkey is not required */
1308 if (!plane_state->ckey.flags) { 1514 if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
1309 const struct drm_framebuffer *fb = plane_state->base.fb;
1310
1311 min_scale = 1; 1515 min_scale = 1;
1312 max_scale = skl_max_scale(crtc_state, 1516 max_scale = skl_max_scale(crtc_state, fb->format->format);
1313 fb ? fb->format->format : 0);
1314 } else {
1315 min_scale = DRM_PLANE_HELPER_NO_SCALING;
1316 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1317 } 1517 }
1318 1518
1319 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 1519 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
@@ -1334,10 +1534,18 @@ int skl_plane_check(struct intel_crtc_state *crtc_state,
1334 if (ret) 1534 if (ret)
1335 return ret; 1535 return ret;
1336 1536
1537 ret = skl_plane_check_nv12_rotation(plane_state);
1538 if (ret)
1539 return ret;
1540
1337 ret = skl_check_plane_surface(plane_state); 1541 ret = skl_check_plane_surface(plane_state);
1338 if (ret) 1542 if (ret)
1339 return ret; 1543 return ret;
1340 1544
1545 /* HW only has 8 bits pixel precision, disable plane if invisible */
1546 if (!(plane_state->base.alpha >> 8))
1547 plane_state->base.visible = false;
1548
1341 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); 1549 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1342 1550
1343 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 1551 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
@@ -1502,24 +1710,30 @@ static const uint32_t vlv_plane_formats[] = {
1502 DRM_FORMAT_VYUY, 1710 DRM_FORMAT_VYUY,
1503}; 1711};
1504 1712
1505static uint32_t skl_plane_formats[] = { 1713static const uint32_t skl_plane_formats[] = {
1714 DRM_FORMAT_C8,
1506 DRM_FORMAT_RGB565, 1715 DRM_FORMAT_RGB565,
1507 DRM_FORMAT_ABGR8888,
1508 DRM_FORMAT_ARGB8888,
1509 DRM_FORMAT_XBGR8888,
1510 DRM_FORMAT_XRGB8888, 1716 DRM_FORMAT_XRGB8888,
1717 DRM_FORMAT_XBGR8888,
1718 DRM_FORMAT_ARGB8888,
1719 DRM_FORMAT_ABGR8888,
1720 DRM_FORMAT_XRGB2101010,
1721 DRM_FORMAT_XBGR2101010,
1511 DRM_FORMAT_YUYV, 1722 DRM_FORMAT_YUYV,
1512 DRM_FORMAT_YVYU, 1723 DRM_FORMAT_YVYU,
1513 DRM_FORMAT_UYVY, 1724 DRM_FORMAT_UYVY,
1514 DRM_FORMAT_VYUY, 1725 DRM_FORMAT_VYUY,
1515}; 1726};
1516 1727
1517static uint32_t skl_planar_formats[] = { 1728static const uint32_t skl_planar_formats[] = {
1729 DRM_FORMAT_C8,
1518 DRM_FORMAT_RGB565, 1730 DRM_FORMAT_RGB565,
1519 DRM_FORMAT_ABGR8888,
1520 DRM_FORMAT_ARGB8888,
1521 DRM_FORMAT_XBGR8888,
1522 DRM_FORMAT_XRGB8888, 1731 DRM_FORMAT_XRGB8888,
1732 DRM_FORMAT_XBGR8888,
1733 DRM_FORMAT_ARGB8888,
1734 DRM_FORMAT_ABGR8888,
1735 DRM_FORMAT_XRGB2101010,
1736 DRM_FORMAT_XBGR2101010,
1523 DRM_FORMAT_YUYV, 1737 DRM_FORMAT_YUYV,
1524 DRM_FORMAT_YVYU, 1738 DRM_FORMAT_YVYU,
1525 DRM_FORMAT_UYVY, 1739 DRM_FORMAT_UYVY,
@@ -1724,8 +1938,36 @@ static const struct drm_plane_funcs skl_plane_funcs = {
1724 .format_mod_supported = skl_plane_format_mod_supported, 1938 .format_mod_supported = skl_plane_format_mod_supported,
1725}; 1939};
1726 1940
1727bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 1941static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
1728 enum pipe pipe, enum plane_id plane_id) 1942 enum pipe pipe, enum plane_id plane_id)
1943{
1944 if (!HAS_FBC(dev_priv))
1945 return false;
1946
1947 return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
1948}
1949
1950static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
1951 enum pipe pipe, enum plane_id plane_id)
1952{
1953 if (INTEL_GEN(dev_priv) >= 11)
1954 return plane_id <= PLANE_SPRITE3;
1955
1956 /* Display WA #0870: skl, bxt */
1957 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
1958 return false;
1959
1960 if (IS_GEN9(dev_priv) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
1961 return false;
1962
1963 if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
1964 return false;
1965
1966 return true;
1967}
1968
1969static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
1970 enum pipe pipe, enum plane_id plane_id)
1729{ 1971{
1730 if (plane_id == PLANE_CURSOR) 1972 if (plane_id == PLANE_CURSOR)
1731 return false; 1973 return false;
@@ -1742,109 +1984,173 @@ bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
1742} 1984}
1743 1985
1744struct intel_plane * 1986struct intel_plane *
1745intel_sprite_plane_create(struct drm_i915_private *dev_priv, 1987skl_universal_plane_create(struct drm_i915_private *dev_priv,
1746 enum pipe pipe, int plane) 1988 enum pipe pipe, enum plane_id plane_id)
1747{ 1989{
1748 struct intel_plane *intel_plane = NULL; 1990 struct intel_plane *plane;
1749 struct intel_plane_state *state = NULL; 1991 enum drm_plane_type plane_type;
1750 const struct drm_plane_funcs *plane_funcs;
1751 unsigned long possible_crtcs;
1752 const uint32_t *plane_formats;
1753 const uint64_t *modifiers;
1754 unsigned int supported_rotations; 1992 unsigned int supported_rotations;
1755 int num_plane_formats; 1993 unsigned int possible_crtcs;
1994 const u64 *modifiers;
1995 const u32 *formats;
1996 int num_formats;
1756 int ret; 1997 int ret;
1757 1998
1758 intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); 1999 plane = intel_plane_alloc();
1759 if (!intel_plane) { 2000 if (IS_ERR(plane))
1760 ret = -ENOMEM; 2001 return plane;
1761 goto fail; 2002
2003 plane->pipe = pipe;
2004 plane->id = plane_id;
2005 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
2006
2007 plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
2008 if (plane->has_fbc) {
2009 struct intel_fbc *fbc = &dev_priv->fbc;
2010
2011 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
1762 } 2012 }
1763 2013
1764 state = intel_create_plane_state(&intel_plane->base); 2014 plane->max_stride = skl_plane_max_stride;
1765 if (!state) { 2015 plane->update_plane = skl_update_plane;
1766 ret = -ENOMEM; 2016 plane->disable_plane = skl_disable_plane;
1767 goto fail; 2017 plane->get_hw_state = skl_plane_get_hw_state;
2018 plane->check_plane = skl_plane_check;
2019 if (icl_is_nv12_y_plane(plane_id))
2020 plane->update_slave = icl_update_slave;
2021
2022 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2023 formats = skl_planar_formats;
2024 num_formats = ARRAY_SIZE(skl_planar_formats);
2025 } else {
2026 formats = skl_plane_formats;
2027 num_formats = ARRAY_SIZE(skl_plane_formats);
1768 } 2028 }
1769 intel_plane->base.state = &state->base;
1770 2029
1771 if (INTEL_GEN(dev_priv) >= 9) { 2030 plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
1772 state->scaler_id = -1; 2031 if (plane->has_ccs)
2032 modifiers = skl_plane_format_modifiers_ccs;
2033 else
2034 modifiers = skl_plane_format_modifiers_noccs;
1773 2035
1774 intel_plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, 2036 if (plane_id == PLANE_PRIMARY)
1775 PLANE_SPRITE0 + plane); 2037 plane_type = DRM_PLANE_TYPE_PRIMARY;
2038 else
2039 plane_type = DRM_PLANE_TYPE_OVERLAY;
1776 2040
1777 intel_plane->max_stride = skl_plane_max_stride; 2041 possible_crtcs = BIT(pipe);
1778 intel_plane->update_plane = skl_update_plane;
1779 intel_plane->disable_plane = skl_disable_plane;
1780 intel_plane->get_hw_state = skl_plane_get_hw_state;
1781 intel_plane->check_plane = skl_plane_check;
1782 2042
1783 if (skl_plane_has_planar(dev_priv, pipe, 2043 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
1784 PLANE_SPRITE0 + plane)) { 2044 possible_crtcs, &skl_plane_funcs,
1785 plane_formats = skl_planar_formats; 2045 formats, num_formats, modifiers,
1786 num_plane_formats = ARRAY_SIZE(skl_planar_formats); 2046 plane_type,
1787 } else { 2047 "plane %d%c", plane_id + 1,
1788 plane_formats = skl_plane_formats; 2048 pipe_name(pipe));
1789 num_plane_formats = ARRAY_SIZE(skl_plane_formats); 2049 if (ret)
1790 } 2050 goto fail;
1791 2051
1792 if (intel_plane->has_ccs) 2052 supported_rotations =
1793 modifiers = skl_plane_format_modifiers_ccs; 2053 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
1794 else 2054 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
1795 modifiers = skl_plane_format_modifiers_noccs; 2055
1796 2056 if (INTEL_GEN(dev_priv) >= 10)
1797 plane_funcs = &skl_plane_funcs; 2057 supported_rotations |= DRM_MODE_REFLECT_X;
1798 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 2058
1799 intel_plane->max_stride = i9xx_plane_max_stride; 2059 drm_plane_create_rotation_property(&plane->base,
1800 intel_plane->update_plane = vlv_update_plane; 2060 DRM_MODE_ROTATE_0,
1801 intel_plane->disable_plane = vlv_disable_plane; 2061 supported_rotations);
1802 intel_plane->get_hw_state = vlv_plane_get_hw_state; 2062
1803 intel_plane->check_plane = vlv_sprite_check; 2063 drm_plane_create_color_properties(&plane->base,
1804 2064 BIT(DRM_COLOR_YCBCR_BT601) |
1805 plane_formats = vlv_plane_formats; 2065 BIT(DRM_COLOR_YCBCR_BT709),
1806 num_plane_formats = ARRAY_SIZE(vlv_plane_formats); 2066 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2067 BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2068 DRM_COLOR_YCBCR_BT709,
2069 DRM_COLOR_YCBCR_LIMITED_RANGE);
2070
2071 drm_plane_create_alpha_property(&plane->base);
2072 drm_plane_create_blend_mode_property(&plane->base,
2073 BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2074 BIT(DRM_MODE_BLEND_PREMULTI) |
2075 BIT(DRM_MODE_BLEND_COVERAGE));
2076
2077 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2078
2079 return plane;
2080
2081fail:
2082 intel_plane_free(plane);
2083
2084 return ERR_PTR(ret);
2085}
2086
2087struct intel_plane *
2088intel_sprite_plane_create(struct drm_i915_private *dev_priv,
2089 enum pipe pipe, int sprite)
2090{
2091 struct intel_plane *plane;
2092 const struct drm_plane_funcs *plane_funcs;
2093 unsigned long possible_crtcs;
2094 unsigned int supported_rotations;
2095 const u64 *modifiers;
2096 const u32 *formats;
2097 int num_formats;
2098 int ret;
2099
2100 if (INTEL_GEN(dev_priv) >= 9)
2101 return skl_universal_plane_create(dev_priv, pipe,
2102 PLANE_SPRITE0 + sprite);
2103
2104 plane = intel_plane_alloc();
2105 if (IS_ERR(plane))
2106 return plane;
2107
2108 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
2109 plane->max_stride = i9xx_plane_max_stride;
2110 plane->update_plane = vlv_update_plane;
2111 plane->disable_plane = vlv_disable_plane;
2112 plane->get_hw_state = vlv_plane_get_hw_state;
2113 plane->check_plane = vlv_sprite_check;
2114
2115 formats = vlv_plane_formats;
2116 num_formats = ARRAY_SIZE(vlv_plane_formats);
1807 modifiers = i9xx_plane_format_modifiers; 2117 modifiers = i9xx_plane_format_modifiers;
1808 2118
1809 plane_funcs = &vlv_sprite_funcs; 2119 plane_funcs = &vlv_sprite_funcs;
1810 } else if (INTEL_GEN(dev_priv) >= 7) { 2120 } else if (INTEL_GEN(dev_priv) >= 7) {
1811 intel_plane->max_stride = g4x_sprite_max_stride; 2121 plane->max_stride = g4x_sprite_max_stride;
1812 intel_plane->update_plane = ivb_update_plane; 2122 plane->update_plane = ivb_update_plane;
1813 intel_plane->disable_plane = ivb_disable_plane; 2123 plane->disable_plane = ivb_disable_plane;
1814 intel_plane->get_hw_state = ivb_plane_get_hw_state; 2124 plane->get_hw_state = ivb_plane_get_hw_state;
1815 intel_plane->check_plane = g4x_sprite_check; 2125 plane->check_plane = g4x_sprite_check;
1816 2126
1817 plane_formats = snb_plane_formats; 2127 formats = snb_plane_formats;
1818 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 2128 num_formats = ARRAY_SIZE(snb_plane_formats);
1819 modifiers = i9xx_plane_format_modifiers; 2129 modifiers = i9xx_plane_format_modifiers;
1820 2130
1821 plane_funcs = &snb_sprite_funcs; 2131 plane_funcs = &snb_sprite_funcs;
1822 } else { 2132 } else {
1823 intel_plane->max_stride = g4x_sprite_max_stride; 2133 plane->max_stride = g4x_sprite_max_stride;
1824 intel_plane->update_plane = g4x_update_plane; 2134 plane->update_plane = g4x_update_plane;
1825 intel_plane->disable_plane = g4x_disable_plane; 2135 plane->disable_plane = g4x_disable_plane;
1826 intel_plane->get_hw_state = g4x_plane_get_hw_state; 2136 plane->get_hw_state = g4x_plane_get_hw_state;
1827 intel_plane->check_plane = g4x_sprite_check; 2137 plane->check_plane = g4x_sprite_check;
1828 2138
1829 modifiers = i9xx_plane_format_modifiers; 2139 modifiers = i9xx_plane_format_modifiers;
1830 if (IS_GEN6(dev_priv)) { 2140 if (IS_GEN6(dev_priv)) {
1831 plane_formats = snb_plane_formats; 2141 formats = snb_plane_formats;
1832 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 2142 num_formats = ARRAY_SIZE(snb_plane_formats);
1833 2143
1834 plane_funcs = &snb_sprite_funcs; 2144 plane_funcs = &snb_sprite_funcs;
1835 } else { 2145 } else {
1836 plane_formats = g4x_plane_formats; 2146 formats = g4x_plane_formats;
1837 num_plane_formats = ARRAY_SIZE(g4x_plane_formats); 2147 num_formats = ARRAY_SIZE(g4x_plane_formats);
1838 2148
1839 plane_funcs = &g4x_sprite_funcs; 2149 plane_funcs = &g4x_sprite_funcs;
1840 } 2150 }
1841 } 2151 }
1842 2152
1843 if (INTEL_GEN(dev_priv) >= 9) { 2153 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1844 supported_rotations =
1845 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
1846 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
1847 } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1848 supported_rotations = 2154 supported_rotations =
1849 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 2155 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1850 DRM_MODE_REFLECT_X; 2156 DRM_MODE_REFLECT_X;
@@ -1853,35 +2159,25 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1853 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 2159 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1854 } 2160 }
1855 2161
1856 intel_plane->pipe = pipe; 2162 plane->pipe = pipe;
1857 intel_plane->i9xx_plane = plane; 2163 plane->id = PLANE_SPRITE0 + sprite;
1858 intel_plane->id = PLANE_SPRITE0 + plane; 2164 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
1859 intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, intel_plane->id);
1860 2165
1861 possible_crtcs = (1 << pipe); 2166 possible_crtcs = BIT(pipe);
1862 2167
1863 if (INTEL_GEN(dev_priv) >= 9) 2168 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
1864 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, 2169 possible_crtcs, plane_funcs,
1865 possible_crtcs, plane_funcs, 2170 formats, num_formats, modifiers,
1866 plane_formats, num_plane_formats, 2171 DRM_PLANE_TYPE_OVERLAY,
1867 modifiers, 2172 "sprite %c", sprite_name(pipe, sprite));
1868 DRM_PLANE_TYPE_OVERLAY,
1869 "plane %d%c", plane + 2, pipe_name(pipe));
1870 else
1871 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
1872 possible_crtcs, plane_funcs,
1873 plane_formats, num_plane_formats,
1874 modifiers,
1875 DRM_PLANE_TYPE_OVERLAY,
1876 "sprite %c", sprite_name(pipe, plane));
1877 if (ret) 2173 if (ret)
1878 goto fail; 2174 goto fail;
1879 2175
1880 drm_plane_create_rotation_property(&intel_plane->base, 2176 drm_plane_create_rotation_property(&plane->base,
1881 DRM_MODE_ROTATE_0, 2177 DRM_MODE_ROTATE_0,
1882 supported_rotations); 2178 supported_rotations);
1883 2179
1884 drm_plane_create_color_properties(&intel_plane->base, 2180 drm_plane_create_color_properties(&plane->base,
1885 BIT(DRM_COLOR_YCBCR_BT601) | 2181 BIT(DRM_COLOR_YCBCR_BT601) |
1886 BIT(DRM_COLOR_YCBCR_BT709), 2182 BIT(DRM_COLOR_YCBCR_BT709),
1887 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 2183 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
@@ -1889,13 +2185,12 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1889 DRM_COLOR_YCBCR_BT709, 2185 DRM_COLOR_YCBCR_BT709,
1890 DRM_COLOR_YCBCR_LIMITED_RANGE); 2186 DRM_COLOR_YCBCR_LIMITED_RANGE);
1891 2187
1892 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); 2188 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
1893 2189
1894 return intel_plane; 2190 return plane;
1895 2191
1896fail: 2192fail:
1897 kfree(state); 2193 intel_plane_free(plane);
1898 kfree(intel_plane);
1899 2194
1900 return ERR_PTR(ret); 2195 return ERR_PTR(ret);
1901} 2196}