* [PATCH v5 00/17] Add new general DRM property "color format"
@ 2025-11-28 21:05 Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 01/17] drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check Nicolas Frattaroli
` (16 more replies)
0 siblings, 17 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli,
Werner Sembach, Andri Yngvason, Marius Vlad
Hello,
this is a follow-up to
https://lore.kernel.org/all/20250911130739.4936-1-marius.vlad@collabora.com/
which in of itself is a follow-up to
https://lore.kernel.org/dri-devel/20240115160554.720247-1-andri@yngvason.is/ where
a new DRM connector property has been added allowing users to
force a particular color format.
That in turn was actually also a follow-up from Werner Sembach's posted at
https://lore.kernel.org/dri-devel/20210630151018.330354-1-wse@tuxedocomputers.com/
As the number of cooks have reached critical mass, I'm hoping I'll be
the last person to touch this particular series.
We have an implementation in Weston at
https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1825 that
adds support for this property. This patch series has been tested
against that MR on i915 (HDMI, DP), amdgpu (HDMI, DP) and on rockchip
(HDMI).
You can also manually test this with modetest like so, but beware that
this is a non-atomic invocation, so testing YUV420 like this will result
in weird outcomes if only some of the modes support YUV420:
$ modetest -s 115:1920x1080-60@NV12 -w 115:'color format':4
where 115 is the connector ID and '4' is the enum value for a particular
color format.
General notes on the approach taken by me: instead of silently switching
to a different format than was explicitly requested, or even worse,
outputting something to the sink the sink doesn't support, bubble up an
error to userspace instead. "color format" is a "I want this" type
property, not a "force this" type property, i.e. the kernel will respect
the limits imposed by the hardware.
I'm not sure if my drm_bridge change actually achieves what I want in a
more complex bridge setup. I'd need to either come up with a virtual
bridge to test these scenarios, or spend some time making a flat flex
cable adapter for the DSI-HDMI bridge board I have here. Before I invest
too much time into either of those, I'd like to get some feedback on
this approach however.
Things I've tested:
- HDMI (YCbCr 4:4:4 + YCbCr 4:2:2 (8-bit) + RGB + Auto) on RK3588
- HDMI (YCbCr 4:4:4 + YCbCr 4:2:2 (8-bit) + RGB + Auto) on RK3576
- HDMI + DP (YCbCr 4:4:4, YCbCr 4:2:0, RGB, Auto) on Intel N97 (i915)
DP-MST is untested, but I expect it to work the same.
- HDMI (YCbCr 4:4:4, YCbCr 4:2:2, YCbCr 4:2:0, RGB, Auto) + DP (YCbCr
4:4:4, RGB, Auto) on an AMD Radeon RX 550 (amdgpu). DP-MST is
untested.
Changes in v5:
- Rebase onto drm-tip
- Drop DRM_MODE_COLOR_FORMAT_* as an enum
- Unify DRM_COLOR_FORMAT_NONE and DRM_COLOR_FORMAT_AUTO, with AUTO being
0. This makes conversion and general logic much easier.
- Note: this means the weston side of this work has a small change as
well.
- Adjust the drm_color_format enum to not needlessly renumber the
existing defines, as it doesn't need to correspond to how HDMI numbers
them.
- Make the DRM-to-HDMI conversion function static inline __pure, because
the assembly it generates is tiny, and the function is pure.
- Don't accept nothing as the list of supported color formats for
registration of the property.
- Drop the per-connector variants of the color format registration
function, as it's not needed.
- drm_hdmi_state_helper: Fix mode_valid rejecting 420-only modes.
- drm_hdmi_state_helper: Only fall back to YUV420 with
DRM_COLOR_FORMAT_AUTO.
- drm_hdmi_state_helper: Remove redundant AUTO->RGB condition, as the
conversion already does this.
- Add KUnit tests for hdmi_compute_config.
- drm/bridge: Refactor bus_format_is_color_fmt and add a few more YUV422
formats.
- Register the color format property in drmm_connector_hdmi_init based
on the supported HDMI formats passed to it. This means rockchip
dw_hdmi_qp no longer needs to register it.
- amdgpu: Simplify YUV420 logic
- amdgpu: Don't try to pick YUV444 on YUV420-only modes
- i915: Try to make behaviour more or less the same as that of the drm
hdmi state helper.
- rockchip dw_hdmi_qp: Set supported HDMI formats
- rockchip dw_hdmi_qp: Set the right VO GRF values depending on color
format.
- rockchip dw_hdmi_qp: Act on the color format property in this driver,
rather than in VOP2, by setting the bus_format appropriately.
- rockchip VOP2: Can the BCSH-based implementation. BCSH isn't available
on all video ports of the hardware, and the code was extremely
suspect. Instead, plug into the existing YUV-to-RGB/RGB-to-YUV code,
which can be done now that the HDMI driver sets the bus format.
- A whole bunch of Rockchip VOP2 fixes.
- Link to v4: https://lore.kernel.org/r/20251117-color-format-v4-0-0ded72bd1b00@collabora.com
Changes in v4:
- Rebase onto next-20251117
- Get rid of HDMI_COLORSPACE_AUTO
- Split hdmi_compute_config change into separate patch
- Add missing symbol export for color_format_to_hdmi_colorspace to fix
builds in certain configurations
- Drop "drm: Pass supported color formats straight onto drm_bridge"
- Make dw-hdmi-qp set the platform data's supported color formats as
the bridge's supported HDMI color formats
- drm_hdmi_state_helper: pass requested color format to
hdmi_compute_format_bpc if set.
- drm_bridge: limit the bus formats to those explicitly requested with
the color format property during the atomic bridge check call,
specifically in drm_atomic_bridge_chain_select_bus_fmts.
- i915: Remove INTEL_OUTPUT_FORMAT_AUTO, as automatic format selection
does not need to involve the hardware state
- i915: Deduplicate ntel_output_format_to_drm_color_format code by
moving it as a static inline __pure function into a shared header
- i915: rework logic in HDMI, DP and DP-MST output config functions to
remove redundant locals, simplify execution flow, and return an error
to userspace if an explicit color_format request can't be satisfied.
- i915: assign myself as the author and make the others Co-developers,
so that they don't get the blame for any of my bugs.
- amdgpu: refactor fill_stream_properties_from_drm_display_mode to
improve readability and ensure that impossible color format requests
get bubbled up to userspace as errors
- amdgpu: don't pick YUV444 over RGB.
- amdgpu: assign authorship to myself, with others as Co-developers, as
logic was modified and the blame should fall on me
- dw_hdmi_qp-rockchip: set the supported color formats platform data
member
- rockchip: remove drm property registration for rk3066_hdmi and
inno_hdmi. None of the platforms that use these use vop2 as the
video output processor.
- Link to v3: https://lore.kernel.org/all/20250911130739.4936-1-marius.vlad@collabora.com/
Changes in v3 by mvlad compared to Andri's v2 series:
- renamed the property to just 'color format'
- the property is added dynamically similar to the Colorspace property
- a key point from previous comments was that drivers should advertise
the color formats they support and userspace would query EDID and
perform an intersection from those color formats which users can
further use. With this patch set each driver that adds this property
has such list of hard-coded color formats, but fundamentally the idea
is that driver can query the HW and do that on its own. The
infrastructure is now in place to allow to do that
- by default the 'AUTO' color format is set. With this patch series that
has been introduced as a fallback to RGB. Drivers could further
customize this behavour and could perform additional checks on the sink
to pick another suitable color format they'd like for AUTO
- drm_bridge bridge code has been improved to allow initialization with
the same color formats list as the DRM connector property. Similarly, bpc
pick-up now takes the color format into consideration when deciding
which bpc to choose from
- The new DRM color format re-uses HDMI_COLORPSACE enum and provides an
enum translations between the two to avoid touching all other drivers that
use HDMI_COLORPSACE enum. I believe at this point that this allows the
least amount of disruption and avoids a massive bike shedding around
that part
- a rockchip implementation has been by my colleague Derek Foreman
- YUV444 color format has been added in i915
- address comment about "Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A
check" where aconnector might be invalid
- Link to v2: https://lore.kernel.org/dri-devel/20240115160554.720247-1-andri@yngvason.is/
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
Andri Yngvason (1):
drm: Add new general DRM property "color format"
Marius Vlad (1):
drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE
Nicolas Frattaroli (14):
drm/bridge: Act on the DRM color format property
drm/display: hdmi-state-helper: Act on color format DRM property
drm/display: hdmi-state-helper: Try subsampling in mode_valid
drm/i915: Implement the "color format" DRM property
drm/amdgpu: Implement "color format" DRM property
drm/rockchip: Add YUV422 output mode constants for VOP2
drm/rockchip: vop2: Fix YUV444 output
drm/rockchip: vop2: Add RK3576 to the RG swap special case
drm/rockchip: vop2: Recognise 10/12-bit YUV422 as YUV formats
drm/rockchip: vop2: Set correct output format for RK3576 YUV422
drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property
drm/rockchip: dw_hdmi_qp: Set supported_formats platdata
drm/connector: Register color format property on HDMI connectors
drm/tests: hdmi: Add tests for the color_format property
Werner Sembach (1):
drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 87 ++++++++++--
.../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 13 ++
drivers/gpu/drm/display/drm_hdmi_state_helper.c | 27 +++-
drivers/gpu/drm/drm_atomic_helper.c | 5 +
drivers/gpu/drm/drm_atomic_uapi.c | 11 ++
drivers/gpu/drm/drm_bridge.c | 45 ++++++
drivers/gpu/drm/drm_connector.c | 156 +++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_connector.c | 11 ++
drivers/gpu/drm/i915/display/intel_connector.h | 1 +
drivers/gpu/drm/i915/display/intel_display_types.h | 15 ++
drivers/gpu/drm/i915/display/intel_dp.c | 55 ++++++--
drivers/gpu/drm/i915/display/intel_dp.h | 4 +
drivers/gpu/drm/i915/display/intel_dp_mst.c | 36 ++++-
drivers/gpu/drm/i915/display/intel_hdmi.c | 53 +++++--
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 65 ++++++++-
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 5 +
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 40 +++++-
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 ++++++++++++++
include/drm/display/drm_hdmi_state_helper.h | 4 +
include/drm/drm_connector.h | 62 +++++++-
20 files changed, 752 insertions(+), 52 deletions(-)
---
base-commit: 7fe1b006b65af67bc0ef5df53aedcd265be7fb19
change-id: 20251028-color-format-49fd202b7183
Best regards,
--
Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v5 01/17] drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 02/17] drm: Add new general DRM property "color format" Nicolas Frattaroli
` (15 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli,
Werner Sembach, Andri Yngvason
From: Werner Sembach <wse@tuxedocomputers.com>
Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check that was performed in the
drm_mode_is_420_only() case, but not in the drm_mode_is_420_also() &&
force_yuv420_output case.
Without further knowledge if YCbCr 4:2:0 is supported outside of HDMI,
there is no reason to use RGB when the display
reports drm_mode_is_420_only() even on a non HDMI connection.
This patch also moves both checks in the same if-case. This eliminates an
extra else-if-case.
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Signed-off-by: Andri Yngvason <andri@yngvason.is>
Tested-by: Andri Yngvason <andri@yngvason.is>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f02bcd108685..0b44bfe9e7e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6668,12 +6668,8 @@ static void fill_stream_properties_from_drm_display_mode(
timing_out->v_border_top = 0;
timing_out->v_border_bottom = 0;
/* TODO: un-hardcode */
- if (drm_mode_is_420_only(info, mode_in)
- && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
- timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
- else if (drm_mode_is_420_also(info, mode_in)
- && aconnector
- && aconnector->force_yuv420_output)
+ if (drm_mode_is_420_only(info, mode_in) || (drm_mode_is_420_also(info, mode_in) &&
+ aconnector && aconnector->force_yuv420_output))
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR422)
&& aconnector
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 02/17] drm: Add new general DRM property "color format"
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 01/17] drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-12-09 14:11 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 03/17] drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE Nicolas Frattaroli
` (14 subsequent siblings)
16 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli,
Andri Yngvason, Werner Sembach, Marius Vlad
From: Andri Yngvason <andri@yngvason.is>
Add a new general DRM property named "color format" which can be used by
userspace to request the display driver to output a particular color
format.
Possible options are:
- auto (setup by default, driver internally picks the color format)
- rgb
- ycbcr444
- ycbcr422
- ycbcr420
Drivers should advertise from this list which formats they support.
Together with this list and EDID data from the sink we should be able
to relay a list of usable color formats to users to pick from.
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Signed-off-by: Andri Yngvason <andri@yngvason.is>
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/drm_atomic_helper.c | 5 ++
drivers/gpu/drm/drm_atomic_uapi.c | 11 +++
drivers/gpu/drm/drm_connector.c | 143 ++++++++++++++++++++++++++++++++++++
include/drm/drm_connector.h | 35 +++++++--
4 files changed, 189 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 10adac9397cf..ca2daa4c84de 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -736,6 +736,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
if (old_connector_state->max_requested_bpc !=
new_connector_state->max_requested_bpc)
new_crtc_state->connectors_changed = true;
+
+ if (old_connector_state->color_format !=
+ new_connector_state->color_format)
+ new_crtc_state->connectors_changed = true;
+
}
if (funcs->atomic_check)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 7320db4b8489..ecf30e23a736 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -915,6 +915,15 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
state->privacy_screen_sw_state = val;
} else if (property == connector->broadcast_rgb_property) {
state->hdmi.broadcast_rgb = val;
+ } else if (property == connector->color_format_property) {
+ if (val >= DRM_COLOR_FORMAT_COUNT) {
+ drm_dbg_atomic(connector->dev,
+ "[CONNECTOR:%d:%s] unknown color format %llu\n",
+ connector->base.id, connector->name, val);
+ return -EINVAL;
+ }
+
+ state->color_format = val ? BIT(val - 1) : DRM_COLOR_FORMAT_AUTO;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -1000,6 +1009,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
*val = state->privacy_screen_sw_state;
} else if (property == connector->broadcast_rgb_property) {
*val = state->hdmi.broadcast_rgb;
+ } else if (property == connector->color_format_property) {
+ *val = ffs(state->color_format);
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 4d6dc9ebfdb5..13151d9bfb82 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1348,6 +1348,32 @@ static const char * const colorspace_names[] = {
[DRM_MODE_COLORIMETRY_BT601_YCC] = "BT601_YCC",
};
+/**
+ * drm_get_color_format_name - return a string for color format
+ * @color_fmt: color format to return the name of
+ *
+ * Returns a string constant matching the format's name, or NULL if no match
+ * is found.
+ */
+const char *drm_get_color_format_name(enum drm_color_format color_fmt)
+{
+ switch (color_fmt) {
+ case DRM_COLOR_FORMAT_AUTO:
+ return "AUTO";
+ case DRM_COLOR_FORMAT_RGB444:
+ return "RGB";
+ case DRM_COLOR_FORMAT_YCBCR444:
+ return "YUV 4:4:4";
+ case DRM_COLOR_FORMAT_YCBCR422:
+ return "YUV 4:2:2";
+ case DRM_COLOR_FORMAT_YCBCR420:
+ return "YUV 4:2:0";
+ default:
+ return NULL;
+ }
+}
+EXPORT_SYMBOL(drm_get_color_format_name);
+
/**
* drm_get_colorspace_name - return a string for color encoding
* @colorspace: color space to compute name of
@@ -1377,6 +1403,20 @@ static const u32 hdmi_colorspaces =
BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) |
BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER);
+/* already bit-shifted */
+static const u32 hdmi_colorformats =
+ DRM_COLOR_FORMAT_RGB444 |
+ DRM_COLOR_FORMAT_YCBCR444 |
+ DRM_COLOR_FORMAT_YCBCR422 |
+ DRM_COLOR_FORMAT_YCBCR420;
+
+/* already bit-shifted */
+static const u32 dp_colorformats =
+ DRM_COLOR_FORMAT_RGB444 |
+ DRM_COLOR_FORMAT_YCBCR444 |
+ DRM_COLOR_FORMAT_YCBCR422 |
+ DRM_COLOR_FORMAT_YCBCR420;
+
/*
* As per DP 1.4a spec, 2.2.5.7.5 VSC SDP Payload for Pixel Encoding/Colorimetry
* Format Table 2-120
@@ -2628,6 +2668,89 @@ int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property);
+/**
+ * drm_mode_create_color_format_property - create color format property
+ * @connector: connector to create the color format property on
+ * @supported_color_formats: bitmask of &enum drm_color_format values the
+ * connector supports
+ *
+ * Called by a driver to create a color format property. Must be attached to
+ * the desired connector afterwards.
+ *
+ * @supported_color_formats should only include color formats the connector
+ * type can actually support.
+ *
+ * Returns:
+ * 0 on success, negative errno on error
+ */
+int drm_mode_create_color_format_property(struct drm_connector *connector,
+ u32 supported_color_formats)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_prop_enum_list enum_list[DRM_COLOR_FORMAT_COUNT];
+ unsigned int len = 1;
+ unsigned int i = 1;
+ u32 fmt;
+
+ if (connector->color_format_property)
+ return 0;
+
+ if (!supported_color_formats) {
+ drm_err(dev, "No supported color formats provided on [CONNECTOR:%d:%s]\n",
+ connector->base.id, connector->name);
+ return -EINVAL;
+ }
+
+ if (supported_color_formats & ~GENMASK_U32(DRM_COLOR_FORMAT_COUNT - 1, 0)) {
+ drm_err(dev, "Unknown color formats provided on [CONNECTOR:%d:%s]\n",
+ connector->base.id, connector->name);
+ return -EINVAL;
+ }
+
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ if (supported_color_formats & ~hdmi_colorformats) {
+ drm_err(dev, "Color formats not allowed for HDMI on [CONNECTOR:%d:%s]\n",
+ connector->base.id, connector->name);
+ return -EINVAL;
+ }
+ break;
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ case DRM_MODE_CONNECTOR_eDP:
+ if (supported_color_formats & ~dp_colorformats) {
+ drm_err(dev, "Color formats not allowed for DP on [CONNECTOR:%d:%s]\n",
+ connector->base.id, connector->name);
+ return -EINVAL;
+ }
+ break;
+ }
+
+ enum_list[0].name = drm_get_color_format_name(DRM_COLOR_FORMAT_AUTO);
+ enum_list[0].type = 0;
+
+ while (supported_color_formats) {
+ fmt = BIT(i - 1);
+ if (supported_color_formats & fmt) {
+ supported_color_formats ^= fmt;
+ enum_list[len].name = drm_get_color_format_name(fmt);
+ enum_list[len].type = i;
+ len++;
+ }
+ i++;
+ }
+
+ connector->color_format_property =
+ drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "color format",
+ enum_list, len);
+
+ if (!connector->color_format_property)
+ return -ENOMEM;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_color_format_property);
+
/**
* drm_mode_create_dp_colorspace_property - create dp colorspace property
* @connector: connector to create the Colorspace property on.
@@ -2845,6 +2968,26 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
+/**
+ * drm_connector_attach_color_format_property - attach "force color format" property
+ * @connector: connector to attach force color format property on.
+ *
+ * This is used to add support for selecting a color format on a connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_color_format_property(struct drm_connector *connector)
+{
+ struct drm_property *prop = connector->color_format_property;
+
+ drm_object_attach_property(&connector->base, prop, DRM_COLOR_FORMAT_AUTO);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_color_format_property);
+
+
/**
* drm_connector_attach_hdr_output_metadata_property - attach "HDR_OUTPUT_METADA" property
* @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8f34f4b8183d..38968a557b82 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -556,6 +556,16 @@ enum drm_colorspace {
DRM_MODE_COLORIMETRY_COUNT
};
+enum drm_color_format {
+ DRM_COLOR_FORMAT_AUTO = 0,
+ DRM_COLOR_FORMAT_RGB444 = BIT(0),
+ DRM_COLOR_FORMAT_YCBCR444 = BIT(1),
+ DRM_COLOR_FORMAT_YCBCR422 = BIT(2),
+ DRM_COLOR_FORMAT_YCBCR420 = BIT(3),
+};
+
+#define DRM_COLOR_FORMAT_COUNT 5
+
/**
* enum drm_bus_flags - bus_flags info for &drm_display_info
*
@@ -699,11 +709,6 @@ struct drm_display_info {
*/
enum subpixel_order subpixel_order;
-#define DRM_COLOR_FORMAT_RGB444 (1<<0)
-#define DRM_COLOR_FORMAT_YCBCR444 (1<<1)
-#define DRM_COLOR_FORMAT_YCBCR422 (1<<2)
-#define DRM_COLOR_FORMAT_YCBCR420 (1<<3)
-
/**
* @panel_orientation: Read only connector property for built-in panels,
* indicating the orientation of the panel vs the device's casing.
@@ -1107,6 +1112,13 @@ struct drm_connector_state {
*/
enum drm_colorspace colorspace;
+ /**
+ * @color_format: State variable for Connector property to request
+ * color format change on Sink. This is most commonly used to switch
+ * between RGB to YUV and vice-versa.
+ */
+ enum drm_color_format color_format;
+
/**
* @writeback_job: Writeback job for writeback connectors
*
@@ -2060,6 +2072,12 @@ struct drm_connector {
*/
struct drm_property *colorspace_property;
+ /**
+ * @color_format_property: Connector property to set the suitable
+ * color format supported by the sink.
+ */
+ struct drm_property *color_format_property;
+
/**
* @path_blob_ptr:
*
@@ -2461,6 +2479,9 @@ int drm_mode_create_dp_colorspace_property(struct drm_connector *connector,
int drm_mode_create_content_type_property(struct drm_device *dev);
int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
+int drm_mode_create_color_format_property(struct drm_connector *connector,
+ u32 supported_color_formats);
+
int drm_connector_set_path_property(struct drm_connector *connector,
const char *path);
int drm_connector_set_tile_property(struct drm_connector *connector);
@@ -2542,6 +2563,10 @@ bool drm_connector_has_possible_encoder(struct drm_connector *connector,
struct drm_encoder *encoder);
const char *drm_get_colorspace_name(enum drm_colorspace colorspace);
+int drm_connector_attach_color_format_property(struct drm_connector *connector);
+
+const char *drm_get_color_format_name(enum drm_color_format color_fmt);
+
/**
* drm_for_each_connector_iter - connector_list iterator macro
* @connector: &struct drm_connector pointer used as cursor
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 03/17] drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 01/17] drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 02/17] drm: Add new general DRM property "color format" Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-12-09 14:12 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 04/17] drm/bridge: Act on the DRM color format property Nicolas Frattaroli
` (13 subsequent siblings)
16 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli,
Marius Vlad
From: Marius Vlad <marius.vlad@collabora.com>
While the two enums have similar values, they're not identical, and
HDMI's enum is defined as per the HDMI standard.
Add a simple conversion function. Unexpected inputs aren't handled in
any clever way, DRM_COLOR_FORMAT_AUTO and any other value that doesn't
cleanly map to HDMI just gets returned as HDMI_COLORSPACE_RGB.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
include/drm/drm_connector.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 38968a557b82..cf556f0e5731 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2567,6 +2567,33 @@ int drm_connector_attach_color_format_property(struct drm_connector *connector);
const char *drm_get_color_format_name(enum drm_color_format color_fmt);
+/**
+ * drm_color_format_to_hdmi_colorspace - convert DRM color format to HDMI
+ * @fmt: the &enum drm_color_format to convert
+ *
+ * Convert a given &enum drm_color_format to an equivalent
+ * &enum hdmi_colorspace. For non-representable values and
+ * %DRM_COLOR_FORMAT_AUTO, the value %HDMI_COLORSPACE_RGB is returned.
+ *
+ * Returns: the corresponding &enum hdmi_colorspace value
+ */
+static inline enum hdmi_colorspace __pure
+drm_color_format_to_hdmi_colorspace(enum drm_color_format fmt)
+{
+ switch (fmt) {
+ default:
+ case DRM_COLOR_FORMAT_AUTO:
+ case DRM_COLOR_FORMAT_RGB444:
+ return HDMI_COLORSPACE_RGB;
+ case DRM_COLOR_FORMAT_YCBCR444:
+ return HDMI_COLORSPACE_YUV444;
+ case DRM_COLOR_FORMAT_YCBCR422:
+ return HDMI_COLORSPACE_YUV422;
+ case DRM_COLOR_FORMAT_YCBCR420:
+ return HDMI_COLORSPACE_YUV420;
+ }
+}
+
/**
* drm_for_each_connector_iter - connector_list iterator macro
* @connector: &struct drm_connector pointer used as cursor
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 04/17] drm/bridge: Act on the DRM color format property
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (2 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 03/17] drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-12-09 14:27 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property Nicolas Frattaroli
` (12 subsequent siblings)
16 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
The new DRM color format property allows userspace to request a specific
color format on a connector. In turn, this fills the connector state's
color_format member to switch color formats.
Make drm_bridges consider the color_format set in the connector state
during the atomic bridge check. Specifically, reject any output bus
formats that do not correspond to the requested color format.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/drm_bridge.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 8f355df883d8..8aac9747f35e 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -1052,6 +1052,47 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
return ret;
}
+static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
+{
+ if (fmt == DRM_COLOR_FORMAT_AUTO)
+ return true;
+
+ switch (bus_fmt) {
+ case MEDIA_BUS_FMT_FIXED:
+ return true;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ case MEDIA_BUS_FMT_RGB101010_1X30:
+ case MEDIA_BUS_FMT_RGB121212_1X36:
+ case MEDIA_BUS_FMT_RGB161616_1X48:
+ return fmt == DRM_COLOR_FORMAT_RGB444;
+ case MEDIA_BUS_FMT_YUV8_1X24:
+ case MEDIA_BUS_FMT_YUV10_1X30:
+ case MEDIA_BUS_FMT_YUV12_1X36:
+ case MEDIA_BUS_FMT_YUV16_1X48:
+ return fmt == DRM_COLOR_FORMAT_YCBCR444;
+ case MEDIA_BUS_FMT_UYVY8_1X16:
+ case MEDIA_BUS_FMT_VYUY8_1X16:
+ case MEDIA_BUS_FMT_YUYV8_1X16:
+ case MEDIA_BUS_FMT_YVYU8_1X16:
+ case MEDIA_BUS_FMT_UYVY10_1X20:
+ case MEDIA_BUS_FMT_YUYV10_1X20:
+ case MEDIA_BUS_FMT_VYUY10_1X20:
+ case MEDIA_BUS_FMT_YVYU10_1X20:
+ case MEDIA_BUS_FMT_UYVY12_1X24:
+ case MEDIA_BUS_FMT_VYUY12_1X24:
+ case MEDIA_BUS_FMT_YUYV12_1X24:
+ case MEDIA_BUS_FMT_YVYU12_1X24:
+ return fmt == DRM_COLOR_FORMAT_YCBCR422;
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+ case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+ case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+ return fmt == DRM_COLOR_FORMAT_YCBCR420;
+ default:
+ return false;
+ }
+}
+
/*
* This function is called by &drm_atomic_bridge_chain_check() just before
* calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
@@ -1137,6 +1178,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
}
for (i = 0; i < num_out_bus_fmts; i++) {
+ if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
+ ret = -ENOTSUPP;
+ continue;
+ }
ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
conn_state, out_bus_fmts[i]);
if (ret != -ENOTSUPP)
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (3 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 04/17] drm/bridge: Act on the DRM color format property Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-12-09 14:16 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid Nicolas Frattaroli
` (11 subsequent siblings)
16 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
With the introduction of the "color format" DRM property, which allows
userspace to request a specific color format, the HDMI state helper
should implement this.
Implement it by checking whether the property is set and set to
something other than auto. If so, pass the requested color format, and
otherwise set RGB.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index a561f124be99..5da956bdd68c 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -649,11 +649,21 @@ hdmi_compute_config(const struct drm_connector *connector,
unsigned int max_bpc = clamp_t(unsigned int,
conn_state->max_bpc,
8, connector->max_bpc);
+ enum hdmi_colorspace hdmi_colorspace =
+ drm_color_format_to_hdmi_colorspace(conn_state->color_format);
int ret;
ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
- HDMI_COLORSPACE_RGB);
+ hdmi_colorspace);
if (ret) {
+ /* If a color format was explicitly requested, don't fall back */
+ if (conn_state->color_format) {
+ drm_dbg_kms(connector->dev,
+ "Explicitly set color format '%s' doesn't work.\n",
+ drm_get_color_format_name(conn_state->color_format));
+ return ret;
+ }
+
if (connector->ycbcr_420_allowed) {
ret = hdmi_compute_format_bpc(connector, conn_state,
mode, max_bpc,
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (4 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-12-09 14:18 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 07/17] drm/i915: Implement the "color format" DRM property Nicolas Frattaroli
` (10 subsequent siblings)
16 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
drm_hdmi_connector_mode_valid assumes modes are only valid if they work
with RGB. The reality is more complex however: YCbCr 4:2:0
chroma-subsampled modes only require half the pixel clock that the same
mode would require in RGB.
This leads to drm_hdmi_connector_mode_valid rejecting perfectly valid
420-only modes.
Fix this by checking whether the mode is 420-only first. If so, then
proceed by checking it with HDMI_COLORSPACE_YUV420 so long as the
connector has legalized 420, otherwise error out. If the mode is not
420-only, check with RGB as was previously always the case.
Fixes: 47368ab437fd ("drm/display: hdmi: add generic mode_valid helper")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 5da956bdd68c..1800e00b30c5 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -892,8 +892,18 @@ drm_hdmi_connector_mode_valid(struct drm_connector *connector,
const struct drm_display_mode *mode)
{
unsigned long long clock;
+ enum hdmi_colorspace fmt;
+
+ if (drm_mode_is_420_only(&connector->display_info, mode)) {
+ if (connector->ycbcr_420_allowed)
+ fmt = HDMI_COLORSPACE_YUV420;
+ else
+ return MODE_NO_420;
+ } else {
+ fmt = HDMI_COLORSPACE_RGB;
+ }
- clock = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+ clock = drm_hdmi_compute_mode_clock(mode, 8, fmt);
if (!clock)
return MODE_ERROR;
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 07/17] drm/i915: Implement the "color format" DRM property
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (5 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 08/17] drm/amdgpu: Implement " Nicolas Frattaroli
` (9 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli,
Werner Sembach, Andri Yngvason, Marius Vlad
This includes RGB, YUV420, YUV444 and Auto. Auto will pick RGB, unless
the mode being asked for is YUV420-only, in which case it picks YUV420.
Should the explicitly requested color format not be supported by the
sink, then an error is returned to userspace, so that it can make a
better choice.
Co-developed-by: Werner Sembach <wse@tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Co-developed-by: Andri Yngvason <andri@yngvason.is>
Signed-off-by: Andri Yngvason <andri@yngvason.is>
Co-developed-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/i915/display/intel_connector.c | 11 +++++
drivers/gpu/drm/i915/display/intel_connector.h | 1 +
drivers/gpu/drm/i915/display/intel_display_types.h | 15 ++++++
drivers/gpu/drm/i915/display/intel_dp.c | 55 +++++++++++++++++-----
drivers/gpu/drm/i915/display/intel_dp.h | 4 ++
drivers/gpu/drm/i915/display/intel_dp_mst.c | 36 +++++++++++++-
drivers/gpu/drm/i915/display/intel_hdmi.c | 53 +++++++++++++++------
7 files changed, 147 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
index 913d90a7a508..5ee74280b9d3 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -40,6 +40,10 @@
#include "intel_hdcp.h"
#include "intel_panel.h"
+static const u32 supported_colorformats = DRM_COLOR_FORMAT_RGB444 |
+ DRM_COLOR_FORMAT_YCBCR444 |
+ DRM_COLOR_FORMAT_YCBCR420;
+
static void intel_connector_modeset_retry_work_fn(struct work_struct *work)
{
struct intel_connector *connector = container_of(work, typeof(*connector),
@@ -333,6 +337,13 @@ intel_attach_dp_colorspace_property(struct drm_connector *connector)
drm_connector_attach_colorspace_property(connector);
}
+void
+intel_attach_colorformat_property(struct drm_connector *connector)
+{
+ if (!drm_mode_create_color_format_property(connector, supported_colorformats))
+ drm_connector_attach_color_format_property(connector);
+}
+
void
intel_attach_scaling_mode_property(struct drm_connector *connector)
{
diff --git a/drivers/gpu/drm/i915/display/intel_connector.h b/drivers/gpu/drm/i915/display/intel_connector.h
index 0aa86626e646..fe6149d1d559 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.h
+++ b/drivers/gpu/drm/i915/display/intel_connector.h
@@ -31,6 +31,7 @@ void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
void intel_attach_aspect_ratio_property(struct drm_connector *connector);
void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
void intel_attach_dp_colorspace_property(struct drm_connector *connector);
+void intel_attach_colorformat_property(struct drm_connector *connector);
void intel_attach_scaling_mode_property(struct drm_connector *connector);
void intel_connector_queue_modeset_retry_work(struct intel_connector *connector);
void intel_connector_cancel_modeset_retry_work(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 38702a9e0f50..c82bff8a44f1 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -2206,6 +2206,21 @@ to_intel_frontbuffer(struct drm_framebuffer *fb)
return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL;
}
+static inline __pure enum drm_color_format
+intel_output_format_to_drm_color_format(enum intel_output_format input)
+{
+ switch (input) {
+ case INTEL_OUTPUT_FORMAT_RGB:
+ return DRM_COLOR_FORMAT_RGB444;
+ case INTEL_OUTPUT_FORMAT_YCBCR444:
+ return DRM_COLOR_FORMAT_YCBCR444;
+ case INTEL_OUTPUT_FORMAT_YCBCR420:
+ return DRM_COLOR_FORMAT_YCBCR420;
+ }
+
+ return DRM_COLOR_FORMAT_AUTO;
+}
+
/*
* Conversion functions/macros from various pointer types to struct
* intel_display pointer.
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 0ec82fcbcf48..bd1687e3a53f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1183,7 +1183,7 @@ dfp_can_convert(struct intel_dp *intel_dp,
return false;
}
-static enum intel_output_format
+enum intel_output_format
intel_dp_output_format(struct intel_connector *connector,
enum intel_output_format sink_format)
{
@@ -3141,17 +3141,24 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
struct intel_connector *connector = intel_dp->attached_connector;
const struct drm_display_info *info = &connector->base.display_info;
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
- bool ycbcr_420_only;
+ enum drm_color_format sink_format_drm;
int ret;
- ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode);
+ if ((conn_state->color_format == DRM_COLOR_FORMAT_YCBCR420 &&
+ drm_mode_is_420(info, adjusted_mode)) ||
+ (conn_state->color_format == DRM_COLOR_FORMAT_AUTO &&
+ drm_mode_is_420_only(info, adjusted_mode)))
+ crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+ else if (conn_state->color_format == DRM_COLOR_FORMAT_YCBCR444)
+ crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+ else
+ crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
- if (ycbcr_420_only && !connector->base.ycbcr_420_allowed) {
+ if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
+ !connector->base.ycbcr_420_allowed) {
drm_dbg_kms(display->drm,
- "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n");
- crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
- } else {
- crtc_state->sink_format = intel_dp_sink_format(connector, adjusted_mode);
+ "YCbCr 4:2:0 mode requested but unsupported by connector.\n");
+ return -EINVAL;
}
crtc_state->output_format = intel_dp_output_format(connector, crtc_state->sink_format);
@@ -3159,9 +3166,20 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
respect_downstream_limits);
if (ret) {
- if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
- !connector->base.ycbcr_420_allowed ||
- !drm_mode_is_420_also(info, adjusted_mode))
+ /*
+ * If no valid link config can be found due to bandwidth constraints,
+ * degrade from RGB/YCbCr 4:4:4 to YCbCr 4:2:0 if permitted by
+ * the source and sink.
+ */
+ if (!connector->base.ycbcr_420_allowed)
+ return ret;
+ /* No point in trying YCbCr420 a second time. */
+ if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ return ret;
+ if (!drm_mode_is_420(info, adjusted_mode))
+ return ret;
+ /* If a non-AUTO color format is chosen, don't fall back. */
+ if (conn_state->color_format)
return ret;
crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
@@ -3169,9 +3187,20 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
crtc_state->sink_format);
ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
respect_downstream_limits);
+ if (ret)
+ return ret;
}
- return ret;
+ sink_format_drm = intel_output_format_to_drm_color_format(crtc_state->sink_format);
+ if (conn_state->color_format && conn_state->color_format != sink_format_drm) {
+ drm_dbg_kms(display->drm,
+ "Explicitly asked for color format %s, got sink format %s\n",
+ drm_get_color_format_name(conn_state->color_format),
+ drm_get_color_format_name(sink_format_drm));
+ return -EINVAL;
+ }
+
+ return 0;
}
void
@@ -6630,6 +6659,8 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *_connec
intel_attach_dp_colorspace_property(&connector->base);
}
+ intel_attach_colorformat_property(&connector->base);
+
if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
drm_connector_attach_hdr_output_metadata_property(&connector->base);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 200a8b267f64..a7492c97ac97 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -205,6 +205,10 @@ bool intel_dp_compute_config_limits(struct intel_dp *intel_dp,
void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
const struct drm_dp_desc *desc, bool is_branch,
struct intel_connector *connector);
+enum intel_output_format
+intel_dp_output_format(struct intel_connector *connector,
+ enum intel_output_format sink_format);
+
bool intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder);
bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4c0b943fe86f..e059306cea40 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -653,6 +653,8 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
+ const struct drm_display_info *info = &connector->base.display_info;
+ enum drm_color_format sink_format_drm;
struct link_config_limits limits;
bool dsc_needed, joiner_needs_dsc;
int num_joined_pipes;
@@ -671,10 +673,35 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
if (num_joined_pipes > 1)
pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1, crtc->pipe);
- pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
- pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
+ if ((conn_state->color_format == DRM_COLOR_FORMAT_YCBCR420 &&
+ drm_mode_is_420(info, adjusted_mode)) ||
+ (conn_state->color_format == DRM_COLOR_FORMAT_AUTO &&
+ drm_mode_is_420_only(info, adjusted_mode)))
+ pipe_config->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+ else if (conn_state->color_format == DRM_COLOR_FORMAT_YCBCR444)
+ pipe_config->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+ else
+ pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
+
+ if (pipe_config->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
+ !connector->base.ycbcr_420_allowed) {
+ drm_dbg_kms(display->drm,
+ "YCbCr 4:2:0 mode requested but unsupported by connector.\n");
+ return -EINVAL;
+ }
+
+ pipe_config->output_format = intel_dp_output_format(connector, pipe_config->sink_format);
pipe_config->has_pch_encoder = false;
+ sink_format_drm = intel_output_format_to_drm_color_format(pipe_config->sink_format);
+ if (conn_state->color_format && conn_state->color_format != sink_format_drm) {
+ drm_dbg_kms(display->drm,
+ "Unsupported color format %s (0x%x), sink has 0x%x\n",
+ drm_get_color_format_name(conn_state->color_format),
+ conn_state->color_format, sink_format_drm);
+ return -EINVAL;
+ }
+
joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
@@ -1660,6 +1687,11 @@ static int mst_topology_add_connector_properties(struct intel_dp *intel_dp,
if (connector->base.max_bpc_property)
drm_connector_attach_max_bpc_property(&connector->base, 6, 12);
+ connector->base.color_format_property =
+ intel_dp->attached_connector->base.color_format_property;
+ if (connector->base.color_format_property)
+ intel_attach_colorformat_property(&connector->base);
+
return drm_connector_set_path_property(&connector->base, pathprop);
}
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 908faf17f93d..d3e77781a0a6 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2271,30 +2271,53 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
struct intel_connector *connector = to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
const struct drm_display_info *info = &connector->base.display_info;
- bool ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode);
+ enum drm_color_format req_fmt = conn_state->color_format;
+ enum drm_color_format sink_format_drm;
int ret;
- crtc_state->sink_format =
- intel_hdmi_sink_format(crtc_state, connector, ycbcr_420_only);
-
- if (ycbcr_420_only && crtc_state->sink_format != INTEL_OUTPUT_FORMAT_YCBCR420) {
- drm_dbg_kms(display->drm,
- "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n");
- crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
- }
+ if (!req_fmt)
+ crtc_state->sink_format =
+ intel_hdmi_sink_format(crtc_state, connector,
+ drm_mode_is_420_only(info, adjusted_mode));
+ else if (req_fmt == DRM_COLOR_FORMAT_YCBCR444)
+ crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+ else
+ crtc_state->sink_format = intel_hdmi_sink_format(crtc_state, connector,
+ req_fmt == DRM_COLOR_FORMAT_YCBCR420);
crtc_state->output_format = intel_hdmi_output_format(crtc_state);
ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
if (ret) {
- if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
- !crtc_state->has_hdmi_sink ||
- !connector->base.ycbcr_420_allowed ||
- !drm_mode_is_420_also(info, adjusted_mode))
+ /*
+ * If no valid link config can be found due to bandwidth constraints,
+ * degrade from RGB/YCbCr 4:4:4 to YCbCr 4:2:0 if permitted by
+ * the source and sink.
+ */
+ if (!connector->base.ycbcr_420_allowed)
+ return ret;
+ /* No point in trying YCbCr420 a second time. */
+ if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ return ret;
+ if (!drm_mode_is_420(info, adjusted_mode))
+ return ret;
+ /* If a non-AUTO color format is chosen, don't fall back. */
+ if (req_fmt)
return ret;
crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
crtc_state->output_format = intel_hdmi_output_format(crtc_state);
ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
+ if (ret)
+ return ret;
+ }
+
+ sink_format_drm = intel_output_format_to_drm_color_format(crtc_state->sink_format);
+ if (req_fmt && req_fmt != sink_format_drm) {
+ drm_dbg_kms(display->drm,
+ "Explicitly asked for color format %s, got sink format %s\n",
+ drm_get_color_format_name(req_fmt),
+ drm_get_color_format_name(sink_format_drm));
+ ret = -EINVAL;
}
return ret;
@@ -2690,8 +2713,10 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *_
if (DISPLAY_VER(display) >= 10)
drm_connector_attach_hdr_output_metadata_property(&connector->base);
- if (!HAS_GMCH(display))
+ if (!HAS_GMCH(display)) {
drm_connector_attach_max_bpc_property(&connector->base, 8, 12);
+ intel_attach_colorformat_property(&connector->base);
+ }
}
/*
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 08/17] drm/amdgpu: Implement "color format" DRM property
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (6 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 07/17] drm/i915: Implement the "color format" DRM property Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 09/17] drm/rockchip: Add YUV422 output mode constants for VOP2 Nicolas Frattaroli
` (8 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli,
Werner Sembach, Andri Yngvason, Marius Vlad
The "color format" DRM property allows userspace to explicitly pick a
color format to use. If an unsupported color format is requested,
userspace will be given an error instead of silently having its request
disobeyed.
The default case, which is AUTO, picks YCbCr 4:2:0 if it's a 4:2:0-only
mode, and RGB in all other cases.
Co-developed-by: Werner Sembach <wse@tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Co-developed-by: Andri Yngvason <andri@yngvason.is>
Signed-off-by: Andri Yngvason <andri@yngvason.is>
Co-developed-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 85 +++++++++++++++++++---
.../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 13 ++++
2 files changed, 89 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0b44bfe9e7e5..60de0a748172 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6650,11 +6650,14 @@ static void fill_stream_properties_from_drm_display_mode(
const struct dc_stream_state *old_stream,
int requested_bpc)
{
+ bool is_dp_or_hdmi = dc_is_hdmi_signal(stream->signal) || dc_is_dp_signal(stream->signal);
struct dc_crtc_timing *timing_out = &stream->timing;
const struct drm_display_info *info = &connector->display_info;
struct amdgpu_dm_connector *aconnector = NULL;
struct hdmi_vendor_infoframe hv_frame;
struct hdmi_avi_infoframe avi_frame;
+ bool want_420;
+ bool want_422;
ssize_t err;
if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
@@ -6667,19 +6670,38 @@ static void fill_stream_properties_from_drm_display_mode(
timing_out->h_border_right = 0;
timing_out->v_border_top = 0;
timing_out->v_border_bottom = 0;
- /* TODO: un-hardcode */
- if (drm_mode_is_420_only(info, mode_in) || (drm_mode_is_420_also(info, mode_in) &&
- aconnector && aconnector->force_yuv420_output))
+
+ want_420 = (aconnector && aconnector->force_yuv420_output) ||
+ (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR420);
+ want_422 = (aconnector && aconnector->force_yuv422_output) ||
+ (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR422);
+
+ if (drm_mode_is_420_only(info, mode_in) && (want_420 || !connector_state->color_format))
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
- else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR422)
- && aconnector
- && aconnector->force_yuv422_output)
+ else if (drm_mode_is_420_also(info, mode_in) && want_420)
+ timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+ else if ((info->color_formats & DRM_COLOR_FORMAT_YCBCR422) && want_422 && is_dp_or_hdmi)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR422;
- else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
- && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
+ else if (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR444 &&
+ (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) && is_dp_or_hdmi)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
- else
+ else if ((connector_state->color_format == DRM_COLOR_FORMAT_RGB444 ||
+ !connector_state->color_format))
timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+ else {
+ /*
+ * If a format was explicitly requested but the requested format
+ * can't be satisfied, set it to an invalid value so that an
+ * error bubbles up to userspace. This way, userspace knows it
+ * needs to make a better choice.
+ */
+ if (connector_state->color_format)
+ timing_out->pixel_encoding = PIXEL_ENCODING_UNDEFINED;
+ else if (drm_mode_is_420_only(info, mode_in))
+ timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+ else
+ timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+ }
timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
timing_out->display_color_depth = convert_color_depth_from_display_info(
@@ -8027,6 +8049,38 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc,
return dc_result;
}
+static enum dc_status
+dm_validate_stream_color_format(const struct drm_connector_state *drm_state,
+ const struct dc_stream_state *stream)
+{
+ enum dc_pixel_encoding encoding;
+
+ if (!drm_state->color_format)
+ return DC_OK;
+
+ switch (drm_state->color_format) {
+ case DRM_COLOR_FORMAT_AUTO:
+ case DRM_COLOR_FORMAT_RGB444:
+ encoding = PIXEL_ENCODING_RGB;
+ break;
+ case DRM_COLOR_FORMAT_YCBCR444:
+ encoding = PIXEL_ENCODING_YCBCR444;
+ break;
+ case DRM_COLOR_FORMAT_YCBCR422:
+ encoding = PIXEL_ENCODING_YCBCR422;
+ break;
+ case DRM_COLOR_FORMAT_YCBCR420:
+ encoding = PIXEL_ENCODING_YCBCR420;
+ break;
+ default:
+ encoding = PIXEL_ENCODING_UNDEFINED;
+ break;
+ }
+
+ return encoding == stream->timing.pixel_encoding ?
+ DC_OK : DC_UNSUPPORTED_VALUE;
+}
+
struct dc_stream_state *
create_validate_stream_for_sink(struct drm_connector *connector,
const struct drm_display_mode *drm_mode,
@@ -8073,6 +8127,9 @@ create_validate_stream_for_sink(struct drm_connector *connector,
if (dc_result == DC_OK)
dc_result = dm_validate_stream_and_context(adev->dm.dc, stream);
+ if (dc_result == DC_OK)
+ dc_result = dm_validate_stream_color_format(drm_state, stream);
+
if (dc_result != DC_OK) {
DRM_DEBUG_KMS("Pruned mode %d x %d (clk %d) %s %s -- %s\n",
drm_mode->hdisplay,
@@ -8888,6 +8945,12 @@ static const u32 supported_colorspaces =
BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) |
BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
+static const u32 supported_colorformats =
+ DRM_COLOR_FORMAT_RGB444 |
+ DRM_COLOR_FORMAT_YCBCR444 |
+ DRM_COLOR_FORMAT_YCBCR422 |
+ DRM_COLOR_FORMAT_YCBCR420;
+
void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
struct amdgpu_dm_connector *aconnector,
int connector_type,
@@ -9000,6 +9063,10 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
if (adev->dm.hdcp_workqueue)
drm_connector_attach_content_protection_property(&aconnector->base, true);
+
+ if (!drm_mode_create_color_format_property(&aconnector->base,
+ supported_colorformats))
+ drm_connector_attach_color_format_property(&aconnector->base);
}
if (connector_type == DRM_MODE_CONNECTOR_eDP) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index dbd1da4d85d3..3ae610e11806 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -52,6 +52,12 @@
#define PEAK_FACTOR_X1000 1006
+static const u32 supported_colorformats =
+ DRM_COLOR_FORMAT_RGB444 |
+ DRM_COLOR_FORMAT_YCBCR444 |
+ DRM_COLOR_FORMAT_YCBCR422 |
+ DRM_COLOR_FORMAT_YCBCR420;
+
/*
* This function handles both native AUX and I2C-Over-AUX transactions.
*/
@@ -679,6 +685,13 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
if (connector->max_bpc_property)
drm_connector_attach_max_bpc_property(connector, 8, 16);
+ connector->color_format_property = master->base.color_format_property;
+ if (connector->color_format_property) {
+ if (!drm_mode_create_color_format_property(&aconnector->base,
+ supported_colorformats))
+ drm_connector_attach_color_format_property(&aconnector->base);
+ }
+
connector->vrr_capable_property = master->base.vrr_capable_property;
if (connector->vrr_capable_property)
drm_connector_attach_vrr_capable_property(connector);
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 09/17] drm/rockchip: Add YUV422 output mode constants for VOP2
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (7 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 08/17] drm/amdgpu: Implement " Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 10/17] drm/rockchip: vop2: Fix YUV444 output Nicolas Frattaroli
` (7 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
The Rockchip display controller has a general YUV422 output mode, and
some SoC-specific connector-specific output modes for RK3576.
Add them, based on the values in downstream and the TRM (dsp_out_mode in
RK3576 TRM Part 2, register POST*_CTRL_POST_DSP_CTRL).
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 2e86ad00979c..4705dc6b8bd7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,10 +30,14 @@
#define ROCKCHIP_OUT_MODE_P565 2
#define ROCKCHIP_OUT_MODE_BT656 5
#define ROCKCHIP_OUT_MODE_S888 8
+#define ROCKCHIP_OUT_MODE_YUV422 9
#define ROCKCHIP_OUT_MODE_S888_DUMMY 12
#define ROCKCHIP_OUT_MODE_YUV420 14
/* for use special outface */
#define ROCKCHIP_OUT_MODE_AAAA 15
+/* SoC specific output modes */
+#define ROCKCHIP_OUT_MODE_YUV422_RK3576_DP 12
+#define ROCKCHIP_OUT_MODE_YUV422_RK3576_HDMI 13
/* output flags */
#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0)
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 10/17] drm/rockchip: vop2: Fix YUV444 output
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (8 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 09/17] drm/rockchip: Add YUV422 output mode constants for VOP2 Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 11/17] drm/rockchip: vop2: Add RK3576 to the RG swap special case Nicolas Frattaroli
` (6 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
YUV444 (aka YCbCr444) output isn't working quite right on RK3588. The
resulting image on the display, while identifying itself as YUV444, has
some components swapped, even after adding the necessary DRM formats to
the conversion functions.
Judging by downstream, this is because YUV444 also needs an rb swap
performed in the AFBC case.
Add the DRM formats to the appropriate switch statements, and add a
function for checking whether an rb swap needs to be performed in the
AFBC case.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 498df0ce4680..f1252d1f06e9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -176,6 +176,7 @@ static enum vop2_data_format vop2_convert_format(u32 format)
case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_VUY101010:
return VOP2_FMT_XRGB101010;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
@@ -184,6 +185,7 @@ static enum vop2_data_format vop2_convert_format(u32 format)
return VOP2_FMT_ARGB8888;
case DRM_FORMAT_RGB888:
case DRM_FORMAT_BGR888:
+ case DRM_FORMAT_VUY888:
return VOP2_FMT_RGB888;
case DRM_FORMAT_RGB565:
case DRM_FORMAT_BGR565:
@@ -225,6 +227,7 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_VUY101010:
return VOP2_AFBC_FMT_ARGB2101010;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
@@ -233,6 +236,7 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
return VOP2_AFBC_FMT_ARGB8888;
case DRM_FORMAT_RGB888:
case DRM_FORMAT_BGR888:
+ case DRM_FORMAT_VUY888:
return VOP2_AFBC_FMT_RGB888;
case DRM_FORMAT_RGB565:
case DRM_FORMAT_BGR565:
@@ -270,6 +274,19 @@ static bool vop2_win_rb_swap(u32 format)
}
}
+static bool vop2_afbc_rb_swap(u32 format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV30:
+ case DRM_FORMAT_VUY888:
+ case DRM_FORMAT_VUY101010:
+ return true;
+ default:
+ return false;
+ }
+}
+
static bool vop2_afbc_uv_swap(u32 format)
{
switch (format) {
@@ -1304,6 +1321,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
/* It's for head stride, each head size is 16 byte */
stride = ALIGN(stride, block_w) / block_w * 16;
+ rb_swap = vop2_afbc_rb_swap(fb->format->format);
uv_swap = vop2_afbc_uv_swap(fb->format->format);
/*
* This is a workaround for crazy IC design, Cluster
@@ -1321,6 +1339,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1);
vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format);
vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap);
+ vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap);
/*
* On rk3566/8, this bit is auto gating enable,
* but this function is not work well so we need
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 11/17] drm/rockchip: vop2: Add RK3576 to the RG swap special case
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (9 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 10/17] drm/rockchip: vop2: Fix YUV444 output Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 12/17] drm/rockchip: vop2: Recognise 10/12-bit YUV422 as YUV formats Nicolas Frattaroli
` (5 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
Much like RK3588, RK3576 requires an RG swap to be performed for YUV444
8-bit and YUV444 10-bit bus formats.
Add its version to the already existing check for RK3588, so that YUV444
output is correct on this platform.
Fixes: 944757a4cba6 ("drm/rockchip: vop2: Add support for rk3576")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index f1252d1f06e9..0a1adf36a24f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -354,7 +354,8 @@ static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format)
{
- if (vop2->version == VOP_VERSION_RK3588) {
+ if (vop2->version == VOP_VERSION_RK3588 ||
+ vop2->version == VOP_VERSION_RK3576) {
if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
bus_format == MEDIA_BUS_FMT_YUV10_1X30)
return true;
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 12/17] drm/rockchip: vop2: Recognise 10/12-bit YUV422 as YUV formats
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (10 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 11/17] drm/rockchip: vop2: Add RK3576 to the RG swap special case Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 13/17] drm/rockchip: vop2: Set correct output format for RK3576 YUV422 Nicolas Frattaroli
` (4 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
The Rockchip VOP2 video output driver has a "is_yuv_output" function,
which returns true when a given bus format is a YUV format, and false
otherwise.
This switch statement is lacking the bus format used for YUV422 10-bit,
as well as the bus format used for YUV422 12-bit.
Add MEDIA_BUS_FMT_YUYV10_1X20 and MEDIA_BUS_FMT_YUYV12_1X24 to
is_yuv_output's switch cases to resolve this.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0a1adf36a24f..21afcca1218c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -369,6 +369,8 @@ static bool is_yuv_output(u32 bus_format)
switch (bus_format) {
case MEDIA_BUS_FMT_YUV8_1X24:
case MEDIA_BUS_FMT_YUV10_1X30:
+ case MEDIA_BUS_FMT_YUYV10_1X20:
+ case MEDIA_BUS_FMT_YUYV12_1X24:
case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
case MEDIA_BUS_FMT_YUYV8_2X8:
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 13/17] drm/rockchip: vop2: Set correct output format for RK3576 YUV422
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (11 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 12/17] drm/rockchip: vop2: Recognise 10/12-bit YUV422 as YUV formats Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 14/17] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property Nicolas Frattaroli
` (3 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
For RK3576 to be able to output YUV422 signals, it first needs to be
able to pick the right output mode in the display controller to do so.
The RK3576 hardware specifies different output formats depending on the
used display protocol.
Adjust the written register value based on the SoC and connector, so
other users of vcstate->output_mode don't have to care about this.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 21afcca1218c..cd18876955e4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1707,6 +1707,22 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
!(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))
out_mode = ROCKCHIP_OUT_MODE_P888;
+ else if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 &&
+ vop2->version == VOP_VERSION_RK3576)
+ switch (vcstate->output_type) {
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ case DRM_MODE_CONNECTOR_eDP:
+ out_mode = ROCKCHIP_OUT_MODE_YUV422_RK3576_DP;
+ break;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ out_mode = ROCKCHIP_OUT_MODE_YUV422_RK3576_HDMI;
+ break;
+ default:
+ drm_err(vop2->drm, "Unknown DRM_MODE_CONNECTOR %d\n",
+ vcstate->output_type);
+ vop2_unlock(vop2);
+ return;
+ }
else
out_mode = vcstate->output_mode;
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 14/17] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (12 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 13/17] drm/rockchip: vop2: Set correct output format for RK3576 YUV422 Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 15/17] drm/rockchip: dw_hdmi_qp: Set supported_formats platdata Nicolas Frattaroli
` (2 subsequent siblings)
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
Switch between requested color formats by setting the right bus formats,
configuring the VO GRF registers, and setting the right output mode.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 61 ++++++++++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 +
2 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c9fe6aa3e3e3..c79ebd9e866c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -11,6 +11,7 @@
#include <linux/gpio/consumer.h>
#include <linux/hw_bitfield.h>
#include <linux/mfd/syscon.h>
+#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
@@ -135,24 +136,70 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
- struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
+ struct drm_display_info *info = &conn_state->connector->display_info;
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+ struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
union phy_configure_opts phy_cfg = {};
int ret;
if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
- s->output_bpc == conn_state->hdmi.output_bpc)
+ s->output_bpc == conn_state->hdmi.output_bpc &&
+ s->color_format == conn_state->color_format)
return 0;
+ if (conn_state->color_format &&
+ !(info->color_formats & conn_state->color_format))
+ return -EINVAL;
+
+ switch (conn_state->color_format) {
+ case DRM_COLOR_FORMAT_AUTO:
+ case DRM_COLOR_FORMAT_RGB444:
+ if (conn_state->hdmi.output_bpc == 8)
+ s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ else if (conn_state->hdmi.output_bpc == 10)
+ s->bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
+ else
+ return -EINVAL;
+ s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+ break;
+ case DRM_COLOR_FORMAT_YCBCR444:
+ if (conn_state->hdmi.output_bpc == 8)
+ s->bus_format = MEDIA_BUS_FMT_YUV8_1X24;
+ else if (conn_state->hdmi.output_bpc == 10)
+ s->bus_format = MEDIA_BUS_FMT_YUV10_1X30;
+ else
+ return -EINVAL;
+ s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+ break;
+ case DRM_COLOR_FORMAT_YCBCR422:
+ if (conn_state->hdmi.output_bpc == 8)
+ s->bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
+ else /* 10 bpc possible, but currently busted */
+ return -EINVAL;
+ s->output_mode = ROCKCHIP_OUT_MODE_YUV422;
+ break;
+ case DRM_COLOR_FORMAT_YCBCR420:
+ if (conn_state->hdmi.output_bpc == 8)
+ s->bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
+ else if (conn_state->hdmi.output_bpc == 10)
+ s->bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
+ else
+ return -EINVAL;
+ s->output_mode = ROCKCHIP_OUT_MODE_YUV420;
+ break;
+ default:
+ return -EINVAL;
+ }
+
phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;
ret = phy_configure(hdmi->phy, &phy_cfg);
if (!ret) {
hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
- s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
s->output_bpc = conn_state->hdmi.output_bpc;
+ s->color_format = conn_state->color_format;
} else {
dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret);
}
@@ -391,6 +438,8 @@ static void dw_hdmi_qp_rk3588_io_init(struct rockchip_hdmi_qp *hdmi)
static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi,
struct rockchip_crtc_state *state)
{
+ enum hdmi_colorspace color =
+ drm_color_format_to_hdmi_colorspace(state->color_format);
u32 val;
if (state->output_bpc == 10)
@@ -398,12 +447,16 @@ static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi,
else
val = FIELD_PREP_WM16(RK3576_COLOR_DEPTH_MASK, RK3576_8BPC);
+ val |= FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, color);
+
regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON8, val);
}
static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi,
struct rockchip_crtc_state *state)
{
+ enum hdmi_colorspace color =
+ drm_color_format_to_hdmi_colorspace(state->color_format);
u32 val;
if (state->output_bpc == 10)
@@ -411,6 +464,8 @@ static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi,
else
val = FIELD_PREP_WM16(RK3588_COLOR_DEPTH_MASK, RK3588_8BPC);
+ val |= FIELD_PREP_WM16(RK3588_COLOR_FORMAT_MASK, color);
+
regmap_write(hdmi->vo_regmap,
hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
val);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 4705dc6b8bd7..2549e58f3497 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -57,6 +57,7 @@ struct rockchip_crtc_state {
u32 bus_format;
u32 bus_flags;
int color_space;
+ enum drm_color_format color_format;
};
#define to_rockchip_crtc_state(s) \
container_of(s, struct rockchip_crtc_state, base)
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 15/17] drm/rockchip: dw_hdmi_qp: Set supported_formats platdata
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (13 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 14/17] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 16/17] drm/connector: Register color format property on HDMI connectors Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format property Nicolas Frattaroli
16 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
With the introduction of the supported_formats member in the
dw-hdmi-qp platform data struct, drivers that have access to this
information should now set it.
Set it in the rockchip dw_hdmi_qp glue driver.
This allows this information to be passed down to the dw-hdmi-qp core,
which sets it in the bridge it creates, and consequently will allow the
common HDMI bridge code to act on it.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c79ebd9e866c..5827ca2de0bd 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -576,6 +576,10 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
plat_data.phy_data = hdmi;
plat_data.max_bpc = 10;
+ plat_data.supported_formats = BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV444) |
+ BIT(HDMI_COLORSPACE_YUV422);
+
encoder = &hdmi->encoder.encoder;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 16/17] drm/connector: Register color format property on HDMI connectors
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (14 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 15/17] drm/rockchip: dw_hdmi_qp: Set supported_formats platdata Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-12-09 14:22 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format property Nicolas Frattaroli
16 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
The drmm_connector_hdmi_init function can figure out what DRM color
formats are supported by a particular connector based on the supported
HDMI format bitmask that's passed in.
Use it to register the drm color format property.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/drm_connector.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 13151d9bfb82..7c38123f99cd 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -578,6 +578,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
unsigned long supported_formats,
unsigned int max_bpc)
{
+ u32 supported_drm_formats = 0;
int ret;
if (!vendor || !product)
@@ -621,6 +622,18 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
if (max_bpc > 8)
drm_connector_attach_hdr_output_metadata_property(connector);
+ if (supported_formats & BIT(HDMI_COLORSPACE_RGB))
+ supported_drm_formats |= DRM_COLOR_FORMAT_RGB444;
+ if (supported_formats & BIT(HDMI_COLORSPACE_YUV444))
+ supported_drm_formats |= DRM_COLOR_FORMAT_YCBCR444;
+ if (supported_formats & BIT(HDMI_COLORSPACE_YUV422))
+ supported_drm_formats |= DRM_COLOR_FORMAT_YCBCR422;
+ if (supported_formats & BIT(HDMI_COLORSPACE_YUV420))
+ supported_drm_formats |= DRM_COLOR_FORMAT_YCBCR420;
+
+ if (!drm_mode_create_color_format_property(connector, supported_drm_formats))
+ drm_connector_attach_color_format_property(connector);
+
connector->hdmi.funcs = hdmi_funcs;
return 0;
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format property
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
` (15 preceding siblings ...)
2025-11-28 21:05 ` [PATCH v5 16/17] drm/connector: Register color format property on HDMI connectors Nicolas Frattaroli
@ 2025-11-28 21:05 ` Nicolas Frattaroli
2025-12-12 9:19 ` Maxime Ripard
16 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-11-28 21:05 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, Nicolas Frattaroli
Add some KUnit tests to check the color_format property is working as
expected with the HDMI state helper.
The added tests check that AUTO results in RGB, and the YCBCR modes
result in the corresponding YUV modes. An additional test ensures that
only DRM_COLOR_FORMAT_AUTO falls back to YUV420 with a YUV420-only mode,
and RGB errors out instead, while explicitly asking for YUV420 still
works.
This requires exporting hdmi_compute_config, so that it is accessible
from the tests.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/display/drm_hdmi_state_helper.c | 3 +-
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 +++++++++++++++++++++
include/drm/display/drm_hdmi_state_helper.h | 4 +
3 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 1800e00b30c5..e86fb837ceaf 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -641,7 +641,7 @@ hdmi_compute_format_bpc(const struct drm_connector *connector,
return -EINVAL;
}
-static int
+int
hdmi_compute_config(const struct drm_connector *connector,
struct drm_connector_state *conn_state,
const struct drm_display_mode *mode)
@@ -680,6 +680,7 @@ hdmi_compute_config(const struct drm_connector *connector,
return ret;
}
+EXPORT_SYMBOL(hdmi_compute_config);
static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
struct drm_connector_state *conn_state)
diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
index 8bd412735000..e7050cd9cb12 100644
--- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
@@ -55,6 +55,23 @@ static struct drm_display_mode *find_preferred_mode(struct drm_connector *connec
return preferred;
}
+static struct drm_display_mode *find_420_only_mode(struct drm_connector *connector)
+{
+ struct drm_device *drm = connector->dev;
+ struct drm_display_mode *mode;
+
+ mutex_lock(&drm->mode_config.mutex);
+ list_for_each_entry(mode, &connector->modes, head) {
+ if (drm_mode_is_420_only(&connector->display_info, mode)) {
+ mutex_unlock(&drm->mode_config.mutex);
+ return mode;
+ }
+ }
+ mutex_unlock(&drm->mode_config.mutex);
+
+ return NULL;
+}
+
static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
const void *edid, size_t edid_len)
{
@@ -1999,6 +2016,95 @@ static void drm_test_check_disable_connector(struct kunit *test)
drm_modeset_acquire_fini(&ctx);
}
+struct color_format_test_param {
+ enum drm_color_format fmt;
+ enum hdmi_colorspace expected;
+ const char *desc;
+};
+
+/* Test that AUTO results in RGB, and explicit choices result in those */
+static void drm_test_check_hdmi_color_format(struct kunit *test)
+{
+ const struct color_format_test_param *param = test->param_value;
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ int ret;
+
+ priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV420) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12,
+ &dummy_connector_hdmi_funcs,
+ test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn_state = priv->connector.state;
+ info = &priv->connector.display_info;
+ conn_state->color_format = param->fmt;
+ KUNIT_ASSERT_TRUE(test, priv->connector.ycbcr_420_allowed);
+
+ preferred = find_preferred_mode(&priv->connector);
+ KUNIT_ASSERT_TRUE(test, drm_mode_is_420(info, preferred));
+
+ ret = hdmi_compute_config(&priv->connector, conn_state, preferred);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, param->expected);
+}
+
+static const struct color_format_test_param hdmi_color_format_params[] = {
+ { DRM_COLOR_FORMAT_AUTO, HDMI_COLORSPACE_RGB, "AUTO -> RGB" },
+ { DRM_COLOR_FORMAT_YCBCR422, HDMI_COLORSPACE_YUV422, "YCBCR422 -> YUV422" },
+ { DRM_COLOR_FORMAT_YCBCR420, HDMI_COLORSPACE_YUV420, "YCBCR420 -> YUV420" },
+ { DRM_COLOR_FORMAT_YCBCR444, HDMI_COLORSPACE_YUV444, "YCBCR444 -> YUV444" },
+ { DRM_COLOR_FORMAT_RGB444, HDMI_COLORSPACE_RGB, "RGB -> RGB" },
+};
+
+KUNIT_ARRAY_PARAM_DESC(check_hdmi_color_format,
+ hdmi_color_format_params, desc);
+
+
+/* Test that AUTO falls back to YUV420, and that RGB does not, but YUV420 works */
+static void drm_test_check_hdmi_color_format_420_only(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_display_mode *dank;
+ int ret;
+
+ priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV420) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12,
+ &dummy_connector_hdmi_funcs,
+ test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn_state = priv->connector.state;
+
+ dank = find_420_only_mode(&priv->connector);
+ KUNIT_ASSERT_NOT_NULL(test, dank);
+
+ conn_state->color_format = DRM_COLOR_FORMAT_AUTO;
+ ret = hdmi_compute_config(&priv->connector, conn_state, dank);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV420);
+
+ conn_state->color_format = DRM_COLOR_FORMAT_RGB444;
+ ret = hdmi_compute_config(&priv->connector, conn_state, dank);
+ KUNIT_EXPECT_LT(test, ret, 0);
+
+ conn_state->color_format = DRM_COLOR_FORMAT_YCBCR420;
+ ret = hdmi_compute_config(&priv->connector, conn_state, dank);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV420);
+};
+
static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
@@ -2028,6 +2134,9 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
+ KUNIT_CASE_PARAM(drm_test_check_hdmi_color_format,
+ check_hdmi_color_format_gen_params),
+ KUNIT_CASE(drm_test_check_hdmi_color_format_420_only),
/*
* TODO: We should have tests to check that a change in the
* format triggers a CRTC mode change just like we do for the
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index 2349c0d0f00f..01ae31209820 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -30,4 +30,8 @@ enum drm_mode_status
drm_hdmi_connector_mode_valid(struct drm_connector *connector,
const struct drm_display_mode *mode);
+int hdmi_compute_config(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state,
+ const struct drm_display_mode *mode);
+
#endif // DRM_HDMI_STATE_HELPER_H_
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH v5 02/17] drm: Add new general DRM property "color format"
2025-11-28 21:05 ` [PATCH v5 02/17] drm: Add new general DRM property "color format" Nicolas Frattaroli
@ 2025-12-09 14:11 ` Maxime Ripard
0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2025-12-09 14:11 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe, Andri Yngvason, Werner Sembach, Marius Vlad
[-- Attachment #1: Type: text/plain, Size: 737 bytes --]
Hi,
On Fri, Nov 28, 2025 at 10:05:38PM +0100, Nicolas Frattaroli wrote:
> From: Andri Yngvason <andri@yngvason.is>
>
> Add a new general DRM property named "color format" which can be used by
> userspace to request the display driver to output a particular color
> format.
>
> Possible options are:
> - auto (setup by default, driver internally picks the color format)
I'm not entirely sure that's how we should document it. i915, amdgpu,
and every driver using the hdmi helpers uses the same algorithm: first
try with RGB, then fallback to YUV420 if it doesn't work.
I think we should document that, and every driver exposing this property
should behave that way. It's going to be a mess otherwise.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 03/17] drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE
2025-11-28 21:05 ` [PATCH v5 03/17] drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE Nicolas Frattaroli
@ 2025-12-09 14:12 ` Maxime Ripard
0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2025-12-09 14:12 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: amd-gfx, dri-devel, intel-gfx, intel-xe, kernel, linux-arm-kernel,
linux-kernel, linux-rockchip, Alex Deucher, Andrzej Hajda,
Andy Yan, Christian König, David Airlie, Dmitry Baryshkov,
Harry Wentland, Heiko Stübner, Jani Nikula, Jernej Skrabec,
Jonas Karlman, Joonas Lahtinen, Laurent Pinchart, Leo Li,
Maarten Lankhorst, Marius Vlad, Maxime Ripard, Neil Armstrong,
Rob Herring, Robert Foss, Rodrigo Siqueira, Rodrigo Vivi,
Sandy Huang, Sascha Hauer, Simona Vetter, Thomas Zimmermann,
Tvrtko Ursulin
On Fri, 28 Nov 2025 22:05:39 +0100, Nicolas Frattaroli wrote:
> From: Marius Vlad <marius.vlad@collabora.com>
>
> While the two enums have similar values, they're not identical, and
> HDMI's enum is defined as per the HDMI standard.
>
>
> [ ... ]
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property
2025-11-28 21:05 ` [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property Nicolas Frattaroli
@ 2025-12-09 14:16 ` Maxime Ripard
2025-12-11 19:42 ` Nicolas Frattaroli
0 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2025-12-09 14:16 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
[-- Attachment #1: Type: text/plain, Size: 2196 bytes --]
On Fri, Nov 28, 2025 at 10:05:41PM +0100, Nicolas Frattaroli wrote:
> With the introduction of the "color format" DRM property, which allows
> userspace to request a specific color format, the HDMI state helper
> should implement this.
>
> Implement it by checking whether the property is set and set to
> something other than auto. If so, pass the requested color format, and
> otherwise set RGB.
>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
> drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> index a561f124be99..5da956bdd68c 100644
> --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> @@ -649,11 +649,21 @@ hdmi_compute_config(const struct drm_connector *connector,
> unsigned int max_bpc = clamp_t(unsigned int,
> conn_state->max_bpc,
> 8, connector->max_bpc);
> + enum hdmi_colorspace hdmi_colorspace =
> + drm_color_format_to_hdmi_colorspace(conn_state->color_format);
> int ret;
>
> ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> - HDMI_COLORSPACE_RGB);
> + hdmi_colorspace);
> if (ret) {
> + /* If a color format was explicitly requested, don't fall back */
> + if (conn_state->color_format) {
> + drm_dbg_kms(connector->dev,
> + "Explicitly set color format '%s' doesn't work.\n",
> + drm_get_color_format_name(conn_state->color_format));
> + return ret;
> + }
> +
I think the following would be more readable:
if (conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO) {
enum hdmi_colorspace hdmi_colorspace =
drm_color_format_to_hdmi_colorspace(conn_state->color_format);
return hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc, hdmi_colorspace)
}
ret = ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
HDMI_COLORSPACE_RGB);
...
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid
2025-11-28 21:05 ` [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid Nicolas Frattaroli
@ 2025-12-09 14:18 ` Maxime Ripard
2025-12-11 19:59 ` Nicolas Frattaroli
0 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2025-12-09 14:18 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
[-- Attachment #1: Type: text/plain, Size: 1892 bytes --]
On Fri, Nov 28, 2025 at 10:05:42PM +0100, Nicolas Frattaroli wrote:
> drm_hdmi_connector_mode_valid assumes modes are only valid if they work
> with RGB. The reality is more complex however: YCbCr 4:2:0
> chroma-subsampled modes only require half the pixel clock that the same
> mode would require in RGB.
>
> This leads to drm_hdmi_connector_mode_valid rejecting perfectly valid
> 420-only modes.
>
> Fix this by checking whether the mode is 420-only first. If so, then
> proceed by checking it with HDMI_COLORSPACE_YUV420 so long as the
> connector has legalized 420, otherwise error out. If the mode is not
> 420-only, check with RGB as was previously always the case.
>
> Fixes: 47368ab437fd ("drm/display: hdmi: add generic mode_valid helper")
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
> drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> index 5da956bdd68c..1800e00b30c5 100644
> --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> @@ -892,8 +892,18 @@ drm_hdmi_connector_mode_valid(struct drm_connector *connector,
> const struct drm_display_mode *mode)
> {
> unsigned long long clock;
> + enum hdmi_colorspace fmt;
> +
> + if (drm_mode_is_420_only(&connector->display_info, mode)) {
> + if (connector->ycbcr_420_allowed)
> + fmt = HDMI_COLORSPACE_YUV420;
> + else
> + return MODE_NO_420;
> + } else {
> + fmt = HDMI_COLORSPACE_RGB;
> + }
>
> - clock = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
> + clock = drm_hdmi_compute_mode_clock(mode, 8, fmt);
I agree on principle, but we need to have a test for this.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 16/17] drm/connector: Register color format property on HDMI connectors
2025-11-28 21:05 ` [PATCH v5 16/17] drm/connector: Register color format property on HDMI connectors Nicolas Frattaroli
@ 2025-12-09 14:22 ` Maxime Ripard
0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2025-12-09 14:22 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: amd-gfx, dri-devel, intel-gfx, intel-xe, kernel, linux-arm-kernel,
linux-kernel, linux-rockchip, Alex Deucher, Andrzej Hajda,
Andy Yan, Christian König, David Airlie, Dmitry Baryshkov,
Harry Wentland, Heiko Stübner, Jani Nikula, Jernej Skrabec,
Jonas Karlman, Joonas Lahtinen, Laurent Pinchart, Leo Li,
Maarten Lankhorst, Maxime Ripard, Neil Armstrong, Rob Herring,
Robert Foss, Rodrigo Siqueira, Rodrigo Vivi, Sandy Huang,
Sascha Hauer, Simona Vetter, Thomas Zimmermann, Tvrtko Ursulin
On Fri, 28 Nov 2025 22:05:52 +0100, Nicolas Frattaroli wrote:
> The drmm_connector_hdmi_init function can figure out what DRM color
> formats are supported by a particular connector based on the supported
> HDMI format bitmask that's passed in.
>
> Use it to register the drm color format property.
>
> [ ... ]
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 04/17] drm/bridge: Act on the DRM color format property
2025-11-28 21:05 ` [PATCH v5 04/17] drm/bridge: Act on the DRM color format property Nicolas Frattaroli
@ 2025-12-09 14:27 ` Maxime Ripard
2025-12-11 19:34 ` Nicolas Frattaroli
0 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2025-12-09 14:27 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
[-- Attachment #1: Type: text/plain, Size: 3001 bytes --]
Hi,
On Fri, Nov 28, 2025 at 10:05:40PM +0100, Nicolas Frattaroli wrote:
> The new DRM color format property allows userspace to request a specific
> color format on a connector. In turn, this fills the connector state's
> color_format member to switch color formats.
>
> Make drm_bridges consider the color_format set in the connector state
> during the atomic bridge check. Specifically, reject any output bus
> formats that do not correspond to the requested color format.
>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
> drivers/gpu/drm/drm_bridge.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index 8f355df883d8..8aac9747f35e 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -1052,6 +1052,47 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> return ret;
> }
>
> +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
> +{
> + if (fmt == DRM_COLOR_FORMAT_AUTO)
> + return true;
> +
> + switch (bus_fmt) {
> + case MEDIA_BUS_FMT_FIXED:
> + return true;
> + case MEDIA_BUS_FMT_RGB888_1X24:
> + case MEDIA_BUS_FMT_RGB101010_1X30:
> + case MEDIA_BUS_FMT_RGB121212_1X36:
> + case MEDIA_BUS_FMT_RGB161616_1X48:
> + return fmt == DRM_COLOR_FORMAT_RGB444;
> + case MEDIA_BUS_FMT_YUV8_1X24:
> + case MEDIA_BUS_FMT_YUV10_1X30:
> + case MEDIA_BUS_FMT_YUV12_1X36:
> + case MEDIA_BUS_FMT_YUV16_1X48:
> + return fmt == DRM_COLOR_FORMAT_YCBCR444;
> + case MEDIA_BUS_FMT_UYVY8_1X16:
> + case MEDIA_BUS_FMT_VYUY8_1X16:
> + case MEDIA_BUS_FMT_YUYV8_1X16:
> + case MEDIA_BUS_FMT_YVYU8_1X16:
> + case MEDIA_BUS_FMT_UYVY10_1X20:
> + case MEDIA_BUS_FMT_YUYV10_1X20:
> + case MEDIA_BUS_FMT_VYUY10_1X20:
> + case MEDIA_BUS_FMT_YVYU10_1X20:
> + case MEDIA_BUS_FMT_UYVY12_1X24:
> + case MEDIA_BUS_FMT_VYUY12_1X24:
> + case MEDIA_BUS_FMT_YUYV12_1X24:
> + case MEDIA_BUS_FMT_YVYU12_1X24:
> + return fmt == DRM_COLOR_FORMAT_YCBCR422;
> + case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> + case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> + case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> + case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> + return fmt == DRM_COLOR_FORMAT_YCBCR420;
> + default:
> + return false;
> + }
> +}
> +
> /*
> * This function is called by &drm_atomic_bridge_chain_check() just before
> * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
> @@ -1137,6 +1178,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
> }
>
> for (i = 0; i < num_out_bus_fmts; i++) {
> + if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
> + ret = -ENOTSUPP;
> + continue;
> + }
Sorry, I'm struggling a bit to understand how this would work if a bridge both supports the bus
format selection and HDMI state helpers? Can you expand on it?
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 04/17] drm/bridge: Act on the DRM color format property
2025-12-09 14:27 ` Maxime Ripard
@ 2025-12-11 19:34 ` Nicolas Frattaroli
2025-12-12 9:50 ` Maxime Ripard
0 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-12-11 19:34 UTC (permalink / raw)
To: Maxime Ripard
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
On Tuesday, 9 December 2025 15:27:28 Central European Standard Time Maxime Ripard wrote:
> Hi,
>
> On Fri, Nov 28, 2025 at 10:05:40PM +0100, Nicolas Frattaroli wrote:
> > The new DRM color format property allows userspace to request a specific
> > color format on a connector. In turn, this fills the connector state's
> > color_format member to switch color formats.
> >
> > Make drm_bridges consider the color_format set in the connector state
> > during the atomic bridge check. Specifically, reject any output bus
> > formats that do not correspond to the requested color format.
> >
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > ---
> > drivers/gpu/drm/drm_bridge.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 45 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > index 8f355df883d8..8aac9747f35e 100644
> > --- a/drivers/gpu/drm/drm_bridge.c
> > +++ b/drivers/gpu/drm/drm_bridge.c
> > @@ -1052,6 +1052,47 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> > return ret;
> > }
> >
> > +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
> > +{
> > + if (fmt == DRM_COLOR_FORMAT_AUTO)
> > + return true;
> > +
> > + switch (bus_fmt) {
> > + case MEDIA_BUS_FMT_FIXED:
> > + return true;
> > + case MEDIA_BUS_FMT_RGB888_1X24:
> > + case MEDIA_BUS_FMT_RGB101010_1X30:
> > + case MEDIA_BUS_FMT_RGB121212_1X36:
> > + case MEDIA_BUS_FMT_RGB161616_1X48:
> > + return fmt == DRM_COLOR_FORMAT_RGB444;
> > + case MEDIA_BUS_FMT_YUV8_1X24:
> > + case MEDIA_BUS_FMT_YUV10_1X30:
> > + case MEDIA_BUS_FMT_YUV12_1X36:
> > + case MEDIA_BUS_FMT_YUV16_1X48:
> > + return fmt == DRM_COLOR_FORMAT_YCBCR444;
> > + case MEDIA_BUS_FMT_UYVY8_1X16:
> > + case MEDIA_BUS_FMT_VYUY8_1X16:
> > + case MEDIA_BUS_FMT_YUYV8_1X16:
> > + case MEDIA_BUS_FMT_YVYU8_1X16:
> > + case MEDIA_BUS_FMT_UYVY10_1X20:
> > + case MEDIA_BUS_FMT_YUYV10_1X20:
> > + case MEDIA_BUS_FMT_VYUY10_1X20:
> > + case MEDIA_BUS_FMT_YVYU10_1X20:
> > + case MEDIA_BUS_FMT_UYVY12_1X24:
> > + case MEDIA_BUS_FMT_VYUY12_1X24:
> > + case MEDIA_BUS_FMT_YUYV12_1X24:
> > + case MEDIA_BUS_FMT_YVYU12_1X24:
> > + return fmt == DRM_COLOR_FORMAT_YCBCR422;
> > + case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> > + case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> > + case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> > + case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> > + return fmt == DRM_COLOR_FORMAT_YCBCR420;
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > /*
> > * This function is called by &drm_atomic_bridge_chain_check() just before
> > * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
> > @@ -1137,6 +1178,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
> > }
> >
> > for (i = 0; i < num_out_bus_fmts; i++) {
> > + if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
> > + ret = -ENOTSUPP;
> > + continue;
> > + }
>
> Sorry, I'm struggling a bit to understand how this would work if a bridge both supports the bus
> format selection and HDMI state helpers? Can you expand on it?
I have very little idea of whether this makes conceptual sense. The
hope is that by working backwards from the last bridge and only
accepting either fixed formats or something that corresponds to
the target color format, we don't claim that a setup can do a
colour format if the whole bridge chain isn't able to do it.
Of course, format conversions along the bridge chain where one
input format can be converted to a set of output formats by some
bridge will throw a massive wrench into this. And this is all
assuming that the bus format is in any way related to the color
format that will be sent out on the wire.
In practice, I don't have any hardware where whatever counts as
a "bridge" is an actually more involved setup than just the TX
controller. I tried looking into getting a board with one of the
supported DSI-to-HDMI bridge chips so I can at least test how it
would work in such a scenario, and I got one, but I'd need to make
my own flat flex PCB to adapt it to the pinout of my SBC's DSI
port.
So yeah I don't know how it's supposed to work, I just know this
works for the case I'm working with, and any more complex case
is literally unobtanium hardware which I'm not going to bother
blowing days on maybe making a cable for when I'm already touching
three different GPU drivers here and the intel-gfx-ci is screaming
into my inbox about vague failures in unrelated codepaths in its
native language, Klingon.
Which is all to say: is there a virtual drm bridge driver that
exists, where I can set what formats it supports on the input
and on the output, so that I can actually get a feel for how this
is conceptually supposed to work without needing special hardware?
Better yet: do you have a specific setup in mind where you know
this approach does not work?
>
> Maxime
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property
2025-12-09 14:16 ` Maxime Ripard
@ 2025-12-11 19:42 ` Nicolas Frattaroli
2025-12-12 9:20 ` Maxime Ripard
0 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-12-11 19:42 UTC (permalink / raw)
To: Maxime Ripard
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
On Tuesday, 9 December 2025 15:16:58 Central European Standard Time Maxime Ripard wrote:
> On Fri, Nov 28, 2025 at 10:05:41PM +0100, Nicolas Frattaroli wrote:
> > With the introduction of the "color format" DRM property, which allows
> > userspace to request a specific color format, the HDMI state helper
> > should implement this.
> >
> > Implement it by checking whether the property is set and set to
> > something other than auto. If so, pass the requested color format, and
> > otherwise set RGB.
> >
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > ---
> > drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
> > 1 file changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > index a561f124be99..5da956bdd68c 100644
> > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > @@ -649,11 +649,21 @@ hdmi_compute_config(const struct drm_connector *connector,
> > unsigned int max_bpc = clamp_t(unsigned int,
> > conn_state->max_bpc,
> > 8, connector->max_bpc);
> > + enum hdmi_colorspace hdmi_colorspace =
> > + drm_color_format_to_hdmi_colorspace(conn_state->color_format);
> > int ret;
> >
> > ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> > - HDMI_COLORSPACE_RGB);
> > + hdmi_colorspace);
> > if (ret) {
> > + /* If a color format was explicitly requested, don't fall back */
> > + if (conn_state->color_format) {
> > + drm_dbg_kms(connector->dev,
> > + "Explicitly set color format '%s' doesn't work.\n",
> > + drm_get_color_format_name(conn_state->color_format));
> > + return ret;
> > + }
> > +
>
> I think the following would be more readable:
>
>
> if (conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO) {
> enum hdmi_colorspace hdmi_colorspace =
> drm_color_format_to_hdmi_colorspace(conn_state->color_format);
>
> return hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc, hdmi_colorspace)
> }
>
> ret = ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> HDMI_COLORSPACE_RGB);
>
> ...
I think I get what you mean: if conn_state->color_format is set, return
directly, instead of bailing out in the fallback path. I can do that.
However, `conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO`
is redundant now as of v5 since DRM_COLOR_FORMAT_AUTO is 0 (and
I use its falsy nature in many other places, and don't intend to
stop doing that).
>
> Maxime
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid
2025-12-09 14:18 ` Maxime Ripard
@ 2025-12-11 19:59 ` Nicolas Frattaroli
2025-12-12 9:29 ` Maxime Ripard
0 siblings, 1 reply; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-12-11 19:59 UTC (permalink / raw)
To: Maxime Ripard
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
On Tuesday, 9 December 2025 15:18:25 Central European Standard Time Maxime Ripard wrote:
> On Fri, Nov 28, 2025 at 10:05:42PM +0100, Nicolas Frattaroli wrote:
> > drm_hdmi_connector_mode_valid assumes modes are only valid if they work
> > with RGB. The reality is more complex however: YCbCr 4:2:0
> > chroma-subsampled modes only require half the pixel clock that the same
> > mode would require in RGB.
> >
> > This leads to drm_hdmi_connector_mode_valid rejecting perfectly valid
> > 420-only modes.
> >
> > Fix this by checking whether the mode is 420-only first. If so, then
> > proceed by checking it with HDMI_COLORSPACE_YUV420 so long as the
> > connector has legalized 420, otherwise error out. If the mode is not
> > 420-only, check with RGB as was previously always the case.
> >
> > Fixes: 47368ab437fd ("drm/display: hdmi: add generic mode_valid helper")
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > ---
> > drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
> > 1 file changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > index 5da956bdd68c..1800e00b30c5 100644
> > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > @@ -892,8 +892,18 @@ drm_hdmi_connector_mode_valid(struct drm_connector *connector,
> > const struct drm_display_mode *mode)
> > {
> > unsigned long long clock;
> > + enum hdmi_colorspace fmt;
> > +
> > + if (drm_mode_is_420_only(&connector->display_info, mode)) {
> > + if (connector->ycbcr_420_allowed)
> > + fmt = HDMI_COLORSPACE_YUV420;
> > + else
> > + return MODE_NO_420;
> > + } else {
> > + fmt = HDMI_COLORSPACE_RGB;
> > + }
> >
> > - clock = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
> > + clock = drm_hdmi_compute_mode_clock(mode, 8, fmt);
>
> I agree on principle, but we need to have a test for this.
I'd like to change `drm_mode_is_420_only` to `drm_mode_is_420` in
the next revision, and modify the control flow to work correctly
in this case, because rejecting 420-also modes on the basis that
we can't do them in RGB isn't correct either.
But my concern with adding yet more tests is that I found this bug
in a function unrelated to the series while adding tests you asked
for, because the tests relied on this function to not be broken as
part of the test setup. Yes, I was not be able to get any 4:2:0
modes on the test connector in the kunit tests because
drm_hdmi_connector_mode_valid helpfully discarded all of them.
So now I am wondering whether adding yet more tests will uncover
more bugs in functions unrelated to implementing the "color format"
property, that were only called because the new test required them
to set up some test fixture. And then I have to add another fix and
another test to this series, rinse and repeat.
Can we just agree that I am not going to expand the scope of this
series any further? If you want me to send a follow-up series that
adds tests to some of the hdmi state helper functions, then I can
do that, but I don't want to do it as a precondition for the 17
other patches in this series to get merged.
>
> Maxime
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format property
2025-11-28 21:05 ` [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format property Nicolas Frattaroli
@ 2025-12-12 9:19 ` Maxime Ripard
2025-12-12 20:28 ` Nicolas Frattaroli
0 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2025-12-12 9:19 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
[-- Attachment #1: Type: text/plain, Size: 6008 bytes --]
On Fri, Nov 28, 2025 at 10:05:53PM +0100, Nicolas Frattaroli wrote:
> Add some KUnit tests to check the color_format property is working as
> expected with the HDMI state helper.
>
> The added tests check that AUTO results in RGB, and the YCBCR modes
> result in the corresponding YUV modes. An additional test ensures that
> only DRM_COLOR_FORMAT_AUTO falls back to YUV420 with a YUV420-only mode,
> and RGB errors out instead, while explicitly asking for YUV420 still
> works.
>
> This requires exporting hdmi_compute_config, so that it is accessible
> from the tests.
>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
> drivers/gpu/drm/display/drm_hdmi_state_helper.c | 3 +-
> drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 +++++++++++++++++++++
> include/drm/display/drm_hdmi_state_helper.h | 4 +
> 3 files changed, 115 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> index 1800e00b30c5..e86fb837ceaf 100644
> --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> @@ -641,7 +641,7 @@ hdmi_compute_format_bpc(const struct drm_connector *connector,
> return -EINVAL;
> }
>
> -static int
> +int
> hdmi_compute_config(const struct drm_connector *connector,
> struct drm_connector_state *conn_state,
> const struct drm_display_mode *mode)
> @@ -680,6 +680,7 @@ hdmi_compute_config(const struct drm_connector *connector,
>
> return ret;
> }
> +EXPORT_SYMBOL(hdmi_compute_config);
I don't think we need to export hdmi_compute_config directly, and if we
do, it shouldn't be named that way.
The rest of the tests in the suite manage to test everything fine
without exporting it. Is there any reason you can't do it for these
tests?
> static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
> struct drm_connector_state *conn_state)
> diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
> index 8bd412735000..e7050cd9cb12 100644
> --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
> @@ -55,6 +55,23 @@ static struct drm_display_mode *find_preferred_mode(struct drm_connector *connec
> return preferred;
> }
>
> +static struct drm_display_mode *find_420_only_mode(struct drm_connector *connector)
> +{
> + struct drm_device *drm = connector->dev;
> + struct drm_display_mode *mode;
> +
> + mutex_lock(&drm->mode_config.mutex);
> + list_for_each_entry(mode, &connector->modes, head) {
> + if (drm_mode_is_420_only(&connector->display_info, mode)) {
> + mutex_unlock(&drm->mode_config.mutex);
> + return mode;
> + }
> + }
> + mutex_unlock(&drm->mode_config.mutex);
> +
> + return NULL;
> +}
> +
> static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
> const void *edid, size_t edid_len)
> {
> @@ -1999,6 +2016,95 @@ static void drm_test_check_disable_connector(struct kunit *test)
> drm_modeset_acquire_fini(&ctx);
> }
>
> +struct color_format_test_param {
> + enum drm_color_format fmt;
> + enum hdmi_colorspace expected;
> + const char *desc;
> +};
> +
> +/* Test that AUTO results in RGB, and explicit choices result in those */
We need a bit more details. Which EDID are you using, with which monitor
capabilities?
IIRC, we already have tests to make sure that the fallback happens and
only when it's supposed to. We just need to make sure we have asserts on
the property being auto for those.
This means we only need to test the !auto values, but we need to test it
both ways: that when the property is set and the display supports it,
the format chosen is indeed the one we asked for, but also that when the
property is set but the display doesn't support it, we get an error.
> +static void drm_test_check_hdmi_color_format(struct kunit *test)
> +{
> + const struct color_format_test_param *param = test->param_value;
> + struct drm_atomic_helper_connector_hdmi_priv *priv;
> + struct drm_connector_state *conn_state;
> + struct drm_display_info *info;
> + struct drm_display_mode *preferred;
> + int ret;
> +
> + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
> + BIT(HDMI_COLORSPACE_RGB) |
> + BIT(HDMI_COLORSPACE_YUV422) |
> + BIT(HDMI_COLORSPACE_YUV420) |
> + BIT(HDMI_COLORSPACE_YUV444),
> + 12,
> + &dummy_connector_hdmi_funcs,
> + test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz);
> + KUNIT_ASSERT_NOT_NULL(test, priv);
> +
> + conn_state = priv->connector.state;
> + info = &priv->connector.display_info;
> + conn_state->color_format = param->fmt;
> + KUNIT_ASSERT_TRUE(test, priv->connector.ycbcr_420_allowed);
> +
> + preferred = find_preferred_mode(&priv->connector);
> + KUNIT_ASSERT_TRUE(test, drm_mode_is_420(info, preferred));
> +
> + ret = hdmi_compute_config(&priv->connector, conn_state, preferred);
> + KUNIT_EXPECT_EQ(test, ret, 0);
> + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, param->expected);
> +}
> +
> +static const struct color_format_test_param hdmi_color_format_params[] = {
> + { DRM_COLOR_FORMAT_AUTO, HDMI_COLORSPACE_RGB, "AUTO -> RGB" },
> + { DRM_COLOR_FORMAT_YCBCR422, HDMI_COLORSPACE_YUV422, "YCBCR422 -> YUV422" },
> + { DRM_COLOR_FORMAT_YCBCR420, HDMI_COLORSPACE_YUV420, "YCBCR420 -> YUV420" },
> + { DRM_COLOR_FORMAT_YCBCR444, HDMI_COLORSPACE_YUV444, "YCBCR444 -> YUV444" },
> + { DRM_COLOR_FORMAT_RGB444, HDMI_COLORSPACE_RGB, "RGB -> RGB" },
> +};
> +
> +KUNIT_ARRAY_PARAM_DESC(check_hdmi_color_format,
> + hdmi_color_format_params, desc);
> +
> +
> +/* Test that AUTO falls back to YUV420, and that RGB does not, but YUV420 works */
Same thing, the description needs to be improved here.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property
2025-12-11 19:42 ` Nicolas Frattaroli
@ 2025-12-12 9:20 ` Maxime Ripard
0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2025-12-12 9:20 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
[-- Attachment #1: Type: text/plain, Size: 3003 bytes --]
On Thu, Dec 11, 2025 at 08:42:00PM +0100, Nicolas Frattaroli wrote:
> On Tuesday, 9 December 2025 15:16:58 Central European Standard Time Maxime Ripard wrote:
> > On Fri, Nov 28, 2025 at 10:05:41PM +0100, Nicolas Frattaroli wrote:
> > > With the introduction of the "color format" DRM property, which allows
> > > userspace to request a specific color format, the HDMI state helper
> > > should implement this.
> > >
> > > Implement it by checking whether the property is set and set to
> > > something other than auto. If so, pass the requested color format, and
> > > otherwise set RGB.
> > >
> > > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > > ---
> > > drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
> > > 1 file changed, 11 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > index a561f124be99..5da956bdd68c 100644
> > > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > @@ -649,11 +649,21 @@ hdmi_compute_config(const struct drm_connector *connector,
> > > unsigned int max_bpc = clamp_t(unsigned int,
> > > conn_state->max_bpc,
> > > 8, connector->max_bpc);
> > > + enum hdmi_colorspace hdmi_colorspace =
> > > + drm_color_format_to_hdmi_colorspace(conn_state->color_format);
> > > int ret;
> > >
> > > ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> > > - HDMI_COLORSPACE_RGB);
> > > + hdmi_colorspace);
> > > if (ret) {
> > > + /* If a color format was explicitly requested, don't fall back */
> > > + if (conn_state->color_format) {
> > > + drm_dbg_kms(connector->dev,
> > > + "Explicitly set color format '%s' doesn't work.\n",
> > > + drm_get_color_format_name(conn_state->color_format));
> > > + return ret;
> > > + }
> > > +
> >
> > I think the following would be more readable:
> >
> >
> > if (conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO) {
> > enum hdmi_colorspace hdmi_colorspace =
> > drm_color_format_to_hdmi_colorspace(conn_state->color_format);
> >
> > return hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc, hdmi_colorspace)
> > }
> >
> > ret = ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> > HDMI_COLORSPACE_RGB);
> >
> > ...
>
> I think I get what you mean: if conn_state->color_format is set, return
> directly, instead of bailing out in the fallback path. I can do that.
Yes
> However, `conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO`
> is redundant now as of v5 since DRM_COLOR_FORMAT_AUTO is 0 (and
> I use its falsy nature in many other places, and don't intend to
> stop doing that).
Ok, that makes sense.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid
2025-12-11 19:59 ` Nicolas Frattaroli
@ 2025-12-12 9:29 ` Maxime Ripard
0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2025-12-12 9:29 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
[-- Attachment #1: Type: text/plain, Size: 3929 bytes --]
On Thu, Dec 11, 2025 at 08:59:14PM +0100, Nicolas Frattaroli wrote:
> On Tuesday, 9 December 2025 15:18:25 Central European Standard Time Maxime Ripard wrote:
> > On Fri, Nov 28, 2025 at 10:05:42PM +0100, Nicolas Frattaroli wrote:
> > > drm_hdmi_connector_mode_valid assumes modes are only valid if they work
> > > with RGB. The reality is more complex however: YCbCr 4:2:0
> > > chroma-subsampled modes only require half the pixel clock that the same
> > > mode would require in RGB.
> > >
> > > This leads to drm_hdmi_connector_mode_valid rejecting perfectly valid
> > > 420-only modes.
> > >
> > > Fix this by checking whether the mode is 420-only first. If so, then
> > > proceed by checking it with HDMI_COLORSPACE_YUV420 so long as the
> > > connector has legalized 420, otherwise error out. If the mode is not
> > > 420-only, check with RGB as was previously always the case.
> > >
> > > Fixes: 47368ab437fd ("drm/display: hdmi: add generic mode_valid helper")
> > > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > > ---
> > > drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
> > > 1 file changed, 11 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > index 5da956bdd68c..1800e00b30c5 100644
> > > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > @@ -892,8 +892,18 @@ drm_hdmi_connector_mode_valid(struct drm_connector *connector,
> > > const struct drm_display_mode *mode)
> > > {
> > > unsigned long long clock;
> > > + enum hdmi_colorspace fmt;
> > > +
> > > + if (drm_mode_is_420_only(&connector->display_info, mode)) {
> > > + if (connector->ycbcr_420_allowed)
> > > + fmt = HDMI_COLORSPACE_YUV420;
> > > + else
> > > + return MODE_NO_420;
> > > + } else {
> > > + fmt = HDMI_COLORSPACE_RGB;
> > > + }
> > >
> > > - clock = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
> > > + clock = drm_hdmi_compute_mode_clock(mode, 8, fmt);
> >
> > I agree on principle, but we need to have a test for this.
>
> I'd like to change `drm_mode_is_420_only` to `drm_mode_is_420` in
> the next revision, and modify the control flow to work correctly
> in this case, because rejecting 420-also modes on the basis that
> we can't do them in RGB isn't correct either.
>
> But my concern with adding yet more tests is that I found this bug
> in a function unrelated to the series while adding tests you asked
> for, because the tests relied on this function to not be broken as
> part of the test setup. Yes, I was not be able to get any 4:2:0
> modes on the test connector in the kunit tests because
> drm_hdmi_connector_mode_valid helpfully discarded all of them.
>
> So now I am wondering whether adding yet more tests will uncover
> more bugs in functions unrelated to implementing the "color format"
> property, that were only called because the new test required them
> to set up some test fixture. And then I have to add another fix and
> another test to this series, rinse and repeat.
>
> Can we just agree that I am not going to expand the scope of this
> series any further? If you want me to send a follow-up series that
> adds tests to some of the hdmi state helper functions, then I can
> do that, but I don't want to do it as a precondition for the 17
> other patches in this series to get merged.
But it is a precondition. See
https://docs.kernel.org/gpu/drm-internals.html#kunit-coverage-rules
You're adding code to a port of DRM that is covered by tests already,
and are fixing a hole in that test coverage. We must add a test to close
that hole too.
Now, if you want to take that fix out of your series and work on those
tests, fine, but we'll still need them.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 04/17] drm/bridge: Act on the DRM color format property
2025-12-11 19:34 ` Nicolas Frattaroli
@ 2025-12-12 9:50 ` Maxime Ripard
2025-12-12 14:45 ` Nicolas Frattaroli
0 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2025-12-12 9:50 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
[-- Attachment #1: Type: text/plain, Size: 6611 bytes --]
On Thu, Dec 11, 2025 at 08:34:22PM +0100, Nicolas Frattaroli wrote:
> On Tuesday, 9 December 2025 15:27:28 Central European Standard Time Maxime Ripard wrote:
> > On Fri, Nov 28, 2025 at 10:05:40PM +0100, Nicolas Frattaroli wrote:
> > > The new DRM color format property allows userspace to request a specific
> > > color format on a connector. In turn, this fills the connector state's
> > > color_format member to switch color formats.
> > >
> > > Make drm_bridges consider the color_format set in the connector state
> > > during the atomic bridge check. Specifically, reject any output bus
> > > formats that do not correspond to the requested color format.
> > >
> > > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > > ---
> > > drivers/gpu/drm/drm_bridge.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 45 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > > index 8f355df883d8..8aac9747f35e 100644
> > > --- a/drivers/gpu/drm/drm_bridge.c
> > > +++ b/drivers/gpu/drm/drm_bridge.c
> > > @@ -1052,6 +1052,47 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> > > return ret;
> > > }
> > >
> > > +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
> > > +{
> > > + if (fmt == DRM_COLOR_FORMAT_AUTO)
> > > + return true;
> > > +
> > > + switch (bus_fmt) {
> > > + case MEDIA_BUS_FMT_FIXED:
> > > + return true;
> > > + case MEDIA_BUS_FMT_RGB888_1X24:
> > > + case MEDIA_BUS_FMT_RGB101010_1X30:
> > > + case MEDIA_BUS_FMT_RGB121212_1X36:
> > > + case MEDIA_BUS_FMT_RGB161616_1X48:
> > > + return fmt == DRM_COLOR_FORMAT_RGB444;
> > > + case MEDIA_BUS_FMT_YUV8_1X24:
> > > + case MEDIA_BUS_FMT_YUV10_1X30:
> > > + case MEDIA_BUS_FMT_YUV12_1X36:
> > > + case MEDIA_BUS_FMT_YUV16_1X48:
> > > + return fmt == DRM_COLOR_FORMAT_YCBCR444;
> > > + case MEDIA_BUS_FMT_UYVY8_1X16:
> > > + case MEDIA_BUS_FMT_VYUY8_1X16:
> > > + case MEDIA_BUS_FMT_YUYV8_1X16:
> > > + case MEDIA_BUS_FMT_YVYU8_1X16:
> > > + case MEDIA_BUS_FMT_UYVY10_1X20:
> > > + case MEDIA_BUS_FMT_YUYV10_1X20:
> > > + case MEDIA_BUS_FMT_VYUY10_1X20:
> > > + case MEDIA_BUS_FMT_YVYU10_1X20:
> > > + case MEDIA_BUS_FMT_UYVY12_1X24:
> > > + case MEDIA_BUS_FMT_VYUY12_1X24:
> > > + case MEDIA_BUS_FMT_YUYV12_1X24:
> > > + case MEDIA_BUS_FMT_YVYU12_1X24:
> > > + return fmt == DRM_COLOR_FORMAT_YCBCR422;
> > > + case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> > > + case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> > > + case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> > > + case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> > > + return fmt == DRM_COLOR_FORMAT_YCBCR420;
> > > + default:
> > > + return false;
> > > + }
> > > +}
> > > +
> > > /*
> > > * This function is called by &drm_atomic_bridge_chain_check() just before
> > > * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
> > > @@ -1137,6 +1178,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
> > > }
> > >
> > > for (i = 0; i < num_out_bus_fmts; i++) {
> > > + if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
> > > + ret = -ENOTSUPP;
> > > + continue;
> > > + }
> >
> > Sorry, I'm struggling a bit to understand how this would work if a bridge both supports the bus
> > format selection and HDMI state helpers? Can you expand on it?
>
> I have very little idea of whether this makes conceptual sense.
.. I wasn't asking you if it makes sense, I was asking you to explain
how you wanted it to work.
> The hope is that by working backwards from the last bridge and only
> accepting either fixed formats or something that corresponds to the
> target color format, we don't claim that a setup can do a colour
> format if the whole bridge chain isn't able to do it.
>
> Of course, format conversions along the bridge chain where one
> input format can be converted to a set of output formats by some
> bridge will throw a massive wrench into this. And this is all
> assuming that the bus format is in any way related to the color
> format that will be sent out on the wire.
I'm not really concerned about this. As we move more and more bridges to
the state helpers, we can always fix it, but it needs at the very least
to document how you envision the whole thing to work, and ideally have
bunch of tests to make sure it still does.
> In practice, I don't have any hardware where whatever counts as
> a "bridge" is an actually more involved setup than just the TX
> controller. I tried looking into getting a board with one of the
> supported DSI-to-HDMI bridge chips so I can at least test how it
> would work in such a scenario, and I got one, but I'd need to make
> my own flat flex PCB to adapt it to the pinout of my SBC's DSI
> port.
>
> So yeah I don't know how it's supposed to work, I just know this
> works for the case I'm working with, and any more complex case
> is literally unobtanium hardware which I'm not going to bother
> blowing days on maybe making a cable for when I'm already touching
> three different GPU drivers here and the intel-gfx-ci is screaming
> into my inbox about vague failures in unrelated codepaths in its
> native language, Klingon.
That's uncalled for.
> Which is all to say: is there a virtual drm bridge driver that
> exists, where I can set what formats it supports on the input
> and on the output, so that I can actually get a feel for how this
> is conceptually supposed to work without needing special hardware?
If your question is "do we have a way to replicate and test an arbitrary
setup to check how it behaves?", then yes, we do, it's what we're doing
in kunit. But you don't seem too fond of those.
> Better yet: do you have a specific setup in mind where you know
> this approach does not work?
Look. I was asking a genuine question. If you want to get all defensive
about it, go ahead. But sending a series implementing something with a
lot of history, complex interactions, etc. and then expecting it to be a
breeze that will get merged in a few revisions is not going to work.
Pushing back when asked to follow our documented rules, or being
dismissive when asked design questions is not going to help you push
this forward. If anything, and because it's complex, the more tests you
add the better because we A) know it works in a specific set of cases,
and B) know it will still work going forward.
I'm sure you know what you're doing, but so do we.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 04/17] drm/bridge: Act on the DRM color format property
2025-12-12 9:50 ` Maxime Ripard
@ 2025-12-12 14:45 ` Nicolas Frattaroli
0 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-12-12 14:45 UTC (permalink / raw)
To: Maxime Ripard
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, amd-gfx,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
intel-gfx, intel-xe
On Friday, 12 December 2025 10:50:26 Central European Standard Time Maxime Ripard wrote:
> On Thu, Dec 11, 2025 at 08:34:22PM +0100, Nicolas Frattaroli wrote:
> > On Tuesday, 9 December 2025 15:27:28 Central European Standard Time Maxime Ripard wrote:
> > > On Fri, Nov 28, 2025 at 10:05:40PM +0100, Nicolas Frattaroli wrote:
> > > > The new DRM color format property allows userspace to request a specific
> > > > color format on a connector. In turn, this fills the connector state's
> > > > color_format member to switch color formats.
> > > >
> > > > Make drm_bridges consider the color_format set in the connector state
> > > > during the atomic bridge check. Specifically, reject any output bus
> > > > formats that do not correspond to the requested color format.
> > > >
> > > > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > > > ---
> > > > drivers/gpu/drm/drm_bridge.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> > > > 1 file changed, 45 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > > > index 8f355df883d8..8aac9747f35e 100644
> > > > --- a/drivers/gpu/drm/drm_bridge.c
> > > > +++ b/drivers/gpu/drm/drm_bridge.c
> > > > @@ -1052,6 +1052,47 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> > > > return ret;
> > > > }
> > > >
> > > > +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
> > > > +{
> > > > + if (fmt == DRM_COLOR_FORMAT_AUTO)
> > > > + return true;
> > > > +
> > > > + switch (bus_fmt) {
> > > > + case MEDIA_BUS_FMT_FIXED:
> > > > + return true;
> > > > + case MEDIA_BUS_FMT_RGB888_1X24:
> > > > + case MEDIA_BUS_FMT_RGB101010_1X30:
> > > > + case MEDIA_BUS_FMT_RGB121212_1X36:
> > > > + case MEDIA_BUS_FMT_RGB161616_1X48:
> > > > + return fmt == DRM_COLOR_FORMAT_RGB444;
> > > > + case MEDIA_BUS_FMT_YUV8_1X24:
> > > > + case MEDIA_BUS_FMT_YUV10_1X30:
> > > > + case MEDIA_BUS_FMT_YUV12_1X36:
> > > > + case MEDIA_BUS_FMT_YUV16_1X48:
> > > > + return fmt == DRM_COLOR_FORMAT_YCBCR444;
> > > > + case MEDIA_BUS_FMT_UYVY8_1X16:
> > > > + case MEDIA_BUS_FMT_VYUY8_1X16:
> > > > + case MEDIA_BUS_FMT_YUYV8_1X16:
> > > > + case MEDIA_BUS_FMT_YVYU8_1X16:
> > > > + case MEDIA_BUS_FMT_UYVY10_1X20:
> > > > + case MEDIA_BUS_FMT_YUYV10_1X20:
> > > > + case MEDIA_BUS_FMT_VYUY10_1X20:
> > > > + case MEDIA_BUS_FMT_YVYU10_1X20:
> > > > + case MEDIA_BUS_FMT_UYVY12_1X24:
> > > > + case MEDIA_BUS_FMT_VYUY12_1X24:
> > > > + case MEDIA_BUS_FMT_YUYV12_1X24:
> > > > + case MEDIA_BUS_FMT_YVYU12_1X24:
> > > > + return fmt == DRM_COLOR_FORMAT_YCBCR422;
> > > > + case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> > > > + case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> > > > + case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> > > > + case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> > > > + return fmt == DRM_COLOR_FORMAT_YCBCR420;
> > > > + default:
> > > > + return false;
> > > > + }
> > > > +}
> > > > +
> > > > /*
> > > > * This function is called by &drm_atomic_bridge_chain_check() just before
> > > > * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
> > > > @@ -1137,6 +1178,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
> > > > }
> > > >
> > > > for (i = 0; i < num_out_bus_fmts; i++) {
> > > > + if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
> > > > + ret = -ENOTSUPP;
> > > > + continue;
> > > > + }
> > >
> > > Sorry, I'm struggling a bit to understand how this would work if a bridge both supports the bus
> > > format selection and HDMI state helpers? Can you expand on it?
> >
> > I have very little idea of whether this makes conceptual sense.
>
> .. I wasn't asking you if it makes sense, I was asking you to explain
> how you wanted it to work.
>
> > The hope is that by working backwards from the last bridge and only
> > accepting either fixed formats or something that corresponds to the
> > target color format, we don't claim that a setup can do a colour
> > format if the whole bridge chain isn't able to do it.
> >
> > Of course, format conversions along the bridge chain where one
> > input format can be converted to a set of output formats by some
> > bridge will throw a massive wrench into this. And this is all
> > assuming that the bus format is in any way related to the color
> > format that will be sent out on the wire.
>
> I'm not really concerned about this. As we move more and more bridges to
> the state helpers, we can always fix it, but it needs at the very least
> to document how you envision the whole thing to work, and ideally have
> bunch of tests to make sure it still does.
Where should I document the intended behavior? A code comment here is
probably not visible to people implementing new bridge drivers, so I
imagine there's a place in the docs?
On the drm-kms docs page, I see:
Note that currently the bridge chaining and interactions with
connectors and panels are still in-flux and not really fully
sorted out yet.
Which means maybe adding a sub-heading for DRM bridge there might
make sense.
For a complete solution, it should probably do a graph traversal
starting from the last bridge's output format, and then looking
to reach the first bridge output format in the chain in any way
possible over a DAG where edges connect from input formats of
the next bridge to the output formats of the previous bridge,
and the output format of each bridge connects to whichever
of its input formats can convert to this output format.
Here's a diagram of what I mean:
.-----------------------------------.
| SoC Video Processor |
|-----------------------------------|
| out rgb | out yuv444 | out yuv420 |
'---------|------------|------------'
^
|
.---------|------.
| in rgb | |
|---------| MIPI |
| ^ | DSI |
| | | TX |
|---------| |
| out rgb | |
'---------|------'
^
|
'----------.
|
.----------|---------|-----------|----------------------------.
| | in rgb | in yuv444 | | |
|----------|---------|-----------|---------------| BOB'S |
| ^ ^ ^ ^ | BARGAIN |
| | | | '--------------. | MIPI DSI |
| .---------' | '----. | | TO HDMI |
| | .--' | | | BRIDGE |
|---------|------------|------------|------------| |
| out rgb | out yuv444 | out yuv422 | out yuv420 | |
'---------|------------|------------|------------|------------'
^ ^ ^
| | |
.---------|------------|------------.
| in rgb | in yuv444 | in yuv422 |
|-----------------------------------|
| HDMI CONNECTOR |
'-----------------------------------'
In this case, the MIPI DSI to HDMI bridge isn't very good so it can
only convert YUV444 to YUV422 and YUV420, despite being able to
convert RGB to YUV444 as well. The important bit is that there is
a path back from "out yuv444" on the "HDMI CONNECTOR" all the way
to the "SoC Video Processor", even though the processor's only going
to be outputting RGB. So setting color_format to yuv444 should be
possible in this case.
My current code doesn't handle this case. It only works if bridges
that convert can convert to any of their output formats regardless
of the input format. Additionally, I don't think I'd have a good
time if the SoC's video output processor sets the bus format to
"fixed", because if everyone along the chain says they can do
fixed formats then the output is going to claim it can do anything,
which isn't the case.
>
> > In practice, I don't have any hardware where whatever counts as
> > a "bridge" is an actually more involved setup than just the TX
> > controller. I tried looking into getting a board with one of the
> > supported DSI-to-HDMI bridge chips so I can at least test how it
> > would work in such a scenario, and I got one, but I'd need to make
> > my own flat flex PCB to adapt it to the pinout of my SBC's DSI
> > port.
> >
> > So yeah I don't know how it's supposed to work, I just know this
> > works for the case I'm working with, and any more complex case
> > is literally unobtanium hardware which I'm not going to bother
> > blowing days on maybe making a cable for when I'm already touching
> > three different GPU drivers here and the intel-gfx-ci is screaming
> > into my inbox about vague failures in unrelated codepaths in its
> > native language, Klingon.
>
> That's uncalled for.
>
> > Which is all to say: is there a virtual drm bridge driver that
> > exists, where I can set what formats it supports on the input
> > and on the output, so that I can actually get a feel for how this
> > is conceptually supposed to work without needing special hardware?
>
> If your question is "do we have a way to replicate and test an arbitrary
> setup to check how it behaves?", then yes, we do, it's what we're doing
> in kunit. But you don't seem too fond of those.
Okay, I will look into virtual bridge tests in kunit.
>
> > Better yet: do you have a specific setup in mind where you know
> > this approach does not work?
>
> Look. I was asking a genuine question. If you want to get all defensive
> about it, go ahead. But sending a series implementing something with a
> lot of history, complex interactions, etc. and then expecting it to be a
> breeze that will get merged in a few revisions is not going to work.
>
> Pushing back when asked to follow our documented rules, or being
> dismissive when asked design questions is not going to help you push
> this forward. If anything, and because it's complex, the more tests you
> add the better because we A) know it works in a specific set of cases,
> and B) know it will still work going forward.
>
> I'm sure you know what you're doing, but so do we.
I worked under the assumption that the general vagueness of the
questions were part of some elaborate dt-bindings-esque hazing
ritual, and not that I was literally the first person to try and
specify how drm bridge bus format selection should work. I apologise
for my tone in light of that.
I'm not convinced unit tests that test whether a single pre-defined
mode is valid, as the existing mode_valid one does, have any value
though. I'll comply however and add another with a yuv420-only mode,
and another with a yuv420-also mode. My criticism is that in a
scenario like this where "working" vs "broken" is highly dependent
on the result based on the input data, the coverage of taken code
branches is mostly irrelevant, and the real information comes from
comprehensive testing of a wide set of inputs with attention paid
to edge cases, verifying that they match the expected outputs.
Kind regards,
Nicolas Frattaroli
>
> Maxime
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format property
2025-12-12 9:19 ` Maxime Ripard
@ 2025-12-12 20:28 ` Nicolas Frattaroli
0 siblings, 0 replies; 33+ messages in thread
From: Nicolas Frattaroli @ 2025-12-12 20:28 UTC (permalink / raw)
To: Maxime Ripard, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, kernel, intel-gfx,
intel-xe
On Friday, 12 December 2025 10:19:13 Central European Standard Time Maxime Ripard wrote:
> On Fri, Nov 28, 2025 at 10:05:53PM +0100, Nicolas Frattaroli wrote:
> > Add some KUnit tests to check the color_format property is working as
> > expected with the HDMI state helper.
> >
> > The added tests check that AUTO results in RGB, and the YCBCR modes
> > result in the corresponding YUV modes. An additional test ensures that
> > only DRM_COLOR_FORMAT_AUTO falls back to YUV420 with a YUV420-only mode,
> > and RGB errors out instead, while explicitly asking for YUV420 still
> > works.
> >
> > This requires exporting hdmi_compute_config, so that it is accessible
> > from the tests.
> >
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> > ---
> > drivers/gpu/drm/display/drm_hdmi_state_helper.c | 3 +-
> > drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 +++++++++++++++++++++
> > include/drm/display/drm_hdmi_state_helper.h | 4 +
> > 3 files changed, 115 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > index 1800e00b30c5..e86fb837ceaf 100644
> > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > @@ -641,7 +641,7 @@ hdmi_compute_format_bpc(const struct drm_connector *connector,
> > return -EINVAL;
> > }
> >
> > -static int
> > +int
> > hdmi_compute_config(const struct drm_connector *connector,
> > struct drm_connector_state *conn_state,
> > const struct drm_display_mode *mode)
> > @@ -680,6 +680,7 @@ hdmi_compute_config(const struct drm_connector *connector,
> >
> > return ret;
> > }
> > +EXPORT_SYMBOL(hdmi_compute_config);
>
> I don't think we need to export hdmi_compute_config directly, and if we
> do, it shouldn't be named that way.
>
> The rest of the tests in the suite manage to test everything fine
> without exporting it. Is there any reason you can't do it for these
> tests?
The only function that calls hdmi_compute_config is the exported
drm_atomic_helper_connector_hdmi_check. While I can write tests around
drm_atomic_helper_connector_hdmi_check, it'll mean I'll have structure
the tests differently, and will accidentally test a lot of other things
as well, because it derives other state from the config and has a lot
more error paths. So checking that hdmi_compute_config fails as expected
won't be possible anymore, just that "_connector_hdmi_check fails.
I will rewrite the tests to do this since that appears to be the way
to do this, but I'll need to read up on the atomic state APIs and the
helper functions I've been using so far a bit to make sure I'm not
writing something broken here.
I do share your concerns about exporting this function though, I didn't
like doing it either. It is a side effect of unit testing not being a
first-class citizen of the C language I guess, but maybe it is better
to do this as an end-to-end test of the exported function rather than
just part of the implementation anyway.
> [...]
For everything I didn't directly reply to, assume I'll address it in
the next revision with no further sobbing to convey from my side.
Kind regards,
Nicolas Frattaroli
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2025-12-12 20:28 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-28 21:05 [PATCH v5 00/17] Add new general DRM property "color format" Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 01/17] drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 02/17] drm: Add new general DRM property "color format" Nicolas Frattaroli
2025-12-09 14:11 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 03/17] drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE Nicolas Frattaroli
2025-12-09 14:12 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 04/17] drm/bridge: Act on the DRM color format property Nicolas Frattaroli
2025-12-09 14:27 ` Maxime Ripard
2025-12-11 19:34 ` Nicolas Frattaroli
2025-12-12 9:50 ` Maxime Ripard
2025-12-12 14:45 ` Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color format DRM property Nicolas Frattaroli
2025-12-09 14:16 ` Maxime Ripard
2025-12-11 19:42 ` Nicolas Frattaroli
2025-12-12 9:20 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling in mode_valid Nicolas Frattaroli
2025-12-09 14:18 ` Maxime Ripard
2025-12-11 19:59 ` Nicolas Frattaroli
2025-12-12 9:29 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 07/17] drm/i915: Implement the "color format" DRM property Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 08/17] drm/amdgpu: Implement " Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 09/17] drm/rockchip: Add YUV422 output mode constants for VOP2 Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 10/17] drm/rockchip: vop2: Fix YUV444 output Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 11/17] drm/rockchip: vop2: Add RK3576 to the RG swap special case Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 12/17] drm/rockchip: vop2: Recognise 10/12-bit YUV422 as YUV formats Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 13/17] drm/rockchip: vop2: Set correct output format for RK3576 YUV422 Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 14/17] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 15/17] drm/rockchip: dw_hdmi_qp: Set supported_formats platdata Nicolas Frattaroli
2025-11-28 21:05 ` [PATCH v5 16/17] drm/connector: Register color format property on HDMI connectors Nicolas Frattaroli
2025-12-09 14:22 ` Maxime Ripard
2025-11-28 21:05 ` [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format property Nicolas Frattaroli
2025-12-12 9:19 ` Maxime Ripard
2025-12-12 20:28 ` Nicolas Frattaroli
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).