* [PATCH 0/5] drm/bridge: synopsys: dw-dp: Add HDR support
@ 2026-08-08 9:57 Igor Paunovic
2026-08-08 9:57 ` [PATCH 1/5] drm/dp: Add drm_dp_hdr_metadata_infoframe_sdp_pack() Igor Paunovic
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Igor Paunovic @ 2026-08-08 9:57 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, linux-rockchip, linux-arm-kernel,
linux-kernel, Sebastian Reichel, Cristian Ciocaltea,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Dmitry Baryshkov, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Ville Syrjälä, Imre Deak,
Ankit Nautiyal, Igor Paunovic
This series teaches the Synopsys DesignWare DisplayPort bridge driver
(dw-dp) to drive HDR sinks: it attaches the "max bpc",
HDR_OUTPUT_METADATA and Colorspace connector properties and transmits
the matching HDR Metadata InfoFrame SDP and BT.2020 VSC SDP
colorimetry on the link. With the series applied, a Wayland compositor
(tested with KWin 6.6.5) recognises the DP output as HDR capable and
can enable HDR with wide color gamut on it.
The series applies on drm-misc-next with Sebastian Reichel's
"Synopsys DisplayPort Controller improvements" v11 [1] applied; the
SDP infrastructure this series builds on (per-slot tracking, locking,
the drm_output_color_format conversion) comes from that series. Happy
to rebase on a future revision.
Patch 1 lifts i915's HDR Metadata InfoFrame SDP packer into
drm_dp_helper.c as drm_dp_hdr_metadata_infoframe_sdp_pack() and
converts i915. Nothing in it is i915 specific.
Patch 2 fixes a latent bridge-connector problem that attaching
"max bpc" would otherwise expose: a connector that attached the
property before drm_mode_config_reset() comes out of that reset with a
freshly zeroed state and nothing restores max_requested_bpc. A driver
that filters formats on conn_state->max_bpc then rejects every format,
and property-naive clients (fbcon in particular) end up with a black
screen. The HDMI bridge-connector path already restores the value from
connector->max_bpc in drm_bridge_connector_create_state(); patch 2
mirrors that on the non-HDMI path. The meson no-regression analysis is
in the commit message.
Patches 3-5 are the dw-dp/Rockchip side: attach "max bpc" with range
(6, 10) - the driver's format table tops out at 10 bpc - then send the
HDR Metadata InfoFrame SDP once per frame while HDR metadata is set,
and signal BT.2020 colorimetry via VSC SDP revision 5, including the
VOP2 CSC selection in the Rockchip glue. BT.2020 requests are rejected
in atomic_check() when the sink's DPCD lacks
DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED, so a userspace TEST_ONLY
probe learns the configuration is impossible; i915 instead silently
omits the VSC SDP in that case (patch 5 has the details).
About the base, so that the test results below are not read too
widely: the runtime testing was done on a rockchip-devel based kernel,
which carries the v9 generation of the dw-dp series, with this series
on top. The series as posted is rebased onto drm-misc-next + v11,
where it applies without conflicts and the touched objects build
cleanly, but I have not repeated the runtime tests on that base. I
did test v11 itself on the same board separately [2].
Hardware: Rockchip RK3588 (Orange Pi 5 Plus), Samsung Odyssey G70B
connected over USB-C DP alt mode through a USB-C to HDMI 2.1 protocol
converter (DPCD ext rev 1.4, HBR2 x4, VSC SDP colorimetry supported):
- KWin 6.6.5 flips the output from "HDR: incapable" to HDR capable as
soon as the properties appear, and enables HDR + wide color gamut:
the monitor switches to HDR mode and the picture visually matches
the same panel driven from the board's HDMI output (dw-hdmi-qp) with
HDR enabled. DRM state while HDR is on: "max bpc" = 10, Colorspace =
BT2020_RGB, HDR_OUTPUT_METADATA blob with SMPTE ST 2084 EOTF.
- Twelve consecutive HDR off/on cycles (24 modesets): no link or SDP
errors and no -EBUSY from SDP slot allocation.
- Plain SDR behavior is unchanged. Once the properties exist KWin
writes Colorspace=Default, a NULL metadata blob and "max bpc" on
every atomic modeset - verified to be a no-op.
- The board boots to a working display with the properties attached,
i.e. the boot-time config-reset path that patch 2 protects.
Bandwidth note, for why "max bpc" matters here: on this HBR2 link
4K60 RGB 10-bit does not fit (17.82 Gbit/s payload vs 17.28
available), so 10-bit output needs YCbCr subsampling on this
converter; native HBR3 links have the headroom for 4K60 10-bit RGB.
[1] https://lore.kernel.org/dri-devel/20260806-synopsys-dw-dp-improvements-v11-0-0d508505f383@collabora.com/
[2] https://lore.kernel.org/all/20260808094138.7205-1-royalnet026@gmail.com/
Igor Paunovic (5):
drm/dp: Add drm_dp_hdr_metadata_infoframe_sdp_pack()
drm/display: bridge-connector: Preserve max bpc across connector reset
drm/rockchip: dw_dp: Attach "max bpc" connector property
drm/bridge: synopsys: dw-dp: Add HDR static metadata support
drm/bridge: synopsys: dw-dp: Add BT.2020 colorimetry support
drivers/gpu/drm/bridge/synopsys/dw-dp.c | 86 ++++++++++++++++++++++---
drivers/gpu/drm/display/drm_bridge_connector.c | 6 +-
drivers/gpu/drm/display/drm_dp_helper.c | 88 ++++++++++++++++++++++++++
drivers/gpu/drm/drm_connector.c | 5 ++
drivers/gpu/drm/i915/display/intel_dp.c | 84 +-----------------------
drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 66 ++++++++++++++++++-
include/drm/display/drm_dp_helper.h | 4 ++
7 files changed, 248 insertions(+), 91 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/5] drm/dp: Add drm_dp_hdr_metadata_infoframe_sdp_pack()
2026-08-08 9:57 [PATCH 0/5] drm/bridge: synopsys: dw-dp: Add HDR support Igor Paunovic
@ 2026-08-08 9:57 ` Igor Paunovic
2026-08-08 9:57 ` [PATCH 2/5] drm/display: bridge-connector: Preserve max bpc across connector reset Igor Paunovic
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Igor Paunovic @ 2026-08-08 9:57 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, linux-rockchip, linux-arm-kernel,
linux-kernel, Sebastian Reichel, Cristian Ciocaltea,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Dmitry Baryshkov, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Ville Syrjälä, Imre Deak,
Ankit Nautiyal, Igor Paunovic
i915 packs HDR static metadata into an HDR Metadata InfoFrame SDP
(DP 1.4a spec, Table 2-100 and Table 2-101) with a driver-private
helper, intel_dp_hdr_metadata_infoframe_sdp_pack(). Nothing in it is
i915 specific: it converts a generic struct hdmi_drm_infoframe into a
generic struct dp_sdp.
Move it to drm_dp_helper.c as drm_dp_hdr_metadata_infoframe_sdp_pack(),
next to drm_dp_vsc_sdp_pack(), and convert i915 to the new helper. The
Synopsys DesignWare DisplayPort bridge driver (dw-dp) needs to send the
same SDP to support HDR and should not have to duplicate the packing
code.
The helper takes a struct drm_device pointer in place of the i915
display pointer for its two debug messages, and an i915-specific
comment about GEN11+ GMP register sizes is dropped. No functional
change.
Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
---
drivers/gpu/drm/display/drm_dp_helper.c | 88 +++++++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_dp.c | 84 +----------------------
include/drm/display/drm_dp_helper.h | 4 ++
3 files changed, 95 insertions(+), 81 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 9c31e14cc413..7b3b079403c4 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -25,6 +25,7 @@
#include <linux/dynamic_debug.h>
#include <linux/errno.h>
#include <linux/export.h>
+#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/iopoll.h>
@@ -3672,6 +3673,93 @@ ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
}
EXPORT_SYMBOL(drm_dp_vsc_sdp_pack);
+/**
+ * drm_dp_hdr_metadata_infoframe_sdp_pack() - pack HDR Metadata InfoFrame SDP
+ * @dev: DRM device
+ * @drm_infoframe: HDMI DRM infoframe carrying the HDR static metadata
+ * @sdp: valid handle to the generic dp_sdp which will be packed
+ * @size: valid size of the passed sdp handle
+ *
+ * Pack a CTA-861 Dynamic Range and Mastering infoframe into an HDR
+ * Metadata InfoFrame SDP, as defined in DP 1.4a spec, Table 2-100 and
+ * Table 2-101.
+ *
+ * Returns: length of sdp on success and error code on failure
+ */
+ssize_t drm_dp_hdr_metadata_infoframe_sdp_pack(struct drm_device *dev,
+ const struct hdmi_drm_infoframe *drm_infoframe,
+ struct dp_sdp *sdp,
+ size_t size)
+{
+ size_t length = sizeof(struct dp_sdp);
+ const int infoframe_size = HDMI_INFOFRAME_HEADER_SIZE + HDMI_DRM_INFOFRAME_SIZE;
+ unsigned char buf[HDMI_INFOFRAME_HEADER_SIZE + HDMI_DRM_INFOFRAME_SIZE];
+ ssize_t len;
+
+ if (size < length)
+ return -ENOSPC;
+
+ memset(sdp, 0, size);
+
+ len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf));
+ if (len < 0) {
+ drm_dbg_kms(dev,
+ "buffer size is smaller than hdr metadata infoframe\n");
+ return -ENOSPC;
+ }
+
+ if (len != infoframe_size) {
+ drm_dbg_kms(dev, "wrong static hdr metadata size\n");
+ return -ENOSPC;
+ }
+
+ /*
+ * Set up the infoframe sdp packet for HDR static metadata.
+ * Prepare VSC Header for SU as per DP 1.4a spec,
+ * Table 2-100 and Table 2-101
+ */
+
+ /* Secondary-Data Packet ID, 00h for non-Audio INFOFRAME */
+ sdp->sdp_header.HB0 = 0;
+ /*
+ * Packet Type 80h + Non-audio INFOFRAME Type value
+ * HDMI_INFOFRAME_TYPE_DRM: 0x87
+ * - 80h + Non-audio INFOFRAME Type value
+ * - InfoFrame Type: 0x07
+ * [CTA-861-G Table-42 Dynamic Range and Mastering InfoFrame]
+ */
+ sdp->sdp_header.HB1 = drm_infoframe->type;
+ /*
+ * Least Significant Eight Bits of (Data Byte Count – 1)
+ * infoframe_size - 1
+ */
+ sdp->sdp_header.HB2 = 0x1D;
+ /* INFOFRAME SDP Version Number */
+ sdp->sdp_header.HB3 = (0x13 << 2);
+ /* CTA Header Byte 2 (INFOFRAME Version Number) */
+ sdp->db[0] = drm_infoframe->version;
+ /* CTA Header Byte 3 (Length of INFOFRAME): HDMI_DRM_INFOFRAME_SIZE */
+ sdp->db[1] = drm_infoframe->length;
+ /*
+ * Copy HDMI_DRM_INFOFRAME_SIZE size from a buffer after
+ * HDMI_INFOFRAME_HEADER_SIZE
+ */
+ BUILD_BUG_ON(sizeof(sdp->db) < HDMI_DRM_INFOFRAME_SIZE + 2);
+ memcpy(&sdp->db[2], &buf[HDMI_INFOFRAME_HEADER_SIZE],
+ HDMI_DRM_INFOFRAME_SIZE);
+
+ /*
+ * Size of DP infoframe sdp packet for HDR static metadata consists of
+ * - DP SDP Header(struct dp_sdp_header): 4 bytes
+ * - Two Data Blocks: 2 bytes
+ * CTA Header Byte2 (INFOFRAME Version Number)
+ * CTA Header Byte3 (Length of INFOFRAME)
+ * - HDMI_DRM_INFOFRAME_SIZE: 26 bytes
+ */
+ return sizeof(struct dp_sdp_header) + 2 + HDMI_DRM_INFOFRAME_SIZE;
+}
+EXPORT_SYMBOL(drm_dp_hdr_metadata_infoframe_sdp_pack);
+
/**
* drm_dp_get_pcon_max_frl_bw() - maximum frl supported by PCON
* @dpcd: DisplayPort configuration data
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 6e3fa6662cbe..093a3b7961f7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5157,84 +5157,6 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,
return length;
}
-static ssize_t
-intel_dp_hdr_metadata_infoframe_sdp_pack(struct intel_display *display,
- const struct hdmi_drm_infoframe *drm_infoframe,
- struct dp_sdp *sdp,
- size_t size)
-{
- size_t length = sizeof(struct dp_sdp);
- const int infoframe_size = HDMI_INFOFRAME_HEADER_SIZE + HDMI_DRM_INFOFRAME_SIZE;
- unsigned char buf[HDMI_INFOFRAME_HEADER_SIZE + HDMI_DRM_INFOFRAME_SIZE];
- ssize_t len;
-
- if (size < length)
- return -ENOSPC;
-
- memset(sdp, 0, size);
-
- len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf));
- if (len < 0) {
- drm_dbg_kms(display->drm,
- "buffer size is smaller than hdr metadata infoframe\n");
- return -ENOSPC;
- }
-
- if (len != infoframe_size) {
- drm_dbg_kms(display->drm, "wrong static hdr metadata size\n");
- return -ENOSPC;
- }
-
- /*
- * Set up the infoframe sdp packet for HDR static metadata.
- * Prepare VSC Header for SU as per DP 1.4a spec,
- * Table 2-100 and Table 2-101
- */
-
- /* Secondary-Data Packet ID, 00h for non-Audio INFOFRAME */
- sdp->sdp_header.HB0 = 0;
- /*
- * Packet Type 80h + Non-audio INFOFRAME Type value
- * HDMI_INFOFRAME_TYPE_DRM: 0x87
- * - 80h + Non-audio INFOFRAME Type value
- * - InfoFrame Type: 0x07
- * [CTA-861-G Table-42 Dynamic Range and Mastering InfoFrame]
- */
- sdp->sdp_header.HB1 = drm_infoframe->type;
- /*
- * Least Significant Eight Bits of (Data Byte Count – 1)
- * infoframe_size - 1
- */
- sdp->sdp_header.HB2 = 0x1D;
- /* INFOFRAME SDP Version Number */
- sdp->sdp_header.HB3 = (0x13 << 2);
- /* CTA Header Byte 2 (INFOFRAME Version Number) */
- sdp->db[0] = drm_infoframe->version;
- /* CTA Header Byte 3 (Length of INFOFRAME): HDMI_DRM_INFOFRAME_SIZE */
- sdp->db[1] = drm_infoframe->length;
- /*
- * Copy HDMI_DRM_INFOFRAME_SIZE size from a buffer after
- * HDMI_INFOFRAME_HEADER_SIZE
- */
- BUILD_BUG_ON(sizeof(sdp->db) < HDMI_DRM_INFOFRAME_SIZE + 2);
- memcpy(&sdp->db[2], &buf[HDMI_INFOFRAME_HEADER_SIZE],
- HDMI_DRM_INFOFRAME_SIZE);
-
- /*
- * Size of DP infoframe sdp packet for HDR static metadata consists of
- * - DP SDP Header(struct dp_sdp_header): 4 bytes
- * - Two Data Blocks: 2 bytes
- * CTA Header Byte2 (INFOFRAME Version Number)
- * CTA Header Byte3 (Length of INFOFRAME)
- * - HDMI_DRM_INFOFRAME_SIZE: 26 bytes
- *
- * Prior to GEN11's GMP register size is identical to DP HDR static metadata
- * infoframe size. But GEN11+ has larger than that size, write_infoframe
- * will pad rest of the size.
- */
- return sizeof(struct dp_sdp_header) + 2 + HDMI_DRM_INFOFRAME_SIZE;
-}
-
static void intel_write_dp_sdp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
unsigned int type)
@@ -5253,9 +5175,9 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder,
len = drm_dp_vsc_sdp_pack(&crtc_state->infoframes.vsc, &sdp);
break;
case HDMI_PACKET_TYPE_GAMUT_METADATA:
- len = intel_dp_hdr_metadata_infoframe_sdp_pack(display,
- &crtc_state->infoframes.drm.drm,
- &sdp, sizeof(sdp));
+ len = drm_dp_hdr_metadata_infoframe_sdp_pack(display->drm,
+ &crtc_state->infoframes.drm.drm,
+ &sdp, sizeof(sdp));
break;
case DP_SDP_ADAPTIVE_SYNC:
len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index ab16c1be3900..c158628f0d38 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -32,6 +32,7 @@
struct drm_device;
struct drm_dp_aux;
struct drm_panel;
+struct hdmi_drm_infoframe;
bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count);
@@ -1029,6 +1030,9 @@ int drm_dp_bw_channel_coding_efficiency(bool is_uhbr);
int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes);
ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, struct dp_sdp *sdp);
+ssize_t drm_dp_hdr_metadata_infoframe_sdp_pack(struct drm_device *dev,
+ const struct hdmi_drm_infoframe *drm_infoframe,
+ struct dp_sdp *sdp, size_t size);
int drm_dp_link_symbol_cycles(int lane_count, int pixels, int dsc_slice_count,
int bpp_x16, int symbol_size, bool is_mst);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/5] drm/display: bridge-connector: Preserve max bpc across connector reset
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 ` Igor Paunovic
2026-08-08 9:57 ` [PATCH 3/5] drm/rockchip: dw_dp: Attach "max bpc" connector property Igor Paunovic
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Igor Paunovic @ 2026-08-08 9:57 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, linux-rockchip, linux-arm-kernel,
linux-kernel, Sebastian Reichel, Cristian Ciocaltea,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Dmitry Baryshkov, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Ville Syrjälä, Imre Deak,
Ankit Nautiyal, Igor Paunovic
drm_connector_attach_max_bpc_property() initializes max_requested_bpc
and max_bpc in the connector state, but nothing restores them when the
connector state is later thrown away and re-created:
drm_bridge_connector_create_state() returns a zeroed state for
non-HDMI bridge connectors, and drm_mode_config_reset() installs such
a fresh state on every connector that implements
&drm_connector_funcs.atomic_create_state instead of a .reset hook.
This matters because drivers can attach the property before
drm_mode_config_reset() runs. Rockchip, for example, binds its
component drivers (which create connectors and attach properties)
before calling drm_mode_config_reset(). After that reset,
max_requested_bpc is 0, so drm_atomic_connector_check() computes
max_bpc = min(info->bpc ?: 8, 0) = 0. Any driver that filters output
formats on conn_state->max_bpc then rejects every format, and clients
that never set the "max bpc" property - fbcon in particular - end up
with a black screen. meson already attaches the property on a
drm_bridge_connector before drm_mode_config_reset() and so already
boots with max_requested_bpc = 0 today. dw-hdmi's format negotiation
does consume the value there, but meson attaches the property with a
maximum of 8 and the 8-bit fallback formats are not gated on it, so
negotiation yields the same result for 0 and 8 - the change is a
no-op for meson.
HDMI bridge connectors are immune: drm_bridge_connector_create_state()
calls __drm_atomic_helper_connector_hdmi_state_init(), which
initializes both fields from connector->max_bpc. amdgpu likewise
re-initializes max_requested_bpc in its own .reset implementation.
Non-HDMI bridge connectors have no equivalent.
Mirror the HDMI helper on the non-HDMI path: record the upper attach
limit in connector->max_bpc (drmm_connector_hdmi_init() already stores
the same value there) and restore max_requested_bpc and max_bpc from
it in drm_bridge_connector_create_state() whenever the "max bpc"
property is attached. Connectors without the property behave exactly
as before.
Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
---
drivers/gpu/drm/display/drm_bridge_connector.c | 6 +++++-
drivers/gpu/drm/drm_connector.c | 5 +++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 632cc3ae3b54..d33c4fc42fbf 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -282,9 +282,13 @@ drm_bridge_connector_create_state(struct drm_connector *connector)
if (IS_ERR(conn_state))
return conn_state;
- if (bridge_connector->bridge_hdmi)
+ if (bridge_connector->bridge_hdmi) {
__drm_atomic_helper_connector_hdmi_state_init(connector,
conn_state);
+ } else if (connector->max_bpc_property) {
+ conn_state->max_requested_bpc = connector->max_bpc;
+ conn_state->max_bpc = connector->max_bpc;
+ }
return conn_state;
}
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8b4baed060f3..0400a6a92e2b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2866,6 +2866,10 @@ EXPORT_SYMBOL(drm_connector_set_link_status_property);
* @max: The maximum bit depth supported by the connector.
*
* This is used to add support for limiting the bit depth on a connector.
+ * @max is also recorded in &drm_connector.max_bpc, so that
+ * &drm_connector_funcs.atomic_create_state and &drm_connector_funcs.reset
+ * implementations can restore the property default when re-creating the
+ * connector state.
*
* Returns:
* Zero on success, negative errno on failure.
@@ -2888,6 +2892,7 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
drm_object_attach_property(&connector->base, prop, max);
connector->state->max_requested_bpc = max;
connector->state->max_bpc = max;
+ connector->max_bpc = max;
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/5] drm/rockchip: dw_dp: Attach "max bpc" connector property
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 ` 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 ` [PATCH 5/5] drm/bridge: synopsys: dw-dp: Add BT.2020 colorimetry support Igor Paunovic
4 siblings, 0 replies; 6+ messages in thread
From: Igor Paunovic @ 2026-08-08 9:57 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, linux-rockchip, linux-arm-kernel,
linux-kernel, Sebastian Reichel, Cristian Ciocaltea,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Dmitry Baryshkov, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Ville Syrjälä, Imre Deak,
Ankit Nautiyal, Igor Paunovic
The dw-dp bridge already filters candidate output formats on
conn_state->max_bpc in dw_dp_bridge_atomic_get_output_bus_fmts() and
validates the result against the link bandwidth, but the connector
never exposes the "max bpc" property, so userspace cannot limit the
bit depth. Attach the property with a range of 6 to 10, matching
dw_dp_output_formats[]: the smallest entry is 6 bpc RGB and the
deepest entries are 10 bpc.
drm_connector_attach_max_bpc_property() initializes
connector->state->max_requested_bpc and therefore requires the
connector to have a state. Rockchip binds its components before
drm_mode_config_reset() runs, so the freshly created bridge connector
does not have one yet - create the connector state before attaching
the property, exactly like drmm_connector_hdmi_init() does for HDMI
bridge connectors. The later drm_mode_config_reset() then re-creates
the connector state, and the preceding patch makes
drm_bridge_connector_create_state() restore max_requested_bpc from
connector->max_bpc, so clients that never set the property (fbcon in
particular) keep the full range instead of ending up with 0.
With the property attached, compositors such as KWin write "max bpc"
on every atomic modeset; any in-range value is handled by the existing
format filter and bandwidth checks.
Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
---
drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 26 +++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
index 770ab042a187..4dc29963b5d8 100644
--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
@@ -172,6 +172,32 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *
"Failed to init bridge connector\n");
}
+ /*
+ * The components are bound before drm_mode_config_reset() runs, so
+ * the connector has no state yet, but
+ * drm_connector_attach_max_bpc_property() requires one. Create the
+ * connector state first, like drmm_connector_hdmi_init() does.
+ */
+ if (connector->funcs->atomic_create_state) {
+ struct drm_connector_state *state;
+
+ state = connector->funcs->atomic_create_state(connector);
+ if (IS_ERR(state)) {
+ dw_dp_unbind(dp->base);
+ return PTR_ERR(state);
+ }
+
+ connector->state = state;
+ } else if (connector->funcs->reset) {
+ connector->funcs->reset(connector);
+ }
+
+ ret = drm_connector_attach_max_bpc_property(connector, 6, 10);
+ if (ret) {
+ dw_dp_unbind(dp->base);
+ return ret;
+ }
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/5] drm/bridge: synopsys: dw-dp: Add HDR static metadata support
2026-08-08 9:57 [PATCH 0/5] drm/bridge: synopsys: dw-dp: Add HDR support Igor Paunovic
` (2 preceding siblings ...)
2026-08-08 9:57 ` [PATCH 3/5] drm/rockchip: dw_dp: Attach "max bpc" connector property Igor Paunovic
@ 2026-08-08 9:57 ` Igor Paunovic
2026-08-08 9:57 ` [PATCH 5/5] drm/bridge: synopsys: dw-dp: Add BT.2020 colorimetry support Igor Paunovic
4 siblings, 0 replies; 6+ messages in thread
From: Igor Paunovic @ 2026-08-08 9:57 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, linux-rockchip, linux-arm-kernel,
linux-kernel, Sebastian Reichel, Cristian Ciocaltea,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Dmitry Baryshkov, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Ville Syrjälä, Imre Deak,
Ankit Nautiyal, Igor Paunovic
Send an HDR Metadata InfoFrame SDP (DP 1.4a, Table 2-100 and
Table 2-101) when the connector state carries HDR output metadata, and
attach the HDR_OUTPUT_METADATA property in the Rockchip glue so
userspace can set it.
The infoframe is built with drm_hdmi_infoframe_set_hdr_metadata() and
packed with drm_dp_hdr_metadata_infoframe_sdp_pack(), then written
into a free slot of the SDP register bank with vertical interval
transmission, so the controller resends it once per frame during the
vertical blanking period. The SDP is sent at the end of
dw_dp_video_enable(), next to the existing VSC SDP; the connector
state is passed down from atomic_enable(), which already looks it up.
The allocated slot is tracked in hdr_sdp_nr and released in
atomic_disable(), following the VSC SDP pattern exactly:
atomic_disable() only clears tracked slots, so an untracked slot would
leak on every enable/disable cycle until dw_dp_send_sdp() runs out of
free slots and fails with -EBUSY for every SDP, including VSC and
audio.
A metadata change on a live stream (HDR on/off toggle, different
mastering display data) forces a full modeset: atomic_check() compares
the old and new connector state with
drm_connector_atomic_hdr_metadata_equal() and sets
crtc_state->mode_changed, the same approach as dw-hdmi. The resulting
disable/enable cycle then drops or (re)sends the SDP.
Commits without HDR metadata are unaffected: with a NULL metadata blob
in both old and new connector state,
drm_connector_atomic_hdr_metadata_equal() treats them as equal, no
modeset is forced, and dw_dp_video_enable() skips the SDP. This keeps
plain SDR commits a no-op even for compositors that write a NULL blob
on every atomic modeset once the property exists (KWin does).
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 | 2 ++
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index df149c52fce0..ca997ea53e66 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -24,6 +24,7 @@
#include <drm/drm_bridge_connector.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_hdmi_audio_helper.h>
+#include <drm/display/drm_hdmi_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>
@@ -369,6 +370,7 @@ struct dw_dp {
struct drm_bridge *next_bridge;
int vsc_sdp_nr;
+ int hdr_sdp_nr;
DECLARE_BITMAP(sdp_reg_bank, SDP_REG_BANK_SIZE);
};
@@ -1171,6 +1173,28 @@ static int dw_dp_send_vsc_sdp(struct dw_dp *dp)
return dw_dp_send_sdp(dp, &sdp);
}
+static int dw_dp_send_hdr_metadata_sdp(struct dw_dp *dp,
+ const struct drm_connector_state *conn_state)
+{
+ struct hdmi_drm_infoframe frame;
+ struct dw_dp_sdp sdp = {};
+ ssize_t len;
+ int ret;
+
+ ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, conn_state);
+ if (ret)
+ return ret;
+
+ len = drm_dp_hdr_metadata_infoframe_sdp_pack(dp->bridge.dev, &frame,
+ &sdp.base, sizeof(sdp.base));
+ if (len < 0)
+ return len;
+
+ sdp.flags = DW_DP_SDP_VERTICAL_INTERVAL;
+
+ return dw_dp_send_sdp(dp, &sdp);
+}
+
static int dw_dp_video_set_pixel_mode(struct dw_dp *dp)
{
switch (dp->pixel_mode) {
@@ -1265,7 +1289,8 @@ static void dw_dp_video_disable(struct dw_dp *dp)
FIELD_PREP(VIDEO_STREAM_ENABLE, 0));
}
-static int dw_dp_video_enable(struct dw_dp *dp)
+static int dw_dp_video_enable(struct dw_dp *dp,
+ const struct drm_connector_state *conn_state)
{
struct dw_dp_link *link = &dp->link;
struct dw_dp_bridge_state *state;
@@ -1440,6 +1465,9 @@ static int dw_dp_video_enable(struct dw_dp *dp)
if (dw_dp_video_need_vsc_sdp(dp))
dp->vsc_sdp_nr = dw_dp_send_vsc_sdp(dp);
+ if (conn_state->hdr_output_metadata)
+ dp->hdr_sdp_nr = dw_dp_send_hdr_metadata_sdp(dp, conn_state);
+
return 0;
}
@@ -1597,6 +1625,7 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge,
struct dw_dp *dp = bridge_to_dp(bridge);
struct dw_dp_bridge_state *state;
const struct dw_dp_output_format *fmt;
+ struct drm_connector_state *old_conn_state;
struct drm_display_mode *mode;
int min_hbp = 16;
int min_hsync = 9;
@@ -1616,6 +1645,11 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge,
state->bpc = fmt->bpc;
state->bpp = fmt->bpp;
+ 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))
+ crtc_state->mode_changed = true;
+
if ((adjusted_mode->hsync_start - adjusted_mode->hdisplay) & 0x1) {
adjusted_mode->hsync_start += 1;
dev_warn(dp->dev, "hfp is not 2 pixeel aligned, fixup to aligned hfp\n");
@@ -2016,7 +2050,7 @@ static void dw_dp_bridge_atomic_enable(struct drm_bridge *bridge,
return;
}
- ret = dw_dp_video_enable(dp);
+ ret = dw_dp_video_enable(dp, conn_state);
if (ret < 0) {
dev_err(dp->dev, "failed to enable video: %d\n", ret);
return;
@@ -2066,6 +2100,11 @@ static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge,
dp->vsc_sdp_nr = -1;
}
+ if (dp->hdr_sdp_nr >= 0) {
+ dw_dp_clear_sdp(dp, dp->hdr_sdp_nr);
+ dp->hdr_sdp_nr = -1;
+ }
+
dw_dp_reset(dp);
pm_runtime_put_autosuspend(dp->dev);
}
@@ -2668,6 +2707,7 @@ int dw_dp_probe(struct dw_dp *dp)
return ret;
dp->vsc_sdp_nr = -1;
+ dp->hdr_sdp_nr = -1;
dp->audio_interface = DW_DP_AUDIO_UNUSED;
dp->audio_sdp_nr = -1;
diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
index 4dc29963b5d8..c5bc178c0a50 100644
--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
@@ -198,6 +198,8 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *
return ret;
}
+ drm_connector_attach_hdr_output_metadata_property(connector);
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/5] drm/bridge: synopsys: dw-dp: Add BT.2020 colorimetry support
2026-08-08 9:57 [PATCH 0/5] drm/bridge: synopsys: dw-dp: Add HDR support Igor Paunovic
` (3 preceding siblings ...)
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
4 siblings, 0 replies; 6+ messages in thread
From: Igor Paunovic @ 2026-08-08 9:57 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, linux-rockchip, linux-arm-kernel,
linux-kernel, Sebastian Reichel, Cristian Ciocaltea,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Dmitry Baryshkov, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Ville Syrjälä, Imre Deak,
Ankit Nautiyal, Igor Paunovic
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
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-08 9:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 5/5] drm/bridge: synopsys: dw-dp: Add BT.2020 colorimetry support Igor Paunovic
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox