From 9f91280febf718ef5dc089a6be06bb48fcc89729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 Dec 2017 21:22:31 +0200 Subject: drm/i915: Remove the pipe/plane ID checks from skl_check_ccs_aux_surface() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core now checks that the plane supports the fb's format+modifier combination, so we can drop the related checks from skl_check_ccs_aux_surface(). These checks were specific to SKL/KBL/BXT anyway. Cc: Ben Widawsky Cc: Jason Ekstrand Cc: Daniel Stone Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171222192231.17981-9-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/intel_display.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 60ba5bb3f34c..3d2929c44804 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3063,9 +3063,6 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state) { - struct intel_plane *plane = to_intel_plane(plane_state->base.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc); const struct drm_framebuffer *fb = plane_state->base.fb; int src_x = plane_state->base.src.x1 >> 16; int src_y = plane_state->base.src.y1 >> 16; @@ -3075,11 +3072,6 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state) int y = src_y / vsub; u32 offset; - if (!skl_plane_has_ccs(dev_priv, crtc->pipe, plane->id)) { - DRM_DEBUG_KMS("No RC support on %s\n", plane->base.name); - return -EINVAL; - } - if (plane_state->base.rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) { DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n", plane_state->base.rotation); -- cgit v1.2.1 From 5deae9191130db6b617c94fb261804597cf9b508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 14 Feb 2018 21:23:23 +0200 Subject: drm/i915: Correctly handle limited range YCbCr data on VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out the VLV/CHV fixed function sprite CSC expects full range data as input. We've been feeding it limited range data to it all along. To expand the data out to full range we'll use the color correction registers (brightness, contrast, and saturation). On CHV pipe B we were actually doing the right thing already because we progammed the custom CSC matrix to do expect limited range input. Now that well pre-expand the data out with the color correction unit, we need to change the CSC matrix to operate with full range input instead. This should make the sprite output of the other pipes match the sprite output of pipe B reasonably well. Looking at the resulting pipe CRCs, there can be a slight difference in the output, but as I don't know the formula used by the fixed function CSC of the other pipes, I don't think it's worth the effort to try to match the output exactly. It might not even be possible due to difference in internal precision etc. One slight caveat here is that the color correction registers are single bufferred, so we should really be updating them during vblank, but we still don't have a mechanism for that, so just toss in another FIXME. v2: Rebase v3: s/bri/brightness/ s/con/contrast/ (Shashank) v4: Clarify the constants and math (Shashank) Cc: Harry Wentland Cc: Daniel Vetter Cc: Daniel Stone Cc: Russell King - ARM Linux Cc: Ilia Mirkin Cc: Hans Verkuil Cc: Shashank Sharma Cc: Uma Shankar Cc: Jyri Sarha Cc: "Tang, Jun" Reported-by: "Tang, Jun" Cc: stable@vger.kernel.org Fixes: 7f1f3851feb0 ("drm/i915: sprite support for ValleyView v4") Reviewed-by: Shashank Sharma Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180214192327.3250-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 10 +++++ drivers/gpu/drm/i915/intel_sprite.c | 81 ++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e9c79b560823..aaed94f074f5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6278,6 +6278,12 @@ enum { #define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4) #define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8) #define SP_CONST_ALPHA_ENABLE (1<<31) +#define _SPACLRC0 (VLV_DISPLAY_BASE + 0x721d0) +#define SP_CONTRAST(x) ((x) << 18) /* u3.6 */ +#define SP_BRIGHTNESS(x) ((x) & 0xff) /* s8 */ +#define _SPACLRC1 (VLV_DISPLAY_BASE + 0x721d4) +#define SP_SH_SIN(x) (((x) & 0x7ff) << 16) /* s4.7 */ +#define SP_SH_COS(x) (x) /* u3.7 */ #define _SPAGAMC (VLV_DISPLAY_BASE + 0x721f4) #define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280) @@ -6291,6 +6297,8 @@ enum { #define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0) #define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4) #define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8) +#define _SPBCLRC0 (VLV_DISPLAY_BASE + 0x722d0) +#define _SPBCLRC1 (VLV_DISPLAY_BASE + 0x722d4) #define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4) #define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \ @@ -6307,6 +6315,8 @@ enum { #define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL) #define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF) #define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA) +#define SPCLRC0(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC0, _SPBCLRC0) +#define SPCLRC1(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC1, _SPBCLRC1) #define SPGAMC(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAGAMC, _SPBGAMC) /* diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 3be22c0fcfb5..9b7171f20549 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -346,44 +346,87 @@ skl_plane_get_hw_state(struct intel_plane *plane) } static void -chv_update_csc(struct intel_plane *plane, uint32_t format) +chv_update_csc(const struct intel_plane_state *plane_state) { + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + const struct drm_framebuffer *fb = plane_state->base.fb; enum plane_id plane_id = plane->id; /* Seems RGB data bypasses the CSC always */ - if (!format_is_yuv(format)) + if (!format_is_yuv(fb->format->format)) return; /* - * BT.601 limited range YCbCr -> full range RGB + * BT.601 full range YCbCr -> full range RGB * - * |r| | 6537 4769 0| |cr | - * |g| = |-3330 4769 -1605| x |y-64| - * |b| | 0 4769 8263| |cb | + * |r| | 5743 4096 0| |cr| + * |g| = |-2925 4096 -1410| x |y | + * |b| | 0 4096 7258| |cb| * - * Cb and Cr apparently come in as signed already, so no - * need for any offset. For Y we need to remove the offset. + * Cb and Cr apparently come in as signed already, + * and we get full range data in on account of CLRC0/1 */ - I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(-64)); + I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); - I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4769) | SPCSC_C0(6537)); - I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-3330) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1605) | SPCSC_C0(4769)); - I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4769) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(8263)); + I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4096) | SPCSC_C0(5743)); + I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-2925) | SPCSC_C0(0)); + I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1410) | SPCSC_C0(4096)); + I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4096) | SPCSC_C0(0)); + I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(7258)); - I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(940) | SPCSC_IMIN(64)); - I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); - I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); + I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); + I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); + I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); } +#define SIN_0 0 +#define COS_0 1 + +static void +vlv_update_clrc(const struct intel_plane_state *plane_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + const struct drm_framebuffer *fb = plane_state->base.fb; + enum pipe pipe = plane->pipe; + enum plane_id plane_id = plane->id; + int contrast, brightness, sh_scale, sh_sin, sh_cos; + + if (format_is_yuv(fb->format->format)) { + /* + * Expand limited range to full range: + * Contrast is applied first and is used to expand Y range. + * Brightness is applied second and is used to remove the + * offset from Y. Saturation/hue is used to expand CbCr range. + */ + contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16); + brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16); + sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128); + sh_sin = SIN_0 * sh_scale; + sh_cos = COS_0 * sh_scale; + } else { + /* Pass-through everything. */ + contrast = 1 << 6; + brightness = 0; + sh_scale = 1 << 7; + sh_sin = SIN_0 * sh_scale; + sh_cos = COS_0 * sh_scale; + } + + /* FIXME these register are single buffered :( */ + I915_WRITE_FW(SPCLRC0(pipe, plane_id), + SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness)); + I915_WRITE_FW(SPCLRC1(pipe, plane_id), + SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos)); +} + static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -477,8 +520,10 @@ vlv_update_plane(struct intel_plane *plane, spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); + vlv_update_clrc(plane_state); + if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) - chv_update_csc(plane, fb->format->format); + chv_update_csc(plane_state); if (key->flags) { I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value); -- cgit v1.2.1 From 38f24f21ae9bb0f2b7ebb42e828f7f8fe5190d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 14 Feb 2018 21:23:24 +0200 Subject: drm/i915: Fix plane YCbCr->RGB conversion for GLK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On GLK the plane CSC controls moved into the COLOR_CTL register. Update the code to progam the YCbCr->RGB CSC mode correctly when faced with an YCbCr framebuffer. The spec is rather confusing as it calls the mode "YUV601 to RGB709". I'm going to assume that just means it's going to use the YCbCr->RGB matrix as specified in BT.601 and doesn't actually change the gamut. Cc: Harry Wentland Cc: Daniel Vetter Cc: Daniel Stone Cc: Russell King - ARM Linux Cc: Ilia Mirkin Cc: Hans Verkuil Cc: Uma Shankar Cc: Shashank Sharma Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180214192327.3250-6-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_reg.h | 5 +++++ drivers/gpu/drm/i915/intel_display.c | 3 +++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_sprite.c | 10 +++++----- 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index aaed94f074f5..98b5c41cc15f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6436,6 +6436,11 @@ enum { #define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ #define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) #define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) +#define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17) +#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17) +#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 (2 << 17) +#define PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020 (3 << 17) +#define PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020 (4 << 17) #define PLANE_COLOR_PLANE_GAMMA_DISABLE (1 << 13) #define PLANE_COLOR_ALPHA_MASK (0x3 << 4) #define PLANE_COLOR_ALPHA_DISABLE (0 << 4) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3d2929c44804..ce13391cff63 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3565,6 +3565,9 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format); + if (intel_format_is_yuv(fb->format->format)) + plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + return plane_color_ctl; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 468ec1e90e16..2bc4e17baf4f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1589,6 +1589,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); +u32 glk_color_ctl(const struct intel_plane_state *plane_state); u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, unsigned int rotation); int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, @@ -2014,6 +2015,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, /* intel_sprite.c */ +bool intel_format_is_yuv(u32 format); int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, int usecs); struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 9b7171f20549..3025c609d688 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -41,8 +41,7 @@ #include #include "i915_drv.h" -static bool -format_is_yuv(uint32_t format) +bool intel_format_is_yuv(u32 format) { switch (format) { case DRM_FORMAT_YUYV: @@ -266,6 +265,7 @@ skl_update_plane(struct intel_plane *plane, if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_state->color_ctl); + if (key->flags) { I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value); @@ -354,7 +354,7 @@ chv_update_csc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id; /* Seems RGB data bypasses the CSC always */ - if (!format_is_yuv(fb->format->format)) + if (!intel_format_is_yuv(fb->format->format)) return; /* @@ -399,7 +399,7 @@ vlv_update_clrc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id; int contrast, brightness, sh_scale, sh_sin, sh_cos; - if (format_is_yuv(fb->format->format)) { + if (intel_format_is_yuv(fb->format->format)) { /* * Expand limited range to full range: * Contrast is applied first and is used to expand Y range. @@ -1024,7 +1024,7 @@ intel_check_sprite_plane(struct intel_plane *plane, src_y = src->y1 >> 16; src_h = drm_rect_height(src) >> 16; - if (format_is_yuv(fb->format->format)) { + if (intel_format_is_yuv(fb->format->format)) { src_x &= ~1; src_w &= ~1; -- cgit v1.2.1 From b0f5c0badc5b54cc6308f21a65f6ebf69087d557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 14 Feb 2018 21:23:25 +0200 Subject: drm/i915: Add support for the YCbCr COLOR_ENCODING property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Cc: Daniel Vetter Cc: Daniel Stone Cc: Russell King - ARM Linux Cc: Ilia Mirkin Cc: Hans Verkuil Cc: Uma Shankar Cc: Shashank Sharma Cc: Jyri Sarha Reviewed-by: Shashank Sharma Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180214192327.3250-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 5 ++- drivers/gpu/drm/i915/intel_display.c | 19 +++++++++-- drivers/gpu/drm/i915/intel_sprite.c | 61 +++++++++++++++++++++++++++--------- 3 files changed, 67 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/i915') 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 { #define DVS_PIPE_CSC_ENABLE (1<<24) #define DVS_SOURCE_KEY (1<<22) #define DVS_RGB_ORDER_XBGR (1<<20) +#define DVS_YUV_FORMAT_BT709 (1<<18) #define DVS_YUV_BYTE_ORDER_MASK (3<<16) #define DVS_YUV_ORDER_YUYV (0<<16) #define DVS_YUV_ORDER_UYVY (1<<16) @@ -6183,7 +6184,7 @@ enum { #define SPRITE_SOURCE_KEY (1<<22) #define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */ #define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19) -#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */ +#define SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */ #define SPRITE_YUV_BYTE_ORDER_MASK (3<<16) #define SPRITE_YUV_ORDER_YUYV (0<<16) #define SPRITE_YUV_ORDER_UYVY (1<<16) @@ -6259,6 +6260,7 @@ enum { #define SP_FORMAT_RGBA8888 (0xf<<26) #define SP_ALPHA_PREMULTIPLY (1<<23) /* CHV pipe B */ #define SP_SOURCE_KEY (1<<22) +#define SP_YUV_FORMAT_BT709 (1<<18) #define SP_YUV_BYTE_ORDER_MASK (3<<16) #define SP_YUV_ORDER_YUYV (0<<16) #define SP_YUV_ORDER_UYVY (1<<16) @@ -6383,6 +6385,7 @@ enum { #define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21) #define PLANE_CTL_ORDER_BGRX (0 << 20) #define PLANE_CTL_ORDER_RGBX (1 << 20) +#define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 (1 << 18) #define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16) #define PLANE_CTL_YUV422_YUYV ( 0 << 16) #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, PLANE_CTL_PIPE_GAMMA_ENABLE | PLANE_CTL_PIPE_CSC_ENABLE | PLANE_CTL_PLANE_GAMMA_DISABLE; + + if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709; } 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, plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format); - if (intel_format_is_yuv(fb->format->format)) - plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + if (intel_format_is_yuv(fb->format->format)) { + if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709; + else + plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + } return plane_color_ctl; } @@ -13289,6 +13296,14 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) DRM_MODE_ROTATE_0, supported_rotations); + if (INTEL_GEN(dev_priv) >= 9) + drm_plane_create_color_properties(&primary->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_LIMITED_RANGE); + drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); 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) struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->base.fb; enum plane_id plane_id = plane->id; + /* + * |r| | c0 c1 c2 | |cr| + * |g| = | c3 c4 c5 | x |y | + * |b| | c6 c7 c8 | |cb| + * + * Coefficients are s3.12. + * + * Cb and Cr apparently come in as signed already, and + * we always get full range data in on account of CLRC0/1. + */ + static const s16 csc_matrix[][9] = { + /* BT.601 full range YCbCr -> full range RGB */ + [DRM_COLOR_YCBCR_BT601] = { + 5743, 4096, 0, + -2925, 4096, -1410, + 0, 4096, 7258, + }, + /* BT.709 full range YCbCr -> full range RGB */ + [DRM_COLOR_YCBCR_BT709] = { + 6450, 4096, 0, + -1917, 4096, -767, + 0, 4096, 7601, + }, + }; + const s16 *csc = csc_matrix[plane_state->base.color_encoding]; /* Seems RGB data bypasses the CSC always */ if (!intel_format_is_yuv(fb->format->format)) return; - /* - * BT.601 full range YCbCr -> full range RGB - * - * |r| | 5743 4096 0| |cr| - * |g| = |-2925 4096 -1410| x |y | - * |b| | 0 4096 7258| |cb| - * - * Cb and Cr apparently come in as signed already, - * and we get full range data in on account of CLRC0/1 - */ I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); - I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4096) | SPCSC_C0(5743)); - I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-2925) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1410) | SPCSC_C0(4096)); - I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4096) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(7258)); + I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0])); + I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2])); + I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4])); + I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6])); + I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8])); I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); 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, return 0; } + if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + sprctl |= SP_YUV_FORMAT_BT709; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SP_TILED; @@ -629,6 +647,9 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, return 0; } + if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SPRITE_TILED; @@ -785,6 +806,9 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, return 0; } + if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + dvscntr |= DVS_YUV_FORMAT_BT709; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) dvscntr |= DVS_TILED; @@ -1501,6 +1525,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, DRM_MODE_ROTATE_0, supported_rotations); + drm_plane_create_color_properties(&intel_plane->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_LIMITED_RANGE); + drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); return intel_plane; -- cgit v1.2.1 From 23b280890a140b0cf1e8f61c252936c2fb77f718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 14 Feb 2018 21:23:26 +0200 Subject: drm/i915: Change the COLOR_ENCODING prop default value to BT.709 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring us forward from the stone age and switch our default YCbCr->RGB conversion matrix to BT.709 from BT.601. I would expect most matrial to be BT.709 these days. Cc: Harry Wentland Cc: Daniel Vetter Cc: Daniel Stone Cc: Russell King - ARM Linux Cc: Ilia Mirkin Cc: Hans Verkuil Cc: Uma Shankar Cc: Shashank Sharma Cc: Jyri Sarha Acked-by: Shashank Sharma Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180214192327.3250-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_sprite.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8149079d01f1..2584b9fb2473 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13301,7 +13301,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), - DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 36798ca1b8bb..84640f92ac2e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1529,7 +1529,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), - DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); -- cgit v1.2.1 From c8624ede3ed3b9f46364f5239c402393ec853e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 14 Feb 2018 21:23:27 +0200 Subject: drm/i915: Add support for the YCbCr COLOR_RANGE property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the COLOR_RANGE property on planes. This property selects whether the input YCbCr data is to treated as limited range or full range. On most platforms this is a matter of setting the "YUV range correction disable" bit, and on VLV/CHV we'll just have to program the color correction logic to pass the data through unmodified. v2: Rebase Cc: Harry Wentland Cc: Daniel Vetter Cc: Daniel Stone Cc: Russell King - ARM Linux Cc: Ilia Mirkin Cc: Hans Verkuil Cc: Uma Shankar Cc: Shashank Sharma Cc: Jyri Sarha Reviewed-by: Shashank Sharma Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180214192327.3250-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ drivers/gpu/drm/i915/intel_display.c | 9 ++++++++- drivers/gpu/drm/i915/intel_sprite.c | 12 ++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b54c837689f6..b576b6ba32a4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6105,6 +6105,7 @@ enum { #define _DVSACNTR 0x72180 #define DVS_ENABLE (1<<31) #define DVS_GAMMA_ENABLE (1<<30) +#define DVS_YUV_RANGE_CORRECTION_DISABLE (1<<27) #define DVS_PIXFORMAT_MASK (3<<25) #define DVS_FORMAT_YUV422 (0<<25) #define DVS_FORMAT_RGBX101010 (1<<25) @@ -6173,6 +6174,7 @@ enum { #define _SPRA_CTL 0x70280 #define SPRITE_ENABLE (1<<31) #define SPRITE_GAMMA_ENABLE (1<<30) +#define SPRITE_YUV_RANGE_CORRECTION_DISABLE (1<<28) #define SPRITE_PIXFORMAT_MASK (7<<25) #define SPRITE_FORMAT_YUV422 (0<<25) #define SPRITE_FORMAT_RGBX101010 (1<<25) @@ -6364,6 +6366,7 @@ enum { #define _PLANE_CTL_3_A 0x70380 #define PLANE_CTL_ENABLE (1 << 31) #define PLANE_CTL_PIPE_GAMMA_ENABLE (1 << 30) /* Pre-GLK */ +#define PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE (1 << 28) /* * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition * expanded to include bit 23 as well. However, the shift-24 based values @@ -6438,6 +6441,7 @@ enum { #define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */ #define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ #define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) +#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE (1 << 28) #define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) #define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17) #define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2584b9fb2473..2dceb4cc5f30 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3539,6 +3539,9 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709; + + if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE; } plane_ctl |= skl_plane_ctl_format(fb->format->format); @@ -3573,6 +3576,9 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709; else plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + + if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; } return plane_color_ctl; @@ -13300,7 +13306,8 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) drm_plane_create_color_properties(&primary->base, BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), - BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 84640f92ac2e..3714836879b2 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -414,7 +414,8 @@ vlv_update_clrc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id; int contrast, brightness, sh_scale, sh_sin, sh_cos; - if (intel_format_is_yuv(fb->format->format)) { + if (intel_format_is_yuv(fb->format->format) && + plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) { /* * Expand limited range to full range: * Contrast is applied first and is used to expand Y range. @@ -650,6 +651,9 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; + if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SPRITE_TILED; @@ -809,6 +813,9 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) dvscntr |= DVS_YUV_FORMAT_BT709; + if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) dvscntr |= DVS_TILED; @@ -1528,7 +1535,8 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, drm_plane_create_color_properties(&intel_plane->base, BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), - BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); -- cgit v1.2.1 From 81af63a4af82e739aaa391d1fbb97e02c58ea6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Jan 2018 19:08:57 +0200 Subject: drm: Don't pass clip to drm_atomic_helper_check_plane_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the plane clip rectangle handling into drm_atomic_helper_check_plane_state(). Drivers no longer have to worry about such mundane details. v2: Convert armada, rcar, and sun4i as well v3: Resolve simple_kms_helper conflict Cc: Liviu Dudau Cc: Brian Starkey Cc: Mali DP Maintainers Cc: Daniel Vetter Cc: Gustavo Padovan Cc: Sean Paul Cc: Philipp Zabel Cc: CK Hu Cc: Neil Armstrong Cc: Rob Clark Cc: Ben Skeggs Cc: Laurent Pinchart Cc: Sandy Huang Cc: "Heiko Stübner" Cc: Maxime Ripard Cc: Thierry Reding Cc: VMware Graphics Cc: Sinclair Yeh Cc: Thomas Hellstrom Cc: Shawn Guo Cc: Archit Taneja Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: nouveau@lists.freedesktop.org Cc: linux-renesas-soc@vger.kernel.org Cc: linux-tegra@vger.kernel.org Cc: Russell King Suggested-by: Daniel Vetter Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Reviewed-by: Thierry Reding Reviewed-by: Archit Taneja #msm Link: https://patchwork.freedesktop.org/patch/msgid/20180123170857.13818-5-ville.syrjala@linux.intel.com Acked-by: Liviu Dudau #hdlcd,malidp Acked-by: Philipp Zabel #imx,mtk Reviewed-by: Laurent Pinchart Reviewed-by: Sinclair Yeh #vmwgfx Acked-by: Neil Armstrong #meson Acked-by: Shawn Guo #zte --- drivers/gpu/drm/i915/intel_display.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2dceb4cc5f30..250597e6f580 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9360,18 +9360,12 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { const struct drm_framebuffer *fb = plane_state->base.fb; - struct drm_rect clip = {}; int src_x, src_y; u32 offset; int ret; - if (crtc_state->base.enable) - drm_mode_get_hv_timing(&crtc_state->base.mode, - &clip.x2, &clip.y2); - ret = drm_atomic_helper_check_plane_state(&plane_state->base, &crtc_state->base, - &clip, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, true, true); @@ -12806,7 +12800,6 @@ intel_check_primary_plane(struct intel_plane *plane, int min_scale = DRM_PLANE_HELPER_NO_SCALING; int max_scale = DRM_PLANE_HELPER_NO_SCALING; bool can_position = false; - struct drm_rect clip = {}; int ret; if (INTEL_GEN(dev_priv) >= 9) { @@ -12818,13 +12811,8 @@ intel_check_primary_plane(struct intel_plane *plane, can_position = true; } - if (crtc_state->base.enable) - drm_mode_get_hv_timing(&crtc_state->base.mode, - &clip.x2, &clip.y2); - ret = drm_atomic_helper_check_plane_state(&state->base, &crtc_state->base, - &clip, min_scale, max_scale, can_position, true); if (ret) -- cgit v1.2.1