linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] drm/bridge: dw-hdmi: Various updates
@ 2020-03-04 23:25 Jernej Skrabec
  2020-03-04 23:25 ` [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry Jernej Skrabec
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Jernej Skrabec @ 2020-03-04 23:25 UTC (permalink / raw)
  To: a.hajda, narmstrong
  Cc: Laurent.pinchart, jonas, jernej.skrabec, airlied, daniel,
	dri-devel, linux-kernel

This series fixes multiple issues I found out.
Patch 1 fixes reporting colorimetry in AVI frame.
Patch 2 sets scan mode to underscan which is in line with most other
hdmi drivers.
Patch 3 aligns RGB quantization to CEA 861 standard.
Patch 4 reworks is_color_space_conversion(). Now it checks only if
color space conversion is required. Patch adds separate function for
checking if any kind of conversion is required.

Please take a look.

Best regards,
Jernej

Changes from v2:
- added tags
- replaced patch 2 with patch 4
- renamed rgb conversion matrix and make hex lowercase
- move logic for checking if rgb full to limited range conversion is
  needed to is_color_space_conversion()
- reworked logic for csc matrix selection

Jernej Skrabec (3):
  drm/bridge: dw-hdmi: fix AVI frame colorimetry
  drm/bridge: dw-hdmi: Add support for RGB limited range
  drm/bridge: dw-hdmi: rework csc related functions

Jonas Karlman (1):
  drm/bridge: dw-hdmi: do not force "none" scan mode

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 132 ++++++++++++++--------
 1 file changed, 88 insertions(+), 44 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry
  2020-03-04 23:25 [PATCH v2 0/4] drm/bridge: dw-hdmi: Various updates Jernej Skrabec
@ 2020-03-04 23:25 ` Jernej Skrabec
  2020-03-05 17:14   ` Jernej Škrabec
  2020-03-04 23:25 ` [PATCH v2 2/4] drm/bridge: dw-hdmi: do not force "none" scan mode Jernej Skrabec
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Jernej Skrabec @ 2020-03-04 23:25 UTC (permalink / raw)
  To: a.hajda, narmstrong
  Cc: Laurent.pinchart, jonas, jernej.skrabec, airlied, daniel,
	dri-devel, linux-kernel, Laurent Pinchart

CTA-861-F explicitly states that for RGB colorspace colorimetry should
be set to "none". Fix that.

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Fixes: def23aa7e982 ("drm: bridge: dw-hdmi: Switch to V4L bus format and encodings")
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 46 +++++++++++++----------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 67fca439bbfb..24965e53d351 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1624,28 +1624,34 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 		frame.colorspace = HDMI_COLORSPACE_RGB;
 
 	/* Set up colorimetry */
-	switch (hdmi->hdmi_data.enc_out_encoding) {
-	case V4L2_YCBCR_ENC_601:
-		if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601)
-			frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
-		else
+	if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
+		switch (hdmi->hdmi_data.enc_out_encoding) {
+		case V4L2_YCBCR_ENC_601:
+			if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601)
+				frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
+			else
+				frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
+			frame.extended_colorimetry =
+					HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
+			break;
+		case V4L2_YCBCR_ENC_709:
+			if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709)
+				frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
+			else
+				frame.colorimetry = HDMI_COLORIMETRY_ITU_709;
+			frame.extended_colorimetry =
+					HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
+			break;
+		default: /* Carries no data */
 			frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
+			frame.extended_colorimetry =
+					HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
+			break;
+		}
+	} else {
+		frame.colorimetry = HDMI_COLORIMETRY_NONE;
 		frame.extended_colorimetry =
-				HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
-		break;
-	case V4L2_YCBCR_ENC_709:
-		if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709)
-			frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
-		else
-			frame.colorimetry = HDMI_COLORIMETRY_ITU_709;
-		frame.extended_colorimetry =
-				HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
-		break;
-	default: /* Carries no data */
-		frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
-		frame.extended_colorimetry =
-				HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
-		break;
+			HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
 	}
 
 	frame.scan_mode = HDMI_SCAN_MODE_NONE;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/4] drm/bridge: dw-hdmi: do not force "none" scan mode
  2020-03-04 23:25 [PATCH v2 0/4] drm/bridge: dw-hdmi: Various updates Jernej Skrabec
  2020-03-04 23:25 ` [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry Jernej Skrabec
@ 2020-03-04 23:25 ` Jernej Skrabec
  2020-03-04 23:25 ` [PATCH v2 3/4] drm/bridge: dw-hdmi: Add support for RGB limited range Jernej Skrabec
  2020-03-04 23:25 ` [PATCH v2 4/4] drm/bridge: dw-hdmi: rework csc related functions Jernej Skrabec
  3 siblings, 0 replies; 9+ messages in thread
From: Jernej Skrabec @ 2020-03-04 23:25 UTC (permalink / raw)
  To: a.hajda, narmstrong
  Cc: Laurent.pinchart, jonas, jernej.skrabec, airlied, daniel,
	dri-devel, linux-kernel, Laurent Pinchart

From: Jonas Karlman <jonas@kwiboo.se>

Setting scan mode to "none" confuses some TVs like LG B8, which randomly
change overscan percentage over time. Digital outputs like HDMI and DVI,
handled by this controller, don't really need overscan, so we can always
set scan mode to underscan. Actually, this is exactly what
drm_hdmi_avi_infoframe_from_display_mode() already does, so we can just
remove offending line.

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
[updated commit message]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 24965e53d351..de2c7ec887c8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1654,8 +1654,6 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 			HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
 	}
 
-	frame.scan_mode = HDMI_SCAN_MODE_NONE;
-
 	/*
 	 * The Designware IP uses a different byte format from standard
 	 * AVI info frames, though generally the bits are in the correct
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/4] drm/bridge: dw-hdmi: Add support for RGB limited range
  2020-03-04 23:25 [PATCH v2 0/4] drm/bridge: dw-hdmi: Various updates Jernej Skrabec
  2020-03-04 23:25 ` [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry Jernej Skrabec
  2020-03-04 23:25 ` [PATCH v2 2/4] drm/bridge: dw-hdmi: do not force "none" scan mode Jernej Skrabec
@ 2020-03-04 23:25 ` Jernej Skrabec
  2020-03-04 23:47   ` Laurent Pinchart
  2020-03-04 23:25 ` [PATCH v2 4/4] drm/bridge: dw-hdmi: rework csc related functions Jernej Skrabec
  3 siblings, 1 reply; 9+ messages in thread
From: Jernej Skrabec @ 2020-03-04 23:25 UTC (permalink / raw)
  To: a.hajda, narmstrong
  Cc: Laurent.pinchart, jonas, jernej.skrabec, airlied, daniel,
	dri-devel, linux-kernel

CEA 861 standard requestis that RGB quantization range is "limited" for
CEA modes. Support that by adding CSC matrix which downscales values.

This allows proper color reproduction on TV and PC monitor at the same
time. In future, override property can be added, like "Broadcast RGB"
in i915 driver.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 63 +++++++++++++++++------
 1 file changed, 46 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index de2c7ec887c8..c8a02e5b5e1b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -92,6 +92,12 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
 	{ 0x6756, 0x78ab, 0x2000, 0x0200 }
 };
 
+static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
+	{ 0x1b7c, 0x0000, 0x0000, 0x0020 },
+	{ 0x0000, 0x1b7c, 0x0000, 0x0020 },
+	{ 0x0000, 0x0000, 0x1b7c, 0x0020 }
+};
+
 struct hdmi_vmode {
 	bool mdataenablepolarity;
 
@@ -109,6 +115,7 @@ struct hdmi_data_info {
 	unsigned int pix_repet_factor;
 	unsigned int hdcp_enable;
 	struct hdmi_vmode video_mode;
+	bool rgb_limited_range;
 };
 
 struct dw_hdmi_i2c {
@@ -956,7 +963,11 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
 
 static int is_color_space_conversion(struct dw_hdmi *hdmi)
 {
-	return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format;
+	return (hdmi->hdmi_data.enc_in_bus_format !=
+			hdmi->hdmi_data.enc_out_bus_format) ||
+	       (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) &&
+		hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) &&
+		hdmi->hdmi_data.rgb_limited_range);
 }
 
 static int is_color_space_decimation(struct dw_hdmi *hdmi)
@@ -986,25 +997,27 @@ static int is_color_space_interpolation(struct dw_hdmi *hdmi)
 static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
 {
 	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
+	bool is_input_rgb, is_output_rgb;
 	unsigned i;
 	u32 csc_scale = 1;
 
-	if (is_color_space_conversion(hdmi)) {
-		if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
-			if (hdmi->hdmi_data.enc_out_encoding ==
-						V4L2_YCBCR_ENC_601)
-				csc_coeff = &csc_coeff_rgb_out_eitu601;
-			else
-				csc_coeff = &csc_coeff_rgb_out_eitu709;
-		} else if (hdmi_bus_fmt_is_rgb(
-					hdmi->hdmi_data.enc_in_bus_format)) {
-			if (hdmi->hdmi_data.enc_out_encoding ==
-						V4L2_YCBCR_ENC_601)
-				csc_coeff = &csc_coeff_rgb_in_eitu601;
-			else
-				csc_coeff = &csc_coeff_rgb_in_eitu709;
-			csc_scale = 0;
-		}
+	is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format);
+	is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format);
+
+	if (!is_input_rgb && is_output_rgb) {
+		if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
+			csc_coeff = &csc_coeff_rgb_out_eitu601;
+		else
+			csc_coeff = &csc_coeff_rgb_out_eitu709;
+	} else if (is_input_rgb && !is_output_rgb) {
+		if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
+			csc_coeff = &csc_coeff_rgb_in_eitu601;
+		else
+			csc_coeff = &csc_coeff_rgb_in_eitu709;
+		csc_scale = 0;
+	} else if (is_input_rgb && is_output_rgb &&
+		   hdmi->hdmi_data.rgb_limited_range) {
+		csc_coeff = &csc_coeff_rgb_full_to_rgb_limited;
 	}
 
 	/* The CSC registers are sequential, alternating MSB then LSB */
@@ -1614,6 +1627,18 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	drm_hdmi_avi_infoframe_from_display_mode(&frame,
 						 &hdmi->connector, mode);
 
+	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
+		drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector,
+						   mode,
+						   hdmi->hdmi_data.rgb_limited_range ?
+						   HDMI_QUANTIZATION_RANGE_LIMITED :
+						   HDMI_QUANTIZATION_RANGE_FULL);
+	} else {
+		frame.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+		frame.ycc_quantization_range =
+			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
+	}
+
 	if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
 		frame.colorspace = HDMI_COLORSPACE_YUV444;
 	else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
@@ -2099,6 +2124,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	/* TOFIX: Default to RGB888 output format */
 	hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
+	hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi &&
+		drm_default_rgb_quant_range(mode) ==
+		HDMI_QUANTIZATION_RANGE_LIMITED;
+
 	hdmi->hdmi_data.pix_repet_factor = 0;
 	hdmi->hdmi_data.hdcp_enable = 0;
 	hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/4] drm/bridge: dw-hdmi: rework csc related functions
  2020-03-04 23:25 [PATCH v2 0/4] drm/bridge: dw-hdmi: Various updates Jernej Skrabec
                   ` (2 preceding siblings ...)
  2020-03-04 23:25 ` [PATCH v2 3/4] drm/bridge: dw-hdmi: Add support for RGB limited range Jernej Skrabec
@ 2020-03-04 23:25 ` Jernej Skrabec
  2020-03-04 23:51   ` Laurent Pinchart
  3 siblings, 1 reply; 9+ messages in thread
From: Jernej Skrabec @ 2020-03-04 23:25 UTC (permalink / raw)
  To: a.hajda, narmstrong
  Cc: Laurent.pinchart, jonas, jernej.skrabec, airlied, daniel,
	dri-devel, linux-kernel

is_color_space_conversion() is a misnomer. It checks not only if color
space conversion is needed, but also if format conversion is needed.
This is actually desired behaviour because result of this function
determines if CSC block should be enabled or not (CSC block can also do
format conversion).

In order to clear misunderstandings, let's rework
is_color_space_conversion() to do exactly what is supposed to do and add
another function which will determine if CSC block must be enabled or
not.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 +++++++++++++++--------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index c8a02e5b5e1b..7724191e0a8b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -963,11 +963,14 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
 
 static int is_color_space_conversion(struct dw_hdmi *hdmi)
 {
-	return (hdmi->hdmi_data.enc_in_bus_format !=
-			hdmi->hdmi_data.enc_out_bus_format) ||
-	       (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) &&
-		hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) &&
-		hdmi->hdmi_data.rgb_limited_range);
+	struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
+	bool is_input_rgb, is_output_rgb;
+
+	is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_in_bus_format);
+	is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_out_bus_format);
+
+	return (is_input_rgb != is_output_rgb) ||
+	       (is_input_rgb && is_output_rgb && hdmi_data->rgb_limited_range);
 }
 
 static int is_color_space_decimation(struct dw_hdmi *hdmi)
@@ -994,6 +997,13 @@ static int is_color_space_interpolation(struct dw_hdmi *hdmi)
 	return 0;
 }
 
+static bool is_conversion_needed(struct dw_hdmi *hdmi)
+{
+	return is_color_space_conversion(hdmi) ||
+	       is_color_space_decimation(hdmi) ||
+	       is_color_space_interpolation(hdmi);
+}
+
 static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
 {
 	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
@@ -2014,18 +2024,19 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 
 	/* Enable csc path */
-	if (is_color_space_conversion(hdmi)) {
+	if (is_conversion_needed(hdmi)) {
 		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
 		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
-	}
 
-	/* Enable color space conversion if needed */
-	if (is_color_space_conversion(hdmi))
 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
 			    HDMI_MC_FLOWCTRL);
-	else
+	} else {
+		hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+
 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
 			    HDMI_MC_FLOWCTRL);
+	}
 }
 
 /* Workaround to clear the overflow condition */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/4] drm/bridge: dw-hdmi: Add support for RGB limited range
  2020-03-04 23:25 ` [PATCH v2 3/4] drm/bridge: dw-hdmi: Add support for RGB limited range Jernej Skrabec
@ 2020-03-04 23:47   ` Laurent Pinchart
  0 siblings, 0 replies; 9+ messages in thread
From: Laurent Pinchart @ 2020-03-04 23:47 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: a.hajda, narmstrong, jonas, airlied, daniel, dri-devel, linux-kernel

Hi Jernej,

Thank you for the patch.

On Thu, Mar 05, 2020 at 12:25:11AM +0100, Jernej Skrabec wrote:
> CEA 861 standard requestis that RGB quantization range is "limited" for
> CEA modes. Support that by adding CSC matrix which downscales values.
> 
> This allows proper color reproduction on TV and PC monitor at the same
> time. In future, override property can be added, like "Broadcast RGB"
> in i915 driver.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 63 +++++++++++++++++------
>  1 file changed, 46 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index de2c7ec887c8..c8a02e5b5e1b 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -92,6 +92,12 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
>  	{ 0x6756, 0x78ab, 0x2000, 0x0200 }
>  };
>  
> +static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
> +	{ 0x1b7c, 0x0000, 0x0000, 0x0020 },
> +	{ 0x0000, 0x1b7c, 0x0000, 0x0020 },
> +	{ 0x0000, 0x0000, 0x1b7c, 0x0020 }
> +};
> +
>  struct hdmi_vmode {
>  	bool mdataenablepolarity;
>  
> @@ -109,6 +115,7 @@ struct hdmi_data_info {
>  	unsigned int pix_repet_factor;
>  	unsigned int hdcp_enable;
>  	struct hdmi_vmode video_mode;
> +	bool rgb_limited_range;
>  };
>  
>  struct dw_hdmi_i2c {
> @@ -956,7 +963,11 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
>  
>  static int is_color_space_conversion(struct dw_hdmi *hdmi)
>  {
> -	return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format;
> +	return (hdmi->hdmi_data.enc_in_bus_format !=
> +			hdmi->hdmi_data.enc_out_bus_format) ||
> +	       (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) &&
> +		hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) &&
> +		hdmi->hdmi_data.rgb_limited_range);
>  }
>  
>  static int is_color_space_decimation(struct dw_hdmi *hdmi)
> @@ -986,25 +997,27 @@ static int is_color_space_interpolation(struct dw_hdmi *hdmi)
>  static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
>  {
>  	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
> +	bool is_input_rgb, is_output_rgb;
>  	unsigned i;
>  	u32 csc_scale = 1;
>  
> -	if (is_color_space_conversion(hdmi)) {
> -		if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
> -			if (hdmi->hdmi_data.enc_out_encoding ==
> -						V4L2_YCBCR_ENC_601)
> -				csc_coeff = &csc_coeff_rgb_out_eitu601;
> -			else
> -				csc_coeff = &csc_coeff_rgb_out_eitu709;
> -		} else if (hdmi_bus_fmt_is_rgb(
> -					hdmi->hdmi_data.enc_in_bus_format)) {
> -			if (hdmi->hdmi_data.enc_out_encoding ==
> -						V4L2_YCBCR_ENC_601)
> -				csc_coeff = &csc_coeff_rgb_in_eitu601;
> -			else
> -				csc_coeff = &csc_coeff_rgb_in_eitu709;
> -			csc_scale = 0;
> -		}
> +	is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format);
> +	is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format);
> +
> +	if (!is_input_rgb && is_output_rgb) {
> +		if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
> +			csc_coeff = &csc_coeff_rgb_out_eitu601;
> +		else
> +			csc_coeff = &csc_coeff_rgb_out_eitu709;
> +	} else if (is_input_rgb && !is_output_rgb) {
> +		if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
> +			csc_coeff = &csc_coeff_rgb_in_eitu601;
> +		else
> +			csc_coeff = &csc_coeff_rgb_in_eitu709;
> +		csc_scale = 0;
> +	} else if (is_input_rgb && is_output_rgb &&
> +		   hdmi->hdmi_data.rgb_limited_range) {
> +		csc_coeff = &csc_coeff_rgb_full_to_rgb_limited;
>  	}
>  
>  	/* The CSC registers are sequential, alternating MSB then LSB */
> @@ -1614,6 +1627,18 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  	drm_hdmi_avi_infoframe_from_display_mode(&frame,
>  						 &hdmi->connector, mode);
>  
> +	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
> +		drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector,
> +						   mode,
> +						   hdmi->hdmi_data.rgb_limited_range ?
> +						   HDMI_QUANTIZATION_RANGE_LIMITED :
> +						   HDMI_QUANTIZATION_RANGE_FULL);
> +	} else {
> +		frame.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
> +		frame.ycc_quantization_range =
> +			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
> +	}
> +
>  	if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
>  		frame.colorspace = HDMI_COLORSPACE_YUV444;
>  	else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
> @@ -2099,6 +2124,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  	/* TOFIX: Default to RGB888 output format */
>  	hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>  
> +	hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi &&
> +		drm_default_rgb_quant_range(mode) ==
> +		HDMI_QUANTIZATION_RANGE_LIMITED;
> +
>  	hdmi->hdmi_data.pix_repet_factor = 0;
>  	hdmi->hdmi_data.hdcp_enable = 0;
>  	hdmi->hdmi_data.video_mode.mdataenablepolarity = true;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/4] drm/bridge: dw-hdmi: rework csc related functions
  2020-03-04 23:25 ` [PATCH v2 4/4] drm/bridge: dw-hdmi: rework csc related functions Jernej Skrabec
@ 2020-03-04 23:51   ` Laurent Pinchart
  2020-03-05 16:53     ` Jernej Škrabec
  0 siblings, 1 reply; 9+ messages in thread
From: Laurent Pinchart @ 2020-03-04 23:51 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: a.hajda, narmstrong, jonas, airlied, daniel, dri-devel, linux-kernel

Hi Jernej,

Thank you for the patch.

On Thu, Mar 05, 2020 at 12:25:12AM +0100, Jernej Skrabec wrote:
> is_color_space_conversion() is a misnomer. It checks not only if color
> space conversion is needed, but also if format conversion is needed.
> This is actually desired behaviour because result of this function
> determines if CSC block should be enabled or not (CSC block can also do
> format conversion).
> 
> In order to clear misunderstandings, let's rework
> is_color_space_conversion() to do exactly what is supposed to do and add
> another function which will determine if CSC block must be enabled or
> not.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 +++++++++++++++--------
>  1 file changed, 21 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index c8a02e5b5e1b..7724191e0a8b 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -963,11 +963,14 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
>  
>  static int is_color_space_conversion(struct dw_hdmi *hdmi)
>  {
> -	return (hdmi->hdmi_data.enc_in_bus_format !=
> -			hdmi->hdmi_data.enc_out_bus_format) ||
> -	       (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) &&
> -		hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) &&
> -		hdmi->hdmi_data.rgb_limited_range);
> +	struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
> +	bool is_input_rgb, is_output_rgb;
> +
> +	is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_in_bus_format);
> +	is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_out_bus_format);
> +
> +	return (is_input_rgb != is_output_rgb) ||
> +	       (is_input_rgb && is_output_rgb && hdmi_data->rgb_limited_range);
>  }
>  
>  static int is_color_space_decimation(struct dw_hdmi *hdmi)
> @@ -994,6 +997,13 @@ static int is_color_space_interpolation(struct dw_hdmi *hdmi)
>  	return 0;
>  }
>  
> +static bool is_conversion_needed(struct dw_hdmi *hdmi)

Maybe is_csc_needed ?

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +{
> +	return is_color_space_conversion(hdmi) ||
> +	       is_color_space_decimation(hdmi) ||
> +	       is_color_space_interpolation(hdmi);
> +}
> +
>  static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
>  {
>  	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
> @@ -2014,18 +2024,19 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
>  	/* Enable csc path */
> -	if (is_color_space_conversion(hdmi)) {
> +	if (is_conversion_needed(hdmi)) {
>  		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
>  		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> -	}
>  
> -	/* Enable color space conversion if needed */
> -	if (is_color_space_conversion(hdmi))
>  		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
>  			    HDMI_MC_FLOWCTRL);
> -	else
> +	} else {
> +		hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> +		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +
>  		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
>  			    HDMI_MC_FLOWCTRL);
> +	}
>  }
>  
>  /* Workaround to clear the overflow condition */

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/4] drm/bridge: dw-hdmi: rework csc related functions
  2020-03-04 23:51   ` Laurent Pinchart
@ 2020-03-05 16:53     ` Jernej Škrabec
  0 siblings, 0 replies; 9+ messages in thread
From: Jernej Škrabec @ 2020-03-05 16:53 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: a.hajda, narmstrong, jonas, airlied, daniel, dri-devel, linux-kernel

Hi Laurent,

Dne četrtek, 05. marec 2020 ob 00:51:49 CET je Laurent Pinchart napisal(a):
> Hi Jernej,
> 
> Thank you for the patch.
> 
> On Thu, Mar 05, 2020 at 12:25:12AM +0100, Jernej Skrabec wrote:
> > is_color_space_conversion() is a misnomer. It checks not only if color
> > space conversion is needed, but also if format conversion is needed.
> > This is actually desired behaviour because result of this function
> > determines if CSC block should be enabled or not (CSC block can also do
> > format conversion).
> > 
> > In order to clear misunderstandings, let's rework
> > is_color_space_conversion() to do exactly what is supposed to do and add
> > another function which will determine if CSC block must be enabled or
> > not.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 +++++++++++++++--------
> >  1 file changed, 21 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
> > c8a02e5b5e1b..7724191e0a8b 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -963,11 +963,14 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
> > 
> >  static int is_color_space_conversion(struct dw_hdmi *hdmi)
> >  {
> > 
> > -	return (hdmi->hdmi_data.enc_in_bus_format !=
> > -			hdmi->hdmi_data.enc_out_bus_format) ||
> > -	       (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) &&
> > -		hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) 
&&
> > -		hdmi->hdmi_data.rgb_limited_range);
> > +	struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
> > +	bool is_input_rgb, is_output_rgb;
> > +
> > +	is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_in_bus_format);
> > +	is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi_data-
>enc_out_bus_format);
> > +
> > +	return (is_input_rgb != is_output_rgb) ||
> > +	       (is_input_rgb && is_output_rgb && hdmi_data-
>rgb_limited_range);
> > 
> >  }
> >  
> >  static int is_color_space_decimation(struct dw_hdmi *hdmi)
> > 
> > @@ -994,6 +997,13 @@ static int is_color_space_interpolation(struct
> > dw_hdmi *hdmi)> 
> >  	return 0;
> >  
> >  }
> > 
> > +static bool is_conversion_needed(struct dw_hdmi *hdmi)
> 
> Maybe is_csc_needed ?

Ok, I'll fix during applying.

> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Thanks!

Best regards,
Jernej

> 
> > +{
> > +	return is_color_space_conversion(hdmi) ||
> > +	       is_color_space_decimation(hdmi) ||
> > +	       is_color_space_interpolation(hdmi);
> > +}
> > +
> > 
> >  static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
> >  {
> >  
> >  	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
> > 
> > @@ -2014,18 +2024,19 @@ static void dw_hdmi_enable_video_path(struct
> > dw_hdmi *hdmi)> 
> >  	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> >  	
> >  	/* Enable csc path */
> > 
> > -	if (is_color_space_conversion(hdmi)) {
> > +	if (is_conversion_needed(hdmi)) {
> > 
> >  		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> >  		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> > 
> > -	}
> > 
> > -	/* Enable color space conversion if needed */
> > -	if (is_color_space_conversion(hdmi))
> > 
> >  		hdmi_writeb(hdmi, 
HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
> >  		
> >  			    HDMI_MC_FLOWCTRL);
> > 
> > -	else
> > +	} else {
> > +		hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> > +		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> > +
> > 
> >  		hdmi_writeb(hdmi, 
HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
> >  		
> >  			    HDMI_MC_FLOWCTRL);
> > 
> > +	}
> > 
> >  }
> >  
> >  /* Workaround to clear the overflow condition */





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry
  2020-03-04 23:25 ` [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry Jernej Skrabec
@ 2020-03-05 17:14   ` Jernej Škrabec
  0 siblings, 0 replies; 9+ messages in thread
From: Jernej Škrabec @ 2020-03-05 17:14 UTC (permalink / raw)
  To: a.hajda, narmstrong
  Cc: Laurent.pinchart, jonas, airlied, daniel, dri-devel,
	linux-kernel, Laurent Pinchart

Dne četrtek, 05. marec 2020 ob 00:25:09 CET je Jernej Skrabec napisal(a):
> CTA-861-F explicitly states that for RGB colorspace colorimetry should
> be set to "none". Fix that.
> 
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Fixes: def23aa7e982 ("drm: bridge: dw-hdmi: Switch to V4L bus format and
> encodings") Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Applied to drm-next-fixes.

Best regards,
Jernej



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-03-05 17:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-04 23:25 [PATCH v2 0/4] drm/bridge: dw-hdmi: Various updates Jernej Skrabec
2020-03-04 23:25 ` [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry Jernej Skrabec
2020-03-05 17:14   ` Jernej Škrabec
2020-03-04 23:25 ` [PATCH v2 2/4] drm/bridge: dw-hdmi: do not force "none" scan mode Jernej Skrabec
2020-03-04 23:25 ` [PATCH v2 3/4] drm/bridge: dw-hdmi: Add support for RGB limited range Jernej Skrabec
2020-03-04 23:47   ` Laurent Pinchart
2020-03-04 23:25 ` [PATCH v2 4/4] drm/bridge: dw-hdmi: rework csc related functions Jernej Skrabec
2020-03-04 23:51   ` Laurent Pinchart
2020-03-05 16:53     ` Jernej Škrabec

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).