The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Igor Paunovic <royalnet026@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
	linux-rockchip@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	"Sebastian Reichel" <sebastian.reichel@collabora.com>,
	"Cristian Ciocaltea" <cristian.ciocaltea@collabora.com>,
	"Andrzej Hajda" <andrzej.hajda@intel.com>,
	"Neil Armstrong" <neil.armstrong@linaro.org>,
	"Robert Foss" <rfoss@kernel.org>,
	"Laurent Pinchart" <Laurent.pinchart@ideasonboard.com>,
	"Jonas Karlman" <jonas@kwiboo.se>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	"Luca Ceresoli" <luca.ceresoli@bootlin.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>,
	"Sandy Huang" <hjc@rock-chips.com>,
	"Heiko Stübner" <heiko@sntech.de>,
	"Andy Yan" <andy.yan@rock-chips.com>,
	"Jani Nikula" <jani.nikula@linux.intel.com>,
	"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
	"Ville Syrjälä" <ville.syrjala@linux.intel.com>,
	"Imre Deak" <imre.deak@intel.com>,
	"Ankit Nautiyal" <ankit.k.nautiyal@intel.com>,
	"Igor Paunovic" <royalnet026@gmail.com>
Subject: [PATCH 5/5] drm/bridge: synopsys: dw-dp: Add BT.2020 colorimetry support
Date: Sat,  8 Aug 2026 11:57:24 +0200	[thread overview]
Message-ID: <20260808095749.9428-6-royalnet026@gmail.com> (raw)
In-Reply-To: <20260808095749.9428-1-royalnet026@gmail.com>

The VSC SDP colorimetry is hardcoded: DEFAULT for RGB output and
BT709_YCC for YCbCr. HDR compositors render into a BT.2020 container
and need a way to tell the sink.

The legacy MSA MISC0 colorimetry bits cannot express BT.2020; DP 1.4a
requires the VSC SDP revision 5 pixel encoding/colorimetry format
indication, with MISC1 bit 6 set so the sink takes the format from the
VSC SDP instead of MISC0. The driver already sets MISC1 bit 6 whenever
it sends the VSC SDP, so only the trigger and the colorimetry values
need extending:

- store conn_state->colorspace in the bridge state during
  atomic_check(), next to the negotiated format;
- send the VSC SDP also when the colorspace is BT2020_RGB or
  BT2020_YCC, not only for YCbCr 4:2:0 output;
- map BT2020_RGB/BT2020_YCC to DP_COLORIMETRY_BT2020_RGB/
  DP_COLORIMETRY_BT2020_YCC in the VSC SDP; every other colorspace
  value keeps today's values. The dynamic range stays VESA for RGB and
  CTA for YCbCr output.

Sinks advertise VSC SDP colorimetry support in the DPCD
(DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED). Without it BT.2020 cannot
be signaled at all, so atomic_check() rejects such a request with
-EINVAL and userspace's TEST_ONLY probe learns the configuration is
impossible; i915 instead silently omits the VSC SDP and scans out
BT.2020 pixels without signaling them. A colorspace change on a live
stream forces a modeset, so the VSC SDP is regenerated with the new
colorimetry.

On the Rockchip side, create the DP Colorspace property with exactly
the enum values the driver implements (Default, BT2020_RGB,
BT2020_YCC). When the colorspace is BT.2020 and the negotiated bus
format is YCbCr, program s->color_space = V4L2_COLORSPACE_BT2020 so
the VOP2 uses its BT.2020 R'G'B' to Y'C'bC'r matrix for the CSC. For
RGB output the pixels leave the VOP2 unconverted and the color space
stays DEFAULT.

Userspace that leaves the property at "Default" sees no change in
behavior: the colorimetry mapping, the VSC SDP trigger and the VOP2
CSC selection all take the previous paths.

Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c   | 44 +++++++++++++++++++----
 drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 38 +++++++++++++++++++-
 2 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index ca997ea53e66..8f0ee9628dcc 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -306,6 +306,7 @@ struct dw_dp_bridge_state {
 	u8 color_format;
 	u8 bpc;
 	u8 bpp;
+	enum drm_colorspace colorspace;
 };
 
 struct dw_dp_sdp {
@@ -1125,6 +1126,12 @@ static void dw_dp_clear_sdp(struct dw_dp *dp, int nr)
 		clear_bit(nr, dp->sdp_reg_bank);
 }
 
+static bool dw_dp_colorspace_is_bt2020(enum drm_colorspace colorspace)
+{
+	return colorspace == DRM_MODE_COLORIMETRY_BT2020_RGB ||
+	       colorspace == DRM_MODE_COLORIMETRY_BT2020_YCC;
+}
+
 static int dw_dp_send_vsc_sdp(struct dw_dp *dp)
 {
 	struct dw_dp_bridge_state *state;
@@ -1160,13 +1167,25 @@ static int dw_dp_send_vsc_sdp(struct dw_dp *dp)
 		break;
 	}
 
-	if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_RGB444) {
-		vsc.colorimetry = DP_COLORIMETRY_DEFAULT;
+	switch (state->colorspace) {
+	case DRM_MODE_COLORIMETRY_BT2020_RGB:
+		vsc.colorimetry = DP_COLORIMETRY_BT2020_RGB;
+		break;
+	case DRM_MODE_COLORIMETRY_BT2020_YCC:
+		vsc.colorimetry = DP_COLORIMETRY_BT2020_YCC;
+		break;
+	default:
+		if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_RGB444)
+			vsc.colorimetry = DP_COLORIMETRY_DEFAULT;
+		else
+			vsc.colorimetry = DP_COLORIMETRY_BT709_YCC;
+		break;
+	}
+
+	if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_RGB444)
 		vsc.dynamic_range = DP_DYNAMIC_RANGE_VESA;
-	} else {
-		vsc.colorimetry = DP_COLORIMETRY_BT709_YCC;
+	else
 		vsc.dynamic_range = DP_DYNAMIC_RANGE_CTA;
-	}
 
 	drm_dp_vsc_sdp_pack(&vsc, &sdp.base);
 
@@ -1227,7 +1246,7 @@ static bool dw_dp_video_need_vsc_sdp(struct dw_dp *dp)
 	if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_YCBCR420)
 		return true;
 
-	return false;
+	return dw_dp_colorspace_is_bt2020(state->colorspace);
 }
 
 static int dw_dp_video_set_msa(struct dw_dp *dp,
@@ -1644,10 +1663,21 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge,
 	state->color_format = fmt->color_format;
 	state->bpc = fmt->bpc;
 	state->bpp = fmt->bpp;
+	state->colorspace = conn_state->colorspace;
+
+	/*
+	 * BT.2020 cannot be signaled through the legacy MSA MISC0
+	 * colorimetry bits; it requires the VSC SDP colorimetry format
+	 * indication, which the sink must support.
+	 */
+	if (dw_dp_colorspace_is_bt2020(conn_state->colorspace) &&
+	    !dp->link.vsc_sdp_supported)
+		return -EINVAL;
 
 	old_conn_state = drm_atomic_get_old_connector_state(conn_state->state,
 							    conn_state->connector);
-	if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, conn_state))
+	if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, conn_state) ||
+	    old_conn_state->colorspace != conn_state->colorspace)
 		crtc_state->mode_changed = true;
 
 	if ((adjusted_mode->hsync_start - adjusted_mode->hdisplay) & 0x1) {
diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
index c5bc178c0a50..798d82893f98 100644
--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
@@ -69,6 +69,21 @@ static void dw_dp_rockchip_hpd_sw_cfg(void *data, bool hpd)
 		     FIELD_PREP_WM16(ROCKCHIP_VO_GRF_DP_SINK_HPD_CFG, hpd));
 }
 
+static bool dw_dp_yuv_bus_format(u32 bus_format)
+{
+	switch (bus_format) {
+	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+	case MEDIA_BUS_FMT_YUYV10_1X20:
+	case MEDIA_BUS_FMT_YUYV8_1X16:
+	case MEDIA_BUS_FMT_YUV10_1X30:
+	case MEDIA_BUS_FMT_YUV8_1X24:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder,
 				      struct drm_crtc_state *crtc_state,
 				      struct drm_connector_state *conn_state)
@@ -102,7 +117,17 @@ static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder,
 	s->output_type = DRM_MODE_CONNECTOR_DisplayPort;
 	s->bus_format = bus_format;
 	s->bus_flags = di->bus_flags;
-	s->color_space = V4L2_COLORSPACE_DEFAULT;
+
+	/*
+	 * For BT.2020 YCbCr output the VOP2 must use its BT.2020 R'G'B' to
+	 * Y'C'bC'r matrix; BT.2020 RGB is passed through unconverted.
+	 */
+	if ((conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_RGB ||
+	     conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_YCC) &&
+	    dw_dp_yuv_bus_format(bus_format))
+		s->color_space = V4L2_COLORSPACE_BT2020;
+	else
+		s->color_space = V4L2_COLORSPACE_DEFAULT;
 
 	return 0;
 }
@@ -200,6 +225,17 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *
 
 	drm_connector_attach_hdr_output_metadata_property(connector);
 
+	ret = drm_mode_create_dp_colorspace_property(connector,
+						     BIT(DRM_MODE_COLORIMETRY_DEFAULT) |
+						     BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) |
+						     BIT(DRM_MODE_COLORIMETRY_BT2020_YCC));
+	if (ret) {
+		dw_dp_unbind(dp->base);
+		return ret;
+	}
+
+	drm_connector_attach_colorspace_property(connector);
+
 	return 0;
 }
 
-- 
2.43.0


      parent reply	other threads:[~2026-08-08  9:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-08  9:57 [PATCH 0/5] drm/bridge: synopsys: dw-dp: Add HDR support Igor Paunovic
2026-08-08  9:57 ` [PATCH 1/5] drm/dp: Add drm_dp_hdr_metadata_infoframe_sdp_pack() Igor Paunovic
2026-08-08  9:57 ` [PATCH 2/5] drm/display: bridge-connector: Preserve max bpc across connector reset Igor Paunovic
2026-08-08  9:57 ` [PATCH 3/5] drm/rockchip: dw_dp: Attach "max bpc" connector property Igor Paunovic
2026-08-08  9:57 ` [PATCH 4/5] drm/bridge: synopsys: dw-dp: Add HDR static metadata support Igor Paunovic
2026-08-08  9:57 ` Igor Paunovic [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260808095749.9428-6-royalnet026@gmail.com \
    --to=royalnet026@gmail.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=airlied@gmail.com \
    --cc=andrzej.hajda@intel.com \
    --cc=andy.yan@rock-chips.com \
    --cc=ankit.k.nautiyal@intel.com \
    --cc=cristian.ciocaltea@collabora.com \
    --cc=dmitry.baryshkov@oss.qualcomm.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=heiko@sntech.de \
    --cc=hjc@rock-chips.com \
    --cc=imre.deak@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=jonas@kwiboo.se \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=luca.ceresoli@bootlin.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=neil.armstrong@linaro.org \
    --cc=rfoss@kernel.org \
    --cc=rodrigo.vivi@intel.com \
    --cc=sebastian.reichel@collabora.com \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    --cc=ville.syrjala@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox