aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2018-02-14 14:23:25 -0500
committerVille Syrjälä <ville.syrjala@linux.intel.com>2018-03-02 07:46:18 -0500
commitb0f5c0badc5b54cc6308f21a65f6ebf69087d557 (patch)
tree4d325a3469b8799bc9be50fa571b580cc8b9db3e
parent38f24f21ae9bb0f2b7ebb42e828f7f8fe5190d89 (diff)
drm/i915: Add support for the YCbCr COLOR_ENCODING property
Add support for the COLOR_ENCODING plane property which selects the matrix coefficients used for the YCbCr->RGB conversion. Our hardware can generally handle BT.601 and BT.709. CHV pipe B sprites have a fully programmable matrix, so in theory we could handle anything, but it doesn't seem all that useful to expose anything beyond BT.601 and BT.709 at this time. GLK can supposedly do BT.2020, but let's leave enabling that for the future as well. v2: Rename bit defines to match the spec more closely (Shashank) Cc: Harry Wentland <harry.wentland@amd.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: Daniel Stone <daniel@fooishbar.org> Cc: Russell King - ARM Linux <linux@armlinux.org.uk> Cc: Ilia Mirkin <imirkin@alum.mit.edu> Cc: Hans Verkuil <hverkuil@xs4all.nl> Cc: Uma Shankar <uma.shankar@intel.com> Cc: Shashank Sharma <shashank.sharma@intel.com> Cc: Jyri Sarha <jsarha@ti.com> Reviewed-by: Shashank Sharma <shashank.sharma@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180214192327.3250-7-ville.syrjala@linux.intel.com
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h5
-rw-r--r--drivers/gpu/drm/i915/intel_display.c19
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c61
3 files changed, 67 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 98b5c41cc15f..b54c837689f6 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6113,6 +6113,7 @@ enum {
6113#define DVS_PIPE_CSC_ENABLE (1<<24) 6113#define DVS_PIPE_CSC_ENABLE (1<<24)
6114#define DVS_SOURCE_KEY (1<<22) 6114#define DVS_SOURCE_KEY (1<<22)
6115#define DVS_RGB_ORDER_XBGR (1<<20) 6115#define DVS_RGB_ORDER_XBGR (1<<20)
6116#define DVS_YUV_FORMAT_BT709 (1<<18)
6116#define DVS_YUV_BYTE_ORDER_MASK (3<<16) 6117#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
6117#define DVS_YUV_ORDER_YUYV (0<<16) 6118#define DVS_YUV_ORDER_YUYV (0<<16)
6118#define DVS_YUV_ORDER_UYVY (1<<16) 6119#define DVS_YUV_ORDER_UYVY (1<<16)
@@ -6183,7 +6184,7 @@ enum {
6183#define SPRITE_SOURCE_KEY (1<<22) 6184#define SPRITE_SOURCE_KEY (1<<22)
6184#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */ 6185#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
6185#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19) 6186#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
6186#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */ 6187#define SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
6187#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16) 6188#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
6188#define SPRITE_YUV_ORDER_YUYV (0<<16) 6189#define SPRITE_YUV_ORDER_YUYV (0<<16)
6189#define SPRITE_YUV_ORDER_UYVY (1<<16) 6190#define SPRITE_YUV_ORDER_UYVY (1<<16)
@@ -6259,6 +6260,7 @@ enum {
6259#define SP_FORMAT_RGBA8888 (0xf<<26) 6260#define SP_FORMAT_RGBA8888 (0xf<<26)
6260#define SP_ALPHA_PREMULTIPLY (1<<23) /* CHV pipe B */ 6261#define SP_ALPHA_PREMULTIPLY (1<<23) /* CHV pipe B */
6261#define SP_SOURCE_KEY (1<<22) 6262#define SP_SOURCE_KEY (1<<22)
6263#define SP_YUV_FORMAT_BT709 (1<<18)
6262#define SP_YUV_BYTE_ORDER_MASK (3<<16) 6264#define SP_YUV_BYTE_ORDER_MASK (3<<16)
6263#define SP_YUV_ORDER_YUYV (0<<16) 6265#define SP_YUV_ORDER_YUYV (0<<16)
6264#define SP_YUV_ORDER_UYVY (1<<16) 6266#define SP_YUV_ORDER_UYVY (1<<16)
@@ -6383,6 +6385,7 @@ enum {
6383#define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21) 6385#define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21)
6384#define PLANE_CTL_ORDER_BGRX (0 << 20) 6386#define PLANE_CTL_ORDER_BGRX (0 << 20)
6385#define PLANE_CTL_ORDER_RGBX (1 << 20) 6387#define PLANE_CTL_ORDER_RGBX (1 << 20)
6388#define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 (1 << 18)
6386#define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16) 6389#define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16)
6387#define PLANE_CTL_YUV422_YUYV ( 0 << 16) 6390#define PLANE_CTL_YUV422_YUYV ( 0 << 16)
6388#define PLANE_CTL_YUV422_UYVY ( 1 << 16) 6391#define PLANE_CTL_YUV422_UYVY ( 1 << 16)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ce13391cff63..8149079d01f1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3536,6 +3536,9 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
3536 PLANE_CTL_PIPE_GAMMA_ENABLE | 3536 PLANE_CTL_PIPE_GAMMA_ENABLE |
3537 PLANE_CTL_PIPE_CSC_ENABLE | 3537 PLANE_CTL_PIPE_CSC_ENABLE |
3538 PLANE_CTL_PLANE_GAMMA_DISABLE; 3538 PLANE_CTL_PLANE_GAMMA_DISABLE;
3539
3540 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
3541 plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
3539 } 3542 }
3540 3543
3541 plane_ctl |= skl_plane_ctl_format(fb->format->format); 3544 plane_ctl |= skl_plane_ctl_format(fb->format->format);
@@ -3565,8 +3568,12 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
3565 plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; 3568 plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
3566 plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format); 3569 plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
3567 3570
3568 if (intel_format_is_yuv(fb->format->format)) 3571 if (intel_format_is_yuv(fb->format->format)) {
3569 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; 3572 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
3573 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
3574 else
3575 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709;
3576 }
3570 3577
3571 return plane_color_ctl; 3578 return plane_color_ctl;
3572} 3579}
@@ -13289,6 +13296,14 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13289 DRM_MODE_ROTATE_0, 13296 DRM_MODE_ROTATE_0,
13290 supported_rotations); 13297 supported_rotations);
13291 13298
13299 if (INTEL_GEN(dev_priv) >= 9)
13300 drm_plane_create_color_properties(&primary->base,
13301 BIT(DRM_COLOR_YCBCR_BT601) |
13302 BIT(DRM_COLOR_YCBCR_BT709),
13303 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
13304 DRM_COLOR_YCBCR_BT601,
13305 DRM_COLOR_YCBCR_LIMITED_RANGE);
13306
13292 drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); 13307 drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
13293 13308
13294 return primary; 13309 return primary;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 3025c609d688..36798ca1b8bb 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -352,30 +352,45 @@ chv_update_csc(const struct intel_plane_state *plane_state)
352 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 352 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
353 const struct drm_framebuffer *fb = plane_state->base.fb; 353 const struct drm_framebuffer *fb = plane_state->base.fb;
354 enum plane_id plane_id = plane->id; 354 enum plane_id plane_id = plane->id;
355 /*
356 * |r| | c0 c1 c2 | |cr|
357 * |g| = | c3 c4 c5 | x |y |
358 * |b| | c6 c7 c8 | |cb|
359 *
360 * Coefficients are s3.12.
361 *
362 * Cb and Cr apparently come in as signed already, and
363 * we always get full range data in on account of CLRC0/1.
364 */
365 static const s16 csc_matrix[][9] = {
366 /* BT.601 full range YCbCr -> full range RGB */
367 [DRM_COLOR_YCBCR_BT601] = {
368 5743, 4096, 0,
369 -2925, 4096, -1410,
370 0, 4096, 7258,
371 },
372 /* BT.709 full range YCbCr -> full range RGB */
373 [DRM_COLOR_YCBCR_BT709] = {
374 6450, 4096, 0,
375 -1917, 4096, -767,
376 0, 4096, 7601,
377 },
378 };
379 const s16 *csc = csc_matrix[plane_state->base.color_encoding];
355 380
356 /* Seems RGB data bypasses the CSC always */ 381 /* Seems RGB data bypasses the CSC always */
357 if (!intel_format_is_yuv(fb->format->format)) 382 if (!intel_format_is_yuv(fb->format->format))
358 return; 383 return;
359 384
360 /*
361 * BT.601 full range YCbCr -> full range RGB
362 *
363 * |r| | 5743 4096 0| |cr|
364 * |g| = |-2925 4096 -1410| x |y |
365 * |b| | 0 4096 7258| |cb|
366 *
367 * Cb and Cr apparently come in as signed already,
368 * and we get full range data in on account of CLRC0/1
369 */
370 I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 385 I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
371 I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 386 I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
372 I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 387 I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
373 388
374 I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4096) | SPCSC_C0(5743)); 389 I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
375 I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-2925) | SPCSC_C0(0)); 390 I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
376 I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1410) | SPCSC_C0(4096)); 391 I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
377 I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4096) | SPCSC_C0(0)); 392 I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
378 I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(7258)); 393 I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
379 394
380 I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); 395 I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
381 I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 396 I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
@@ -476,6 +491,9 @@ static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
476 return 0; 491 return 0;
477 } 492 }
478 493
494 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
495 sprctl |= SP_YUV_FORMAT_BT709;
496
479 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 497 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
480 sprctl |= SP_TILED; 498 sprctl |= SP_TILED;
481 499
@@ -629,6 +647,9 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
629 return 0; 647 return 0;
630 } 648 }
631 649
650 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
651 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
652
632 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 653 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
633 sprctl |= SPRITE_TILED; 654 sprctl |= SPRITE_TILED;
634 655
@@ -785,6 +806,9 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
785 return 0; 806 return 0;
786 } 807 }
787 808
809 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
810 dvscntr |= DVS_YUV_FORMAT_BT709;
811
788 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 812 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
789 dvscntr |= DVS_TILED; 813 dvscntr |= DVS_TILED;
790 814
@@ -1501,6 +1525,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1501 DRM_MODE_ROTATE_0, 1525 DRM_MODE_ROTATE_0,
1502 supported_rotations); 1526 supported_rotations);
1503 1527
1528 drm_plane_create_color_properties(&intel_plane->base,
1529 BIT(DRM_COLOR_YCBCR_BT601) |
1530 BIT(DRM_COLOR_YCBCR_BT709),
1531 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
1532 DRM_COLOR_YCBCR_BT601,
1533 DRM_COLOR_YCBCR_LIMITED_RANGE);
1534
1504 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); 1535 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
1505 1536
1506 return intel_plane; 1537 return intel_plane;