From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 603A42D63F6; Mon, 16 Feb 2026 13:02:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246965; cv=pass; b=VAhDHfy2cBmJFabYrwek8UwR0yhVkqalYkCQHn4Ve9jRjtmMC+sT/FueqOf7YWEyaSKoPg/9tt4fCF3YnliZrwamey6+fFrZ1LvT58VjLuCia3xjbUweRJGzMI8r7Tx5w9PR4H4tEFDmh/jV0lxb2klOe9ClwogAF9fPdZQEBIE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246965; c=relaxed/simple; bh=NFondsDQ0hWFa8TjIDEK+znsqzFDtuf71ClJf1bwM0E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hzosetEZOxp1wvW9mYO8BWiZTZWbjW2KuZJndQzBm2vthuZ66xKNPxePG+YaB52d96Mds9998Nu6WsiPb2QjEiXLV0E4S4V5WJ7mLlm+X6Ynqe/Y/ZvLmHWWGj888K2eIMIqXU9rElkySub4sZMuqF9ZAnpfly/9UK9Cd9T/ofQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=XV++WV77; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="XV++WV77" ARC-Seal: i=1; a=rsa-sha256; t=1771246908; cv=none; d=zohomail.com; s=zohoarc; b=PUg9XPHq9tlDtYY08V8VS65c7SMplaU94ZnHHgp4VEpLUfuERE9d4blVkDCoUfBu7gmaQzB8aSZIacdmrmGPpz8+wr1FoOA9VR0NAbFL1iEi51+d9Q4HzFj6wZO65n6epMdMK/w1IS4ao/H1Vkt6fK/8OoQodkryr3q1Tc/jGeM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246908; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ocgvj144ox473HVw3OzpKSQwBrz1+ydErGS9mpLqcwI=; b=VoGXtpPGfMscs1D9+dnUM1SMEp5FVyE8e8z2Dwc33kfYV3cTHWGpUp9vSW6IilxeEQfTpcH1uwaBP+a6JqGmpiKbYSUcfzH0XogR0qACVH7x53qL/86DjljDtlW6VM9ZOC/O/11qX5DnKeCKX7yyXvVQAHgFZ/uZRBGru08Omp4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246908; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=Ocgvj144ox473HVw3OzpKSQwBrz1+ydErGS9mpLqcwI=; b=XV++WV770yx+WNog9Vn6oDiAuencbbWHXjEgEG7N9zuHXB1h6ZilPByCMsMU5fjU uemr7429IHMxiO7K5Y0HkxxSCWkGXT/ECGSGsguPlCiyNzXMl2TjPoWg/RDY8Lv6A52 yxY4IZjpEu6JDj8V7pzUUtqnupxs0xXFesvs6Z8I= Received: by mx.zohomail.com with SMTPS id 1771246906640653.8907133675959; Mon, 16 Feb 2026 05:01:46 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:15 +0100 Subject: [PATCH v8 01/20] drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-1-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Werner Sembach , Andri Yngvason X-Mailer: b4 0.14.3 From: Werner Sembach 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 Signed-off-by: Andri Yngvason Tested-by: Andri Yngvason Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gp= u/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 47749ccc9c43..0db787ff24f3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6704,12 +6704,9 @@ static void fill_stream_properties_from_drm_display_= mode( timing_out->v_border_top =3D 0; timing_out->v_border_bottom =3D 0; /* TODO: un-hardcode */ - if (drm_mode_is_420_only(info, mode_in) - && stream->signal =3D=3D SIGNAL_TYPE_HDMI_TYPE_A) - timing_out->pixel_encoding =3D 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) || + (aconnector && aconnector->force_yuv420_output && + drm_mode_is_420_also(info, mode_in))) timing_out->pixel_encoding =3D PIXEL_ENCODING_YCBCR420; else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR4= 22) && aconnector --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E1DFD2BE641; Mon, 16 Feb 2026 13:02:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246970; cv=pass; b=WSrhPyZhwBm6ojeMGGpqnbg5JvmHkOrjkj61ZkhMHd3BvB5ygz6pFhCqUKyl2dKQdBLVAdrYHwVw8xfLeUt88NNWELY2yf1yDkZjO0y9JlFICJDuxGZXQLLqDJpHGdzEpRQPsAZC6GP3ACSLyi28OjQhZ8g1nvKpypiQpO3DymE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246970; c=relaxed/simple; bh=G5EB/JrjdDGdsbJB+8xhgjQI48BX6t8mS2rV4O8FeL4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Kql+kjkPP7OjUPwY1LRlsZcpoX0rVbiAUnGAwVrtnCZXIu6WYPALe/r3hf6dqJjy7MfRVZTcR+rEc1RhSLt0ogGBRzGM8t5rEvPOHgbji9TYyzFxkGUt2W1Axblal5DhmfUdSXK1kQT+llD6sTpQMLa3B5CmNgoMXOGsZr0WaQI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=gsRUxu55; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="gsRUxu55" ARC-Seal: i=1; a=rsa-sha256; t=1771246914; cv=none; d=zohomail.com; s=zohoarc; b=AMo6WBYEpMgctUkglUdG0t37FONImJvnai/6ROufkrrjU1kIkNhXE8U66C3IdzdClzPb94XOHcMNStTrVBMMWVscGFIrCchSjHypg0XMp76z9uuO1rvlLrUAkmTk/6pxQ4jY646BYoELyDQbvVDEgilsZA/01H2YRyWUAsBt7Dw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246914; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=egI2vOd+e7jczz93AAA0Dkn6/dXLEC62HRgN8Xs+Co4=; b=ZBKYOAG2xuff1YU7OByWC1ilUWcUbd1pgKRmLeYrxgEZKQCHtx7hX7n2+di5AozrOutyh3vLUf6bnuHVQClBcriRfdVuTOBu/+1feB0NL95VIvrBQHe5QVEeUnUSajiRCuBJRxM9BNrswWqr43E7GpdnmPSj7/uLnDc8EUs7S7w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246914; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=egI2vOd+e7jczz93AAA0Dkn6/dXLEC62HRgN8Xs+Co4=; b=gsRUxu55iODgnvOAbAh+j39H0R3UreuUcFeeVL7tPIUGfTs37XeHRccDC3p9EPCf oDd6vuw1Rbk/EkMToEmkTE9DdT9rbfa0Pp8vuSc3eQG2UzC3hM8p9eiBn09RvmC8G2d 0YwFDu/thZtIyWHy1SByHo1yFcl8Qibx4N89bFjk= Received: by mx.zohomail.com with SMTPS id 1771246914340650.4787889829954; Mon, 16 Feb 2026 05:01:54 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:16 +0100 Subject: [PATCH v8 02/20] drm: Add new general DRM property "color format" Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-2-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Andri Yngvason , Werner Sembach , Marius Vlad X-Mailer: b4 0.14.3 From: Andri Yngvason 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 Signed-off-by: Andri Yngvason Signed-off-by: Marius Vlad Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/drm_atomic_helper.c | 5 ++ drivers/gpu/drm/drm_atomic_uapi.c | 11 +++ drivers/gpu/drm/drm_connector.c | 150 ++++++++++++++++++++++++++++++++= ++++ include/drm/drm_connector.h | 116 ++++++++++++++++++++++++++-- 4 files changed, 277 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atom= ic_helper.c index d422f79b96db..d7e902ce5d2d 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -737,6 +737,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, if (old_connector_state->max_requested_bpc !=3D new_connector_state->max_requested_bpc) new_crtc_state->connectors_changed =3D true; + + if (old_connector_state->color_format !=3D + new_connector_state->color_format) + new_crtc_state->connectors_changed =3D true; + } =20 if (funcs->atomic_check) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic= _uapi.c index dc013a22bf26..907dd3374533 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -931,6 +931,15 @@ static int drm_atomic_connector_set_property(struct dr= m_connector *connector, state->privacy_screen_sw_state =3D val; } else if (property =3D=3D connector->broadcast_rgb_property) { state->hdmi.broadcast_rgb =3D val; + } else if (property =3D=3D connector->color_format_property) { + if (val >=3D DRM_COLOR_FORMAT_ENUM_NUM) { + drm_dbg_atomic(connector->dev, + "[CONNECTOR:%d:%s] unknown color format %llu\n", + connector->base.id, connector->name, val); + return -EINVAL; + } + + state->color_format =3D val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -1016,6 +1025,8 @@ drm_atomic_connector_get_property(struct drm_connecto= r *connector, *val =3D state->privacy_screen_sw_state; } else if (property =3D=3D connector->broadcast_rgb_property) { *val =3D state->hdmi.broadcast_rgb; + } else if (property =3D=3D connector->color_format_property) { + *val =3D 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_connecto= r.c index aec05adbc889..4d85add60d92 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1359,6 +1359,32 @@ static const char * const colorspace_names[] =3D { [DRM_MODE_COLORIMETRY_BT601_YCC] =3D "BT601_YCC", }; =20 +/** + * 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 mat= ch + * is found. + */ +const char *drm_get_color_format_name(enum drm_color_format_enum color_fmt) +{ + switch (color_fmt) { + case DRM_COLOR_FORMAT_ENUM_AUTO: + return "AUTO"; + case DRM_COLOR_FORMAT_ENUM_RGB444: + return "RGB"; + case DRM_COLOR_FORMAT_ENUM_YCBCR444: + return "YUV 4:4:4"; + case DRM_COLOR_FORMAT_ENUM_YCBCR422: + return "YUV 4:2:2"; + case DRM_COLOR_FORMAT_ENUM_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 @@ -1388,6 +1414,20 @@ static const u32 hdmi_colorspaces =3D BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) | BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER); =20 +/* already bit-shifted */ +static const u32 hdmi_colorformats =3D + DRM_COLOR_FORMAT_RGB444 | + DRM_COLOR_FORMAT_YCBCR444 | + DRM_COLOR_FORMAT_YCBCR422 | + DRM_COLOR_FORMAT_YCBCR420; + +/* already bit-shifted */ +static const u32 dp_colorformats =3D + 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/Color= imetry * Format Table 2-120 @@ -2649,6 +2689,97 @@ int drm_mode_create_hdmi_colorspace_property(struct = drm_connector *connector, } EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property); =20 +/** + * 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 =3D connector->dev; + struct drm_prop_enum_list enum_list[DRM_COLOR_FORMAT_ENUM_NUM]; + enum drm_color_format_enum fmt_e; + unsigned int len =3D 1; + unsigned int i =3D 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 & ~DRM_COLOR_FORMAT_ALL) { + 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 =3D drm_get_color_format_name(DRM_COLOR_FORMAT_ENUM_AUT= O); + enum_list[0].type =3D DRM_COLOR_FORMAT_ENUM_AUTO; + + while (supported_color_formats) { + fmt =3D BIT(i - 1); + if (supported_color_formats & fmt) { + supported_color_formats ^=3D fmt; + fmt_e =3D drm_color_format_to_enum(fmt); + if (fmt_e !=3D DRM_COLOR_FORMAT_ENUM_INVALID) { + enum_list[len].name =3D drm_get_color_format_name(fmt_e); + enum_list[len].type =3D fmt_e; + len++; + } else { + drm_warn(dev, + "Unknown supported format 0x%x on [CONNECTOR:%d:%s]\n", + fmt, connector->base.id, connector->name); + } + } + i++; + } + + connector->color_format_property =3D + 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. @@ -2866,6 +2997,25 @@ int drm_connector_attach_max_bpc_property(struct drm= _connector *connector, } EXPORT_SYMBOL(drm_connector_attach_max_bpc_property); =20 +/** + * 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 *conne= ctor) +{ + struct drm_property *prop =3D connector->color_format_property; + + drm_object_attach_property(&connector->base, prop, DRM_COLOR_FORMAT_ENUM_= 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 c18be8c19de0..18bd875b6918 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -556,6 +556,97 @@ enum drm_colorspace { DRM_MODE_COLORIMETRY_COUNT }; =20 +/** + * enum drm_color_format_enum - color model description + * + * This enum is a high-level description of the component makeup of the im= age + * data. It says nothing about how the components are ordered or how many = bits + * they take up (i.e. is unlike MEDIA_BUS_FMT\_ or DRM_FORMAT\_), but + * describes the type of components (Luminance-Chrominance vs. RGB) and the + * sub-sampling. + * + * &enum drm_color_format_enum makes statements about the same attribute of + * an image as the DRM_COLOR_FORMAT\_ bitfields do. Its purpose is to info= rm + * choices made by display protocol specific implementations when it comes= to + * translating it to e.g. &enum hdmi_colorspace or &enum dp_pixelformat, b= oth + * of which also describe the same attribute of the image at the same leve= l of + * specificity. + * + * In precise terms, this enum describes a color model. It makes no statem= ents + * about the primaries, gamma, or current phase of the moon used in conver= sion + * from one to the other. Furthermore, it also makes no statements about t= he + * order of components (e.g. RGB vs. BGR), their depth in bits, or their b= inary + * packing. + */ +enum drm_color_format_enum { + /** + * @DRM_COLOR_FORMAT_ENUM_AUTO: The choice of format is left up to the + * display protocol implementation. All implementations of the same + * display protocol (e.g. HDMI) are supposed to behave the same way, + * though display protocols may choose to behave differently compared to + * each other (e.g. HDMI's "AUTO" does not have to match DP's "AUTO"). + * + * Implementations may rely on @DRM_COLOR_FORMAT_ENUM_AUTO to be falsy. + */ + DRM_COLOR_FORMAT_ENUM_AUTO =3D 0, + + /** + * @DRM_COLOR_FORMAT_ENUM_RGB444: Image components are encoded as RGB + * values of equal resolution. + */ + DRM_COLOR_FORMAT_ENUM_RGB444, + + /** + * @DRM_COLOR_FORMAT_ENUM_YCBCR444: Image components are encoded as + * luminance and chrominance of equal resolution. + */ + DRM_COLOR_FORMAT_ENUM_YCBCR444, + + /** + * @DRM_COLOR_FORMAT_ENUM_YCBCR422: Image components are encoded as + * luminance and chrominance with the chrominance components having half + * the horizontal resolution. + */ + DRM_COLOR_FORMAT_ENUM_YCBCR422, + + /** + * @DRM_COLOR_FORMAT_ENUM_YCBCR420: Image components are encoded as + * luminance and chrominance with the chrominance components having half + * the horizontal and vertical resolution. + */ + DRM_COLOR_FORMAT_ENUM_YCBCR420, + + /** + * @DRM_COLOR_FORMAT_ENUM_NUM: The number of valid color format values + * in this enum. Itself not a valid color format. + */ + DRM_COLOR_FORMAT_ENUM_NUM, + + /** + * @DRM_COLOR_FORMAT_ENUM_INVALID: Error return value for conversion + * functions encountering unexpected inputs. + */ + DRM_COLOR_FORMAT_ENUM_INVALID =3D -EINVAL, +}; + +/* + * Constants for specifying bit masks for e.g. providing a list of support= ed + * color formats as a single integer. + */ +#define DRM_COLOR_FORMAT_RGB444 BIT(0) +#define DRM_COLOR_FORMAT_YCBCR444 BIT(1) +#define DRM_COLOR_FORMAT_YCBCR422 BIT(2) +#define DRM_COLOR_FORMAT_YCBCR420 BIT(3) + +/* + * Mask of all DRM_COLOR_FORMAT\_ constants. When adding new color formats, + * they must be part of this define. + */ +#define DRM_COLOR_FORMAT_ALL (DRM_COLOR_FORMAT_RGB444 | \ + DRM_COLOR_FORMAT_YCBCR444 | \ + DRM_COLOR_FORMAT_YCBCR422 | \ + DRM_COLOR_FORMAT_YCBCR420) + /** * enum drm_bus_flags - bus_flags info for &drm_display_info * @@ -699,11 +790,6 @@ struct drm_display_info { */ enum subpixel_order subpixel_order; =20 -#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 +1193,13 @@ struct drm_connector_state { */ enum drm_colorspace colorspace; =20 + /** + * @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_enum color_format; + /** * @writeback_job: Writeback job for writeback connectors * @@ -2105,6 +2198,12 @@ struct drm_connector { */ struct drm_property *colorspace_property; =20 + /** + * @color_format_property: Connector property to set the suitable + * color format supported by the sink. + */ + struct drm_property *color_format_property; + /** * @path_blob_ptr: * @@ -2507,6 +2606,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); =20 +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); @@ -2588,6 +2690,10 @@ bool drm_connector_has_possible_encoder(struct drm_c= onnector *connector, struct drm_encoder *encoder); const char *drm_get_colorspace_name(enum drm_colorspace colorspace); =20 +int drm_connector_attach_color_format_property(struct drm_connector *conne= ctor); + +const char *drm_get_color_format_name(enum drm_color_format_enum color_fmt= ); + /** * drm_for_each_connector_iter - connector_list iterator macro * @connector: &struct drm_connector pointer used as cursor --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1972D2BE641; Mon, 16 Feb 2026 13:02:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246965; cv=pass; b=pvVnM+HJ7QP4M5nZJTkS34eEJ8z6LGdoeLcj1QA0CMYyZY0xAh0aitx5Ej3ZJT7S5OJNvI8WGHb6N/W+wIXeMEG561bP6VRvAAOH2FGdeEoxLjASpiqIdAjKfPXmPbJTk5toRChXpZDa89rfJLVPMeMyYaKIaOkNCwImKNwNUAA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246965; c=relaxed/simple; bh=Lbdlk6GhhHTsc464Ci4AHXwR19aO0HurSyaZnD7z9kY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jZ2fGJ8Qc+CkMocfQ2YpZA0N8G3/DBI7lAlJH9KTFh/5Fd4uSGKxAKrple7pmuQpteDw9PSEabYc+iAGQmUwyx+5LfK33eZ6qxL4+oF8rRAVx7mVK71t2w6FSr2+Z4pfVo6lYAsrjfMmQAk/XTl1alBDVzNU/nufz7K+eZZ9wO4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=FpBVMtkJ; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="FpBVMtkJ" ARC-Seal: i=1; a=rsa-sha256; t=1771246923; cv=none; d=zohomail.com; s=zohoarc; b=eZVJThR2gA+t6hkkAUI5SiueBkenMCTQGNboTDOT65PQZMu3+zq00/VhZBiglKzBsk1jA2N07djIqRDFnII5j26Eu8F9DhZmFII2ZesM8ylBZJQFSb1iaYzRXJ9JnSUXARypRiFxyyc05s4RH8+nJYSuDOxeuaiNR+x0MZxyxcs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246923; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=E6/IL9T9r6JCufl0RYsNc7jJmCuMbPJaKhaRNoo53fQ=; b=KRAM4C9X2fTMr9MLZ2xbdRCP7NvnMxvBcYwYIrRrMnO1tuVg+DRiwOsRO1nUZ/z9d7GIFTl5aTm/ZMlA6caww4W/QcW6DK/JGiGJlN8bP7qjNM4MsMJXW4DbdcOoNjfpqLJqx7qLBjMFrVLNR61kz57mPiieoLytaA4mRXUtrK4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246923; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=E6/IL9T9r6JCufl0RYsNc7jJmCuMbPJaKhaRNoo53fQ=; b=FpBVMtkJwvPluuKs/sxzKjDlt1CbhDZFt4WkGb9BSe4LMlPQW1yoSMu69gTAt74y HpVAFcu5AdSRH1ubBHV+nepgFnJpdvIBDjRHU5DX4mp8uaN9D1PdaLLIxQ3qdSCjuJe 7weY5+F2NQaz25CVMfZb17kXtAL7ShwL1ChjauVc= Received: by mx.zohomail.com with SMTPS id 1771246921436134.4296104447676; Mon, 16 Feb 2026 05:02:01 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:17 +0100 Subject: [PATCH v8 03/20] drm: Add enum conversions for drm_color_format_enum Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-3-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Marius Vlad X-Mailer: b4 0.14.3 While the drm_color_format_enum enum and the hdmi_colorspace enum have similar values, they're not identical, and HDMI's enum is defined as per the HDMI standard. Meanwhile, each DRM_COLOR_FORMAT_* define has a corresponding drm_color_format_enum, which allows conversion from the bitshifted defines to the enum values. Implement conversion functions from DRM_COLOR_FORMAT bitshifted defines to drm_color_format_enum, and from hdmi_colorspace enum values to drm_color_format_enum enum values. In both conversions, an unexpected input results in a DRM_COLOR_FORMAT_ENUM_INVALID result. The functions are kept inline __pure to give the compiler maximum freedom to do as it pleases. Co-developed-by: Marius Vlad Signed-off-by: Marius Vlad Signed-off-by: Nicolas Frattaroli --- include/drm/drm_connector.h | 53 +++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 53 insertions(+) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 18bd875b6918..886defdd069b 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -2694,6 +2694,59 @@ int drm_connector_attach_color_format_property(struc= t drm_connector *connector); =20 const char *drm_get_color_format_name(enum drm_color_format_enum color_fmt= ); =20 +/** + * drm_color_format_to_enum - convert a single DRM_COLOR_FORMAT\_ to enum + * @fmt: One of the possible DRM_COLOR_FORMAT\_ values + * + * Converts a single DRM_COLOR_FORMAT\_ value to a corresponding + * &enum drm_color_format_enum value. Bitmasks of multiple DRM_COLOR_FORMA= T\_ + * values are not supported, as they would not map to a single enum value. + * + * Returns converted enum value on success, or %DRM_COLOR_FORMAT_ENUM_INVA= LID on + * failure. + */ +static inline enum drm_color_format_enum __pure +drm_color_format_to_enum(u32 fmt) +{ + switch (fmt) { + case DRM_COLOR_FORMAT_RGB444: + return DRM_COLOR_FORMAT_ENUM_RGB444; + case DRM_COLOR_FORMAT_YCBCR444: + return DRM_COLOR_FORMAT_ENUM_YCBCR444; + case DRM_COLOR_FORMAT_YCBCR422: + return DRM_COLOR_FORMAT_ENUM_YCBCR422; + case DRM_COLOR_FORMAT_YCBCR420: + return DRM_COLOR_FORMAT_ENUM_YCBCR420; + default: + return DRM_COLOR_FORMAT_ENUM_INVALID; + } +} + +/** + * drm_color_format_enum_from_hdmi_colorspace - convert hdmi_colorspace en= um to + * drm_color_format_enum + * @fmt: The &enum hdmi_colorspace to convert + * + * Returns the converted result on success, or %DRM_COLOR_FORMAT_ENUM_INVA= LID on + * failure. + */ +static inline enum drm_color_format_enum __pure +drm_color_format_enum_from_hdmi_colorspace(enum hdmi_colorspace fmt) +{ + switch (fmt) { + case HDMI_COLORSPACE_RGB: + return DRM_COLOR_FORMAT_ENUM_RGB444; + case HDMI_COLORSPACE_YUV444: + return DRM_COLOR_FORMAT_ENUM_YCBCR444; + case HDMI_COLORSPACE_YUV422: + return DRM_COLOR_FORMAT_ENUM_YCBCR422; + case HDMI_COLORSPACE_YUV420: + return DRM_COLOR_FORMAT_ENUM_YCBCR420; + default: + return DRM_COLOR_FORMAT_ENUM_INVALID; + } +} + /** * drm_for_each_connector_iter - connector_list iterator macro * @connector: &struct drm_connector pointer used as cursor --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-e107.zoho.com (sender4-pp-e107.zoho.com [136.143.188.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2A260301717; Mon, 16 Feb 2026 13:02:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.107 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246976; cv=pass; b=AOpvh2cGpovgf/fgeaF13+9a7GVBcW87G/hMxwJnAj05ColrNxfpePm9+U8SHF4HHNKmjR5PVlHQXvsEaylztUDOgWVRK7I8bgCZtuWbyX70pCgzTcBuI8w+yUi05v87vQzSbuqfCGV5e6Lo65AIji3e3nwBi/2vJ4pWEWOFxgo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246976; c=relaxed/simple; bh=+bQye9wW/XMvtx873NvBwFfx/uuvg68aj8e2RhPNcYg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Fm5nbZozRYFy6PUmDPV9ct5F98sPpkxKoNVQTn8BeeDssuuMkC0JkE1+tXgOS+vRpkjBvyPyEoTebl/0OTE2yXyJnuFSI3DbQgRIw8lAhgs7QqMgmb6/RN5IjCZ5iv4P1UMXHAyfFSio8WO/erR0/BVQdFAHfvysIY8Q2CT3QOc= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=gaxXP8Xn; arc=pass smtp.client-ip=136.143.188.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="gaxXP8Xn" ARC-Seal: i=1; a=rsa-sha256; t=1771246929; cv=none; d=zohomail.com; s=zohoarc; b=T06pjv0CfT4bVh0U3NXZON3T33KH29hxdIqPPYlzEV5CapQDNdriu+sxh+RX7VG4VUqkGoAkNxk2FlxXk8ARqf7JFoSrnb0qPxB/1kCQy4J7rMiqyDLsVqOjzANcLi8Yht8ZVCQmcrtls4eUAvy4sYLtZyOWG6wvUGcZZxkuzao= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246929; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ps/3KHfahzE4CA312vsVuNcKxzi74v58TBa5PtaiWoo=; b=WwZ83nOP+RxoAqjXsNj7A0Duic26PCxZoymUq17CsIlU3bXylgyLbrTqUStqrldK7FfG0vjCug/k0EsOK3ORDwLQDW5WLBLuppktWpbwnMoOUR0UoVHC7b3CqiijDPNTFJJtGWJH1ZAWBtcWepAxsB9z6QQyaAf9c+87QaUzfQw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246929; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=Ps/3KHfahzE4CA312vsVuNcKxzi74v58TBa5PtaiWoo=; b=gaxXP8XnBCk4o6tA7GWn/+ooa2ZFozNFTn+6S5YEsbywsF5vMdfjKB1PgsWrj3Ar VPrf0bMWie/UZYZWmuC+OVdwATgz1OQ7d241K1S8LRwYHQRpTPZUxjenc3Dwn6UHyyu Voasj9EAGNAV7NSFhu+aswo56LGLpFyVVQMBUlmo= Received: by mx.zohomail.com with SMTPS id 1771246928485527.7495564542533; Mon, 16 Feb 2026 05:02:08 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:18 +0100 Subject: [PATCH v8 04/20] drm/bridge: Act on the DRM color format property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-4-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 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. For bridges that represent HDMI bridges, rely on whatever format the HDMI logic set. Reject any output bus formats that do not correspond to the requested color format. Non-HDMI last bridges with DRM_COLOR_FORMAT_ENUM_AUTO set will end up choosing the first output format that functions to make a whole recursive bridge chain format selection succeed. Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/drm_bridge.c | 78 ++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 94864e05619d..36a5158f0554 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -1117,6 +1117,47 @@ static int select_bus_fmt_recursive(struct drm_bridg= e *first_bridge, return ret; } =20 +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_for= mat_enum fmt) +{ + if (fmt =3D=3D DRM_COLOR_FORMAT_ENUM_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 =3D=3D DRM_COLOR_FORMAT_ENUM_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 =3D=3D DRM_COLOR_FORMAT_ENUM_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 =3D=3D DRM_COLOR_FORMAT_ENUM_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 =3D=3D DRM_COLOR_FORMAT_ENUM_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. @@ -1160,6 +1201,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_br= idge *bridge, struct drm_encoder *encoder =3D bridge->encoder; struct drm_bridge_state *last_bridge_state; unsigned int i, num_out_bus_fmts =3D 0; + enum drm_color_format_enum fmt; u32 *out_bus_fmts; int ret =3D 0; =20 @@ -1201,13 +1243,47 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_= bridge *bridge, out_bus_fmts[0] =3D MEDIA_BUS_FMT_FIXED; } =20 + /* + * On HDMI connectors, use the output format chosen by whatever does the + * HDMI logic. For everyone else, just trust that the bridge out_bus_fmts + * are sorted by preference for %DRM_COLOR_FORMAT_AUTO, as + * bus_format_is_color_fmt() always returns true for AUTO. + */ + if (last_bridge->ops & DRM_BRIDGE_OP_HDMI) { + fmt =3D drm_color_format_enum_from_hdmi_colorspace(conn_state->hdmi.outp= ut_format); + if (fmt =3D=3D DRM_COLOR_FORMAT_ENUM_INVALID) { + ret =3D -EINVAL; + drm_dbg_kms(last_bridge->dev, + "Couldn't convert HDMI format to DRM format\n"); + goto out_free; + } + drm_dbg_kms(last_bridge->dev, "HDMI bridge requests format %s\n", + drm_get_color_format_name(fmt)); + } else { + fmt =3D conn_state->color_format; + drm_dbg_kms(last_bridge->dev, "Non-HDMI bridge requests format %s\n", + drm_get_color_format_name(fmt)); + } + for (i =3D 0; i < num_out_bus_fmts; i++) { + if (!bus_format_is_color_fmt(out_bus_fmts[i], fmt)) { + drm_dbg_kms(last_bridge->dev, + "Skipping bus format 0x%04x as it doesn't match %s\n", + out_bus_fmts[i], drm_get_color_format_name(fmt)); + ret =3D -ENOTSUPP; + continue; + } ret =3D select_bus_fmt_recursive(bridge, last_bridge, crtc_state, conn_state, out_bus_fmts[i]); - if (ret !=3D -ENOTSUPP) + if (ret !=3D -ENOTSUPP) { + drm_dbg_kms(last_bridge->dev, + "Found bridge chain ending with bus format 0x%04x\n", + out_bus_fmts[i]); break; + } } =20 +out_free: kfree(out_bus_fmts); =20 return ret; --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8C4B630E0C0; Mon, 16 Feb 2026 13:02:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246978; cv=pass; b=E9eEV3DgjOwpF1Bb8ZnSdJHReOmMwPlQhhuv3CUPdN3C+jZgNyoez0Iy48e5hG7yOzcfN6dhs9V2ofL25FVhr09AEdQEaaQMlY8frPUYneztLBl6NSnzdaqB8IMMEOB2hr6zW3/hUs+bMi/6CRlQJbT8cqBDo+qZ+0OpkPe/BX0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246978; c=relaxed/simple; bh=HVo/gqYIjhPprngYgHjDXS6TY/6XHs3wncu5CKB3chk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DZPtr4JNe5YGdfxJ2+0iw9W4YX+KDAet314NIneRL+fdA9gnlKjQBi0r5/8Jxj4xgnvts5bLOOQm49Ts+H5oIbWwU8aGOw3uZScOxwy2tnSmHPKwNuB89lv2MAZq8nU9MrXsX80fTVQRRc+VogTwCufsQA8XTqoTH0MfQ06J1pQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=SLYyzIpp; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="SLYyzIpp" ARC-Seal: i=1; a=rsa-sha256; t=1771246937; cv=none; d=zohomail.com; s=zohoarc; b=SjwFdSxGKe/Yd9BHGQsS2tFZh8sCy5jdJJfJk+Ceppp7nHriZgrhek6XQ4sm3y2GywsLm3xI9LrxjmT84T+EG6S6Dhd7Bvt1yyHF+LUNcuJLSxoOffoVLOVQ41TuWfdAgZ5XdI+guGlf0NQjaGyHV+sdFhTew01rYxgLBj4zTFY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246937; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=XJQUiMBk6drlEqyVcvn5t6omt1siA1VhQ5FW6igxkp4=; b=eVKZtrJF96IBY16fn+j3BvwdMnISN+2fju8tz43AAaPku9jYvp5E2z7c9me9YbwdEvdCzkTIaHi/ahzx6u6isF43V10hyRu3dFiAsvmoubfvHFj9WQkbAa562qd7Y4bjmuSw+UVzPPPjQvNaX5iTIlCK/AnPF+XLY4TeqZFrl0k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246937; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=XJQUiMBk6drlEqyVcvn5t6omt1siA1VhQ5FW6igxkp4=; b=SLYyzIpp/sDAePPdKa/wbGGQOZM9CfSx/pvjyQIgBSoN8Pxl3DqRdNaqJGUV/DNK Oihkj9X3YL8u24M5muBRHoLG6BheY3XHc86QPiVrI1DSNt6F0SwvOfLALVXVqmeX+Zq zZhN/9nItYLeiK66SX9pkaNyNMjk9eC6Qa2EgHFw= Received: by mx.zohomail.com with SMTPS id 1771246935363351.37459512313205; Mon, 16 Feb 2026 05:02:15 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:19 +0100 Subject: [PATCH v8 05/20] drm/display: hdmi-state-helper: Act on color format DRM property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-5-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 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 translating the requested drm_color_format_enum to an hdmi_colorspace enum value. Auto is translated to RGB, and a fallback to YUV420 is only performed if the original color format was auto. Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 28 +++++++++++++++++++++= ++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/= drm/display/drm_hdmi_state_helper.c index a1d16762ac7a..3ba752200984 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -649,10 +649,34 @@ hdmi_compute_config(const struct drm_connector *conne= ctor, unsigned int max_bpc =3D clamp_t(unsigned int, conn_state->max_bpc, 8, connector->max_bpc); + enum hdmi_colorspace fmt; int ret; =20 - ret =3D hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc, - HDMI_COLORSPACE_RGB); + switch (conn_state->color_format) { + case DRM_COLOR_FORMAT_ENUM_AUTO: + case DRM_COLOR_FORMAT_ENUM_RGB444: + fmt =3D HDMI_COLORSPACE_RGB; + break; + case DRM_COLOR_FORMAT_ENUM_YCBCR444: + fmt =3D HDMI_COLORSPACE_YUV444; + break; + case DRM_COLOR_FORMAT_ENUM_YCBCR422: + fmt =3D HDMI_COLORSPACE_YUV422; + break; + case DRM_COLOR_FORMAT_ENUM_YCBCR420: + fmt =3D HDMI_COLORSPACE_YUV420; + break; + default: + drm_dbg_kms(connector->dev, "HDMI does not support color format '%s'.\n", + drm_get_color_format_name(conn_state->color_format)); + return -EINVAL; + } + + ret =3D hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc, fmt= ); + + if (conn_state->color_format !=3D DRM_COLOR_FORMAT_ENUM_AUTO) + return ret; + if (ret) { if (connector->ycbcr_420_allowed) { ret =3D hdmi_compute_format_bpc(connector, conn_state, --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8C53330E0EF; Mon, 16 Feb 2026 13:02:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246979; cv=pass; b=SBT2CaHvGYR4v5tOOMXO78F0nR5R45+zvLGP/prstyBYIaKOHTNpQaF8Vfvpk67DVxjdKWMDQXhRz6H/5dOkjHZnFr1Eo8n9+fKUpJe3mKnF4lDrgirRHEstfvP/b5Kz8U49zFwLZaaPkWRaLNMdSF3qqTcehh6kPsafk9oBycE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771246979; c=relaxed/simple; bh=s/xNrrzmyfUxm/yLqr0JZ3JDVgvKplDoIPKNf4l1YTM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=b0C57igguYwwIA166RPctBN+Gs4L2PgRSAIsWmEkvfwZdkCW7K/mV4QG98iD43l47R2Lg8qCqdaxtwfH8OatmuI3bPkq8K+jJey9suiDOAVP8B5fEAkBHNzsRbQpzunZmrFot3nibCewPjPDcAbcEHL+g0heF5cFbrPk/LP9ekQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=KVQnQ9qN; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="KVQnQ9qN" ARC-Seal: i=1; a=rsa-sha256; t=1771246943; cv=none; d=zohomail.com; s=zohoarc; b=k7clRDs/eIBZgJQ5S9mtFM4BZsPkTzoJFLOjFZ4oY3BqCWhkexsq/7RSSVYh46SlteUahlk/4PJzhQZbO5y7Dmw9dvnDdRSG1VCrmCPHkzSU+BBFCBvWXHuw1+DCBVkvNnetGs7/eWDLzZIpq58DUM/7cLmNKwcID9c3Y/DEzss= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246943; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=goTuCsz9zd4JcRIwXM2LrskUyMJNYiEchG/iLKNBRSQ=; b=ZbrhbQksx9u0V0YJd+JJEsIqjcOwNUzJ7ipX2yfMSN7uwy3ZebwcxY2tndl4vRAIVe5khZDwAU411MFJO7tHt1AwfBVCwGtl9TWKbEpKzwmi4hilKY2SS4UJJSff3R6tVC8Eos7aFNQJ2SRQNZRV2DXJlLg+6fRMqsTxgXAA5kc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246943; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=goTuCsz9zd4JcRIwXM2LrskUyMJNYiEchG/iLKNBRSQ=; b=KVQnQ9qNTOtx9p/S5IgkAfkne6Xl1mo+vlHGEg20dNIH4MCwjq26qh40VHZ3YAUN 3tvJPnMPrGsb8i+CGgkABl8cqxnS66MCJrsvO+x4E29P0ubz38FsqqpkYcciqHDtB/N N8q9yjT0qyxFIYlcNWBM12hulxt6MParydheM6lw= Received: by mx.zohomail.com with SMTPS id 177124694222336.605069080808676; Mon, 16 Feb 2026 05:02:22 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:20 +0100 Subject: [PATCH v8 06/20] drm/display: hdmi-state-helper: Try subsampling in mode_valid Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-6-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 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 or 420-also modes. Fix this by checking whether the mode is 420-capable 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-capable, check with RGB as was previously always the case. Fixes: 47368ab437fd ("drm/display: hdmi: add generic mode_valid helper") Signed-off-by: Nicolas Frattaroli Reviewed-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 15 ++++++++++++++- 1 file changed, 14 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 3ba752200984..0975fcba83f3 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -912,8 +912,21 @@ drm_hdmi_connector_mode_valid(struct drm_connector *co= nnector, 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 =3D HDMI_COLORSPACE_YUV420; + else + return MODE_NO_420; + } else if (drm_mode_is_420_also(&connector->display_info, mode) && + connector->ycbcr_420_allowed) { + fmt =3D HDMI_COLORSPACE_YUV420; + } else { + fmt =3D HDMI_COLORSPACE_RGB; + } =20 - clock =3D drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); + clock =3D drm_hdmi_compute_mode_clock(mode, 8, fmt); if (!clock) return MODE_ERROR; =20 --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A59122F12C6; Mon, 16 Feb 2026 13:03:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247001; cv=pass; b=GbwJZhCcKW4AOA5lBVJlEdKx4YezZLopcKd+KppsZLa55M6kDTYbu3uzBOGlt5X+IQCCadpz4XxbZwaTrI4GhDhvRf4fLcFES9Au90E0s1GyxCZnQTsmePzPQ8cUC0HnB/jQ4UPXEFEVrH7P6FwD3boYCCWbNChebxt54Pki9Mw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247001; c=relaxed/simple; bh=iox1SOVHno1W1PYovA8+nnXupso3Es2NqrTioKt1Xbw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gfUo/PVmlJkOSA4ESIG1kc+2PswCxRUwDUy5IN4af1dte91T37AvdoVF7/XlOk4BxVC9QtMPN/AsUochWs72T0FUhUsftt8Swtq5y3l8ClZBO5q8x8HN/o1S76H6HHnyqirnKlCUornWYL4w+ZuNGQS13p/kQ0BGPZYPgrineUs= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=Z3jc+Rey; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="Z3jc+Rey" ARC-Seal: i=1; a=rsa-sha256; t=1771246951; cv=none; d=zohomail.com; s=zohoarc; b=TZX7JipaBl9pREKeJi0GdjGCOlZrW/i0hOUzGdyaDJ3vrnq89RtIKiPKtXRIaU9ynZxCIXcTsrynzmPpSrcWaiynWT8kmxDfaratBNjb47VHDDoqLl8Fob1ZTqFO5Grf75VXJFNrVsbW04DJNqYxEQ/RFOlOsJyvI7SOehIxqGw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246951; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=RerPC70g/9aetx3YG2UkkSsyUHQm6DHz8s9ZmqpdkF4=; b=eo6e/Yp0E9neIwIFBKhqkomMq2oKeAFwcBC90RkHPoLcoXr4c7AyTOdQl3HC3qyP2wGW/1gmGdHjiwdXMoGud74GvyGk9GpHn6Y8poCT0CqbqxGy2/nYUfbmmu9g12JFHhBdgXaqykKlfkNPrvdIoQo62vn/dHa8bpMUDG8L89c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246951; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=RerPC70g/9aetx3YG2UkkSsyUHQm6DHz8s9ZmqpdkF4=; b=Z3jc+ReyA4E80KE2pRqWLMwsqMBppR98zDCiNPcCPDnLy0Z9fW7bFAsVSmKIUKJ/ Ye3Zsjuyk5Q3e59pT1gctbIg43HRncneOovmcb3rltgdlGrReEy3q1l37zsb2JT+AS3 YAZAw7Kijgw9tdQMBxmAj25Rq7ULLWbBxO6ZxAps= Received: by mx.zohomail.com with SMTPS id 1771246949870725.7899809679819; Mon, 16 Feb 2026 05:02:29 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:21 +0100 Subject: [PATCH v8 07/20] drm/i915: Implement the "color format" DRM property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-7-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Werner Sembach , Andri Yngvason , Marius Vlad X-Mailer: b4 0.14.3 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 Signed-off-by: Werner Sembach Co-developed-by: Andri Yngvason Signed-off-by: Andri Yngvason Co-developed-by: Marius Vlad Signed-off-by: Marius Vlad Signed-off-by: Nicolas Frattaroli --- 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 | 58 +++++++++++++++++-= ---- drivers/gpu/drm/i915/display/intel_dp.h | 4 ++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 34 ++++++++++++- drivers/gpu/drm/i915/display/intel_hdmi.c | 57 +++++++++++++++---= --- 7 files changed, 152 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/d= rm/i915/display/intel_connector.c index 682bf1be350d..2d690e0400b5 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -38,6 +38,10 @@ #include "intel_hdcp.h" #include "intel_panel.h" =20 +static const u32 supported_colorformats =3D 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 =3D container_of(work, typeof(*connecto= r), @@ -321,6 +325,13 @@ intel_attach_dp_colorspace_property(struct drm_connect= or *connector) drm_connector_attach_colorspace_property(connector); } =20 +void +intel_attach_colorformat_property(struct drm_connector *connector) +{ + if (!drm_mode_create_color_format_property(connector, supported_colorform= ats)) + 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/d= rm/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_conne= ctor *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 *conn= ector); void intel_connector_cancel_modeset_retry_work(struct intel_connector *con= nector); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/g= pu/drm/i915/display/intel_display_types.h index e8e4af03a6a6..c230a545f95a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -2252,6 +2252,21 @@ to_intel_frontbuffer(struct drm_framebuffer *fb) return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL; } =20 +static inline __pure enum drm_color_format_enum +intel_output_format_to_drm_color_format(enum intel_output_format input) +{ + switch (input) { + case INTEL_OUTPUT_FORMAT_RGB: + return DRM_COLOR_FORMAT_ENUM_RGB444; + case INTEL_OUTPUT_FORMAT_YCBCR444: + return DRM_COLOR_FORMAT_ENUM_YCBCR444; + case INTEL_OUTPUT_FORMAT_YCBCR420: + return DRM_COLOR_FORMAT_ENUM_YCBCR420; + default: + return DRM_COLOR_FORMAT_ENUM_INVALID; + } +} + /* * 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 b5fe7d8ba586..bc89aa5fdf01 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1178,7 +1178,7 @@ dfp_can_convert(struct intel_dp *intel_dp, return false; } =20 -static enum intel_output_format +enum intel_output_format intel_dp_output_format(struct intel_connector *connector, enum intel_output_format sink_format) { @@ -3319,17 +3319,24 @@ intel_dp_compute_output_format(struct intel_encoder= *encoder, struct intel_connector *connector =3D intel_dp->attached_connector; const struct drm_display_info *info =3D &connector->base.display_info; const struct drm_display_mode *adjusted_mode =3D &crtc_state->hw.adjusted= _mode; - bool ycbcr_420_only; + enum drm_color_format_enum sink_format_drm; int ret; =20 - ycbcr_420_only =3D drm_mode_is_420_only(info, adjusted_mode); + if ((conn_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR420 && + drm_mode_is_420(info, adjusted_mode)) || + (conn_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_AUTO && + drm_mode_is_420_only(info, adjusted_mode))) + crtc_state->sink_format =3D INTEL_OUTPUT_FORMAT_YCBCR420; + else if (conn_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR444) + crtc_state->sink_format =3D INTEL_OUTPUT_FORMAT_YCBCR444; + else + crtc_state->sink_format =3D INTEL_OUTPUT_FORMAT_RGB; =20 - if (ycbcr_420_only && !connector->base.ycbcr_420_allowed) { + if (crtc_state->sink_format =3D=3D 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 =3D INTEL_OUTPUT_FORMAT_RGB; - } else { - crtc_state->sink_format =3D intel_dp_sink_format(connector, adjusted_mod= e); + "YCbCr 4:2:0 mode requested but unsupported by connector.\n"); + return -EINVAL; } =20 crtc_state->output_format =3D intel_dp_output_format(connector, crtc_stat= e->sink_format); @@ -3337,9 +3344,20 @@ intel_dp_compute_output_format(struct intel_encoder = *encoder, ret =3D intel_dp_compute_link_config(encoder, crtc_state, conn_state, respect_downstream_limits); if (ret) { - if (crtc_state->sink_format =3D=3D 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 =3D=3D 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; =20 crtc_state->sink_format =3D INTEL_OUTPUT_FORMAT_YCBCR420; @@ -3347,9 +3365,23 @@ intel_dp_compute_output_format(struct intel_encoder = *encoder, crtc_state->sink_format); ret =3D intel_dp_compute_link_config(encoder, crtc_state, conn_state, respect_downstream_limits); + if (ret) + return ret; } =20 - return ret; + sink_format_drm =3D intel_output_format_to_drm_color_format(crtc_state->s= ink_format); + if (sink_format_drm =3D=3D DRM_COLOR_FORMAT_ENUM_INVALID) + return -EINVAL; + + if (conn_state->color_format && conn_state->color_format !=3D 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; } =20 void @@ -6823,6 +6855,8 @@ intel_dp_add_properties(struct intel_dp *intel_dp, st= ruct drm_connector *_connec intel_attach_dp_colorspace_property(&connector->base); } =20 + 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); =20 diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915= /display/intel_dp.h index cbd7fcd3789f..99aa0048a6c2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -201,6 +201,10 @@ bool intel_dp_compute_config_limits(struct intel_dp *i= ntel_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); =20 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 29713075e413..5b2297674ba4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -706,6 +706,8 @@ static int mst_stream_compute_config(struct intel_encod= er *encoder, to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode =3D &pipe_config->hw.adjusted_mode; + const struct drm_display_info *info =3D + &connector->base.display_info; int num_joined_pipes; int ret =3D -EINVAL; =20 @@ -716,8 +718,31 @@ static int mst_stream_compute_config(struct intel_enco= der *encoder, if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; =20 - pipe_config->sink_format =3D INTEL_OUTPUT_FORMAT_RGB; - pipe_config->output_format =3D INTEL_OUTPUT_FORMAT_RGB; + if ((conn_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR420 && + drm_mode_is_420(info, adjusted_mode)) || + (conn_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_AUTO && + drm_mode_is_420_only(info, adjusted_mode))) { + pipe_config->sink_format =3D INTEL_OUTPUT_FORMAT_YCBCR420; + } else if (conn_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR444= ) { + pipe_config->sink_format =3D INTEL_OUTPUT_FORMAT_YCBCR444; + } else if (conn_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_AUTO || + conn_state->color_format =3D=3D DRM_COLOR_FORMAT_RGB444) { + pipe_config->sink_format =3D INTEL_OUTPUT_FORMAT_RGB; + } else { + drm_dbg_kms(display->drm, + "Requested format %s unsupported.\n", + drm_get_color_format_name(conn_state->color_format)); + return -EINVAL; + } + + if (pipe_config->sink_format =3D=3D 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 =3D intel_dp_output_format(connector, pipe_con= fig->sink_format); pipe_config->has_pch_encoder =3D false; =20 for_each_joiner_candidate(connector, adjusted_mode, num_joined_pipes) { @@ -1676,6 +1701,11 @@ static int mst_topology_add_connector_properties(str= uct intel_dp *intel_dp, if (connector->base.max_bpc_property) drm_connector_attach_max_bpc_property(&connector->base, 6, 12); =20 + connector->base.color_format_property =3D + 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); } =20 diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i9= 15/display/intel_hdmi.c index 05e898d10a2b..ff5ebf4b9508 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2270,30 +2270,57 @@ static int intel_hdmi_compute_output_format(struct = intel_encoder *encoder, struct intel_connector *connector =3D to_intel_connector(conn_state->conn= ector); const struct drm_display_mode *adjusted_mode =3D &crtc_state->hw.adjusted= _mode; const struct drm_display_info *info =3D &connector->base.display_info; - bool ycbcr_420_only =3D drm_mode_is_420_only(info, adjusted_mode); + enum drm_color_format_enum req_fmt =3D conn_state->color_format; + enum drm_color_format_enum sink_format_drm; int ret; =20 - crtc_state->sink_format =3D - intel_hdmi_sink_format(crtc_state, connector, ycbcr_420_only); - - if (ycbcr_420_only && crtc_state->sink_format !=3D INTEL_OUTPUT_FORMAT_YC= BCR420) { - 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 =3D INTEL_OUTPUT_FORMAT_RGB; - } + if (!req_fmt) + crtc_state->sink_format =3D + intel_hdmi_sink_format(crtc_state, connector, + drm_mode_is_420_only(info, adjusted_mode)); + else if (req_fmt =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR444) + crtc_state->sink_format =3D INTEL_OUTPUT_FORMAT_YCBCR444; + else + crtc_state->sink_format =3D + intel_hdmi_sink_format(crtc_state, connector, + req_fmt =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR420); =20 crtc_state->output_format =3D intel_hdmi_output_format(crtc_state); ret =3D intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_= limits); if (ret) { - if (crtc_state->sink_format =3D=3D 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 =3D=3D 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; =20 crtc_state->sink_format =3D INTEL_OUTPUT_FORMAT_YCBCR420; crtc_state->output_format =3D intel_hdmi_output_format(crtc_state); ret =3D intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream= _limits); + if (ret) + return ret; + } + + sink_format_drm =3D intel_output_format_to_drm_color_format(crtc_state->s= ink_format); + if (sink_format_drm =3D=3D DRM_COLOR_FORMAT_ENUM_INVALID) + return -EINVAL; + + if (req_fmt && req_fmt !=3D 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 =3D -EINVAL; } =20 return ret; @@ -2689,8 +2716,10 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_h= dmi, struct drm_connector *_ if (DISPLAY_VER(display) >=3D 10) drm_connector_attach_hdr_output_metadata_property(&connector->base); =20 - if (!HAS_GMCH(display)) + if (!HAS_GMCH(display)) { drm_connector_attach_max_bpc_property(&connector->base, 8, 12); + intel_attach_colorformat_property(&connector->base); + } } =20 /* --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B6FF52FF669; Mon, 16 Feb 2026 13:03:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247007; cv=pass; b=nRil7F4q426S2qoENTMSRCzmvnBRuf6uORaeLsfNeL5o8F+gQ4xw4bsfyiVYjblE/emH8OqH6m0+TDJcg6Gx5P57paV0c0BI3dUgiC+Ns+ZpF0T3USq0tFjOMzYt20k2PfW5ZyE7mYmdf2hZYWhJjoVYcAdv6TecyTxp7BEIM8s= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247007; c=relaxed/simple; bh=6mFN69Fi9UqOFeFl+tDYIgZNi4k0CVALSSvKM1vAP/o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KSw1MP1AfcdCKADftadnWjciR/4sIzWJPH3iIuqQBWy7Sj1Gz+tAf9Sbj4IpddscA3UVbrlAOE8Nrg2iKZqBC4R/Y1h+VpmD0ORvx+09/fgXCCJbWeYjc+HPE7gr0pmmvd9uW0pENR89hIDy/CboTBtHvujL6o8XuEkqM+URlEo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=VLPsNnCF; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="VLPsNnCF" ARC-Seal: i=1; a=rsa-sha256; t=1771246959; cv=none; d=zohomail.com; s=zohoarc; b=n3XO2lgay6t9xN+lJkB4yf7dYGqnTuGgJt6r6XAxcL9tSxp4E2SbwZdz+tR7Z9JiTLKfTAoWdYGKPGCe15HH+i/Y//+Ow/oGkhkFWi0JeBr3itAb1RTV+XM4LivLrtfdHOM5Wpy7IZRgfgMg+y9dzbunTxIIur7pFTOwFHSijjE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246959; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=ls+9lbbR6IRLb8BtqpinfauUYeJELiE55SB742as75o=; b=lCz+hLeY6ltHzS4wWoJAmanDYG/dcfQzpFvnUveUyPpQi7SzS3tSnKW78YLMi5M7H19HVlEBYx0up+QsHWZ5RMaJlNsp0qNXDiYA3/Xf70WCaT8dCVeQHKyQBNuwTcLORoLmYNqyV5Kuusw+4M5IUeAFTQIKdKVzZVWZfjpbIzg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246959; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=ls+9lbbR6IRLb8BtqpinfauUYeJELiE55SB742as75o=; b=VLPsNnCFmchFj1SinktyTqtUbhCmVObXXZi58KMRxD5xLl698bdK2UMGDuHwBNOJ IFpcVX63s4yPChdOVB7+eU7e/3GNYGw+fL9r0M7+1JaG6gRCyhm05Wfe9yV6wRNruwC k2VGctk9QFD6foXfVmGa9mL7rbs5Jo3DE1j2VFcw= Received: by mx.zohomail.com with SMTPS id 1771246957273548.7527543997456; Mon, 16 Feb 2026 05:02:37 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:22 +0100 Subject: [PATCH v8 08/20] drm/amdgpu: Implement "color format" DRM property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-8-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Werner Sembach , Andri Yngvason , Marius Vlad X-Mailer: b4 0.14.3 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 Signed-off-by: Werner Sembach Co-developed-by: Andri Yngvason Signed-off-by: Andri Yngvason Co-developed-by: Marius Vlad Signed-off-by: Marius Vlad Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 87 ++++++++++++++++++= +--- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 13 ++++ 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gp= u/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 0db787ff24f3..b0544ddc1ca7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6686,11 +6686,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 =3D dc_is_hdmi_signal(stream->signal) || dc_is_dp_sign= al(stream->signal); struct dc_crtc_timing *timing_out =3D &stream->timing; const struct drm_display_info *info =3D &connector->display_info; struct amdgpu_dm_connector *aconnector =3D NULL; struct hdmi_vendor_infoframe hv_frame; struct hdmi_avi_infoframe avi_frame; + bool want_420; + bool want_422; ssize_t err; =20 if (connector->connector_type !=3D DRM_MODE_CONNECTOR_WRITEBACK) @@ -6703,20 +6706,39 @@ static void fill_stream_properties_from_drm_display= _mode( timing_out->h_border_right =3D 0; timing_out->v_border_top =3D 0; timing_out->v_border_bottom =3D 0; - /* TODO: un-hardcode */ - if (drm_mode_is_420_only(info, mode_in) || - (aconnector && aconnector->force_yuv420_output && - drm_mode_is_420_also(info, mode_in))) + + want_420 =3D (aconnector && aconnector->force_yuv420_output) || + (connector_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR420); + want_422 =3D (aconnector && aconnector->force_yuv422_output) || + (connector_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_YCBCR422); + + if (drm_mode_is_420_only(info, mode_in) && (want_420 || !connector_state-= >color_format)) { timing_out->pixel_encoding =3D PIXEL_ENCODING_YCBCR420; - else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR4= 22) - && aconnector - && aconnector->force_yuv422_output) + } else if (drm_mode_is_420_also(info, mode_in) && want_420) { + timing_out->pixel_encoding =3D PIXEL_ENCODING_YCBCR420; + } else if ((info->color_formats & DRM_COLOR_FORMAT_ENUM_YCBCR422) + && want_422 && is_dp_or_hdmi) { timing_out->pixel_encoding =3D PIXEL_ENCODING_YCBCR422; - else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR4= 44) - && stream->signal =3D=3D SIGNAL_TYPE_HDMI_TYPE_A) + } else if (connector_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_YCB= CR444 && + (info->color_formats & DRM_COLOR_FORMAT_ENUM_YCBCR444) && is_dp_or_hd= mi) { timing_out->pixel_encoding =3D PIXEL_ENCODING_YCBCR444; - else + } else if ((connector_state->color_format =3D=3D DRM_COLOR_FORMAT_ENUM_RG= B444 || + !connector_state->color_format)) { timing_out->pixel_encoding =3D 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 =3D PIXEL_ENCODING_UNDEFINED; + else if (drm_mode_is_420_only(info, mode_in)) + timing_out->pixel_encoding =3D PIXEL_ENCODING_YCBCR420; + else + timing_out->pixel_encoding =3D PIXEL_ENCODING_RGB; + } =20 timing_out->timing_3d_format =3D TIMING_3D_FORMAT_NONE; timing_out->display_color_depth =3D convert_color_depth_from_display_info( @@ -8066,6 +8088,38 @@ static enum dc_status dm_validate_stream_and_context= (struct dc *dc, return dc_result; } =20 +static enum dc_status +dm_validate_stream_color_format(const struct drm_connector_state *drm_stat= e, + 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_ENUM_AUTO: + case DRM_COLOR_FORMAT_ENUM_RGB444: + encoding =3D PIXEL_ENCODING_RGB; + break; + case DRM_COLOR_FORMAT_ENUM_YCBCR444: + encoding =3D PIXEL_ENCODING_YCBCR444; + break; + case DRM_COLOR_FORMAT_ENUM_YCBCR422: + encoding =3D PIXEL_ENCODING_YCBCR422; + break; + case DRM_COLOR_FORMAT_ENUM_YCBCR420: + encoding =3D PIXEL_ENCODING_YCBCR420; + break; + default: + encoding =3D PIXEL_ENCODING_UNDEFINED; + break; + } + + return encoding =3D=3D 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, @@ -8112,6 +8166,9 @@ create_validate_stream_for_sink(struct drm_connector = *connector, if (dc_result =3D=3D DC_OK) dc_result =3D dm_validate_stream_and_context(adev->dm.dc, stream); =20 + if (dc_result =3D=3D DC_OK) + dc_result =3D dm_validate_stream_color_format(drm_state, stream); + if (dc_result !=3D DC_OK) { drm_dbg_kms(connector->dev, "Pruned mode %d x %d (clk %d) %s %s -- %s\n= ", drm_mode->hdisplay, @@ -8935,6 +8992,12 @@ static const u32 supported_colorspaces =3D BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) | BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); =20 +static const u32 supported_colorformats =3D + 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, @@ -9056,6 +9119,10 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_d= isplay_manager *dm, =20 if (adev->dm.hdcp_workqueue) drm_connector_attach_content_protection_property(&aconnector->base, tru= e); + + if (!drm_mode_create_color_format_property(&aconnector->base, + supported_colorformats)) + drm_connector_attach_color_format_property(&aconnector->base); } =20 if (connector_type =3D=3D 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 5e92eaa67aa3..a7b1274ead8d 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 @@ =20 #define PEAK_FACTOR_X1000 1006 =20 +static const u32 supported_colorformats =3D + 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); =20 + connector->color_format_property =3D 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 =3D master->base.vrr_capable_property; if (connector->vrr_capable_property) drm_connector_attach_vrr_capable_property(connector); --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B70C0301717; Mon, 16 Feb 2026 13:03:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247006; cv=pass; b=RCLLfJad7JWwll6IMpQfpdLK9bRHktgncQuOrTqcWcp1E8thKdUi1Uctj3wUAXsQiXP1QMGuLmDwVaKxNUGo7irbs0aXAnxWChQ3fX25VEb7eKOWH2c8pAPVG5oXtrBJxhdp159+RMPLrwqALfUo6jiEYipHj4ZuSQFAyFKjuVw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247006; c=relaxed/simple; bh=33Ww8J2K75Ej72XAJU8c8NggzCA+pSde82fd+km3Om4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WPrbrmOtOyjdN03jmCSWVeHl+vm7mZRPV2ELUaBqJSMlDUK2Io5aCdRv5vX//K8GEA8PZoiXEa1An4dwcKdFpf1r1Vm4BmLbe03RN8E4S9hHfizLRs11r747RiFmHcVK4R2X44MrNFvy8twJag+y11bpucgfEiaY3HBBkC9axdg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=QBMrnXVs; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="QBMrnXVs" ARC-Seal: i=1; a=rsa-sha256; t=1771246965; cv=none; d=zohomail.com; s=zohoarc; b=SWW3TCKoSTB7fLElOsmfM8i80CJiREHjo/Cn1yrYXmyeWINqZqPMjkz3WqhCmSNi3ONTrENLaPUK2YpzZNkN0uKzfDeiMGORVYApoidEMTOVu8HNUEVIeQylU+vGxI+WVRTIwXn34ggrgOAH0Nd0uEROh9A7w85DQmoo7TlxzSc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246965; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=I6mnIoMwQGSuHjHjLVfRnXnzAB6xS7ZmlkuOJOt+Ckg=; b=izuFGQqF/5ZOo1FWE3N3rO4vCt8GR0j2l8c1rZ5KYXF/xYmJ84BUBZB/NshSuNm9C7MDKmvqqIuMj+1Kb2ScY9jq4YVoK0rBBQUu1Is90stLV8iNfwQ58+xcTRtn24/JwDTpGVRwJGFOk5yRB4JweWgV5mTFp6KI7Kk1kQAdntI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246965; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=I6mnIoMwQGSuHjHjLVfRnXnzAB6xS7ZmlkuOJOt+Ckg=; b=QBMrnXVsbne4bSlbqEz0jZdUFWY6Cx7o86CagGi2DOL8r8GQYKd3uOkYD+eHceqK L9Y54JQuhbL+LJ/T/gG8RpcL+ofJ2mNwW2ukoQW/5zbKof6K/hm5OppyEWo9WAgwdxf RXb6Pu5jBpPZknOtC5GxKsFVHt2WHN2QL61ldSjU= Received: by mx.zohomail.com with SMTPS id 1771246964397536.3634160903135; Mon, 16 Feb 2026 05:02:44 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:23 +0100 Subject: [PATCH v8 09/20] drm/rockchip: Add YUV422 output mode constants for VOP2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-9-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Andy Yan X-Mailer: b4 0.14.3 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). Reviewed-by: Andy Yan Signed-off-by: Nicolas Frattaroli --- 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 =20 /* output flags */ #define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E2192D63F6; Mon, 16 Feb 2026 13:03:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247018; cv=pass; b=VLzec49qUpQ+OWRIwfRXv8vlwHoXCXZCZZF7C8VC2BIZ9S3ZqHjsvIOxbBzgEeSOT2O1es7re42QwszP3Jq875ak2GY9zA4CJGLWHCYl3HJIDmKQPY/s5jfL/cDmbZEzT48xTlnDNNwEfKBNyD5Ybd91//dKp6qp6V5tGTDlCQE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247018; c=relaxed/simple; bh=OVI/5v52rwpj9NA8/VcYrpmYXMUR3dgtwMClNO2lIQc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=To2Rh8BRK7/CctcJwGHv3iVbha2egu6mv2Xaun8ZpRtrRJpVIsM1gFEzRccTMrDmsxsgIJsrkvhdZnWCp876LeaV9zzKw8dvonh4CguhS6bI9YiG0oWTEccIOcjokPlf2/IUPXpyevywOwFp7dw8+jAcC2yhfJlLOj49WzUU02k= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=hBWQA4pH; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="hBWQA4pH" ARC-Seal: i=1; a=rsa-sha256; t=1771246973; cv=none; d=zohomail.com; s=zohoarc; b=UQBk8q8c6m7yZHJ0i2nuEj50inrlgIURKKTR/19ybTipGgB2eU1mo/cn/Mz9xrTfynEbpvB5Juo9ymHQlHrr0QO6ShHX77sE+nGxyAI6f0kSW1FMEcAdotQMncLiqER7N6/cA8SLVNb89peBBD05AUgXWKLklIt1s0XyDBbZKNk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246973; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=UuzjSqQYzz1QT9FVEJ1JRFDYSrnS9/+HLRLUmTr5oYU=; b=ZNoMEWYmgum3qZ3FGD1YpxpbRQ/b9/VljFjOuUtpThXkOCAsiXoTns1ivA8Sd/lcYGze0etuHI+RtFOgwC+WPnTHheQib1kASCRDO5Jt6vW1Sb3qmcBQhqAi8jPHc7GAprmXhKQ0Q2FjDxxp8f68iYjqdWgsOYNEPHE61tud6NQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246973; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=UuzjSqQYzz1QT9FVEJ1JRFDYSrnS9/+HLRLUmTr5oYU=; b=hBWQA4pHSkD6bhon4/zr6kTe+my6k4WFo7X2xiu//NGme8Ho3tRNysfiafPnOWb6 hjd5N9U7KUvt6Cus6qMeCdmRbBXKFd0XCj4uLBssZuqM5UBFL3P2nGmqqiHUisr5tSk 1A4zRkhMYAuXtW9RLimRo/q0Jim4GKpeJ6qzRwa8= Received: by mx.zohomail.com with SMTPS id 1771246971429982.6699440107166; Mon, 16 Feb 2026 05:02:51 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:24 +0100 Subject: [PATCH v8 10/20] drm/rockchip: vop2: Add RK3576 to the RG swap special case Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-10-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Andy Yan X-Mailer: b4 0.14.3 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") Reviewed-by: Andy Yan Signed-off-by: Nicolas Frattaroli --- 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 ec3b4fde10db..7c0a93f129f3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -337,7 +337,8 @@ static bool vop2_output_uv_swap(u32 bus_format, u32 out= put_mode) =20 static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format) { - if (vop2->version =3D=3D VOP_VERSION_RK3588) { + if (vop2->version =3D=3D VOP_VERSION_RK3588 || + vop2->version =3D=3D VOP_VERSION_RK3576) { if (bus_format =3D=3D MEDIA_BUS_FMT_YUV8_1X24 || bus_format =3D=3D MEDIA_BUS_FMT_YUV10_1X30) return true; --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 137C52BE641; Mon, 16 Feb 2026 13:03:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247031; cv=pass; b=V6K7+sEvx7sTt8Bp30BMuZPXCFOhYD4Y0QqKTDFZaoHgVtPNrhxWQ9J0caSxDl40kGT3x7qT7DK0618TfaWXzKYg45bE5ONsnXXoVwtyyIOp0c4xkjTekOfH//EV2DH9zQY4kFJH/HUl3SrAxloIqFAoOpoM7qd1vAbjtPDZWGM= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247031; c=relaxed/simple; bh=zp3RRxLE65hsnv+xQdzZziJnBWqoafwIu+84dQtOAcM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ckJOmg1LqdI+UDpxJl/w0AS9S+8c5TC7dFOjD4hsxWAUkT1TWQ5Fp02Vglf/iJ12fi5HuSP/cWshzFU8GboPFY49gkxrhztuz6uVT4EmfvaHS1c49Na9a2+z5Is6HlCL4Asq0AJ3U2xAqgpME2UDBRzgT0QVWKGfwuLK57eawKI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=UPoAtcYQ; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="UPoAtcYQ" ARC-Seal: i=1; a=rsa-sha256; t=1771246979; cv=none; d=zohomail.com; s=zohoarc; b=hb4/Cbi7DNQ6KDoQm10/Ijs/Jy3/AIW3XimFlwuaVjpUSrfNRyZqd97HcxO5w6YrZAdBr5OozCPlg+KMfMFKx/Oqt3YCTm3IMaGb+khhnRoyt0bFKDSHXUd9GtBNAneD2UNo7q3EVyhCcfqquWrceTfd1J+U7nam436QfCdefIY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246979; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=v3cuHWp4ZUczC8K8xwIJtvmVhWuzP8cUhPMUU9ertxo=; b=md4DwTaqKzhyP+BrkssRAkZaDW2VT+bLvQ9hhLiDlmseBP4KfGfZnShU1BC7du+dIMsC3ZuV38TkrNh5RD96jKiIaJdDYcwslfPxcSg3yUwofqdf1OZaLtzL+KpA27oTmZQCQM/tv0E9Z92X47m0Eohvi3ikhKn4xSR8y4yc3JY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246979; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=v3cuHWp4ZUczC8K8xwIJtvmVhWuzP8cUhPMUU9ertxo=; b=UPoAtcYQLIYvG1+6trdymlUouWmEulPjp1bHrgAPfHgaB0SiLxshgt/cmdh6EI5k LpOd8mcwhrf6L+wczvWAUc3oU0cq9ov7p7mZDq1kubmLScqGLfZ1AdHoX3FrPm8urFT Emzk1O1x9Er1Zf9xbCLNLhCoZ/Y/TuXxKgIoZzZA= Received: by mx.zohomail.com with SMTPS id 177124697831043.703670429346744; Mon, 16 Feb 2026 05:02:58 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:25 +0100 Subject: [PATCH v8 11/20] drm/rockchip: vop2: Recognise 10-bit YUV422 as YUV format Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-11-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 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. Add the two component orderings of the YUV422 10-bit bus formats to the switch statement. Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") Signed-off-by: Nicolas Frattaroli --- 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 7c0a93f129f3..130fd1ac3cd5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -352,6 +352,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_UYVY10_1X20: case MEDIA_BUS_FMT_UYYVYY8_0_5X24: case MEDIA_BUS_FMT_UYYVYY10_0_5X30: case MEDIA_BUS_FMT_YUYV8_2X8: --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-g125.zoho.com (sender4-pp-g125.zoho.com [136.143.188.125]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 177FE303A02; Mon, 16 Feb 2026 13:03:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.125 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247036; cv=pass; b=RWEozmKsYL3I0OkS0E/H2z6Kngt2XxhbwI6RdHFUxBrLXqG4SxTxyXpwSQU0gmmssDN+/k+2zszz4B/jgzDqLKhLFUP7KZVugseLG34dt22B152NoCUmoNJwOxzB3Lvwq9t/NMnLFXYQrRo2qlvq4P5PBzhw/ljOsnO0y9fwXCY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247036; c=relaxed/simple; bh=nylZnl7lCJyuJuqXLSa/cDhQCtkynMkoDw8V6gYxMxc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=g6jyzPB5ReBr9A884ALJz/8DwehC0Gg/iAWpRgEwGrLD4fUzYjrVF5FQMY4Yn01BIRftMYnqButMRrhXUjFTMrtek5knjF1hHejx2Ah4W5k4tKbL/8GSC9QRa/4eag5tj9yHT/sGPTyHbOtW/SbBvx0pB29wEs9QLvPo8aoj6nQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=PDEl8wn8; arc=pass smtp.client-ip=136.143.188.125 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="PDEl8wn8" ARC-Seal: i=1; a=rsa-sha256; t=1771246987; cv=none; d=zohomail.com; s=zohoarc; b=MdJ/mxA5fgJoakqG0FghbVUlSv4xX19Pg5FkZNtYJfH3R6g293gEcfmar7CNEk3lrIWkzGPEEgEG2B3aF/KV/Cr84/s5uKbZ3l/Gxi2XmZ8/LDACaozjRhLGHzNHm5By0V3bzqIfpGtK58xlKq4eMoC00RnKBmBINS2WSBzJp54= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246987; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=+mbL29SVjCbTNM5wNdqf38glrTcCQqkW0K6Sv4hImIU=; b=avQWLNohGNmD7IF+Qsoha6qRUxV3vOUk7A7Af7A7gyW9zGFX19b1oe243faAZTRHejFV8tglyUJtlAGF6nniso2jlWoiKrXh1rmVuNYoX6xjIT5q03N21cpTBRDE9C1rL1uqZE0TFbpcwVY9tqUN5CZIJ64yVGyOa9a7345Tzpc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246987; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=+mbL29SVjCbTNM5wNdqf38glrTcCQqkW0K6Sv4hImIU=; b=PDEl8wn8npnpBLBzAzMHKidIg4PteknKKY+vf9Hf9+NJCb2Mm4OmT/CmyBm+DLny UhBacK3VLFH73GAPMYauAEziTPdFnRuEqxaGyilPoc68XmXFVDpWxZOGI+Vh3BoCQwW /yAuK+7YIp5JJmylqtlb6RuD5h/D4m0NKUzu+8W4= Received: by mx.zohomail.com with SMTPS id 1771246985455212.40280047260944; Mon, 16 Feb 2026 05:03:05 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:26 +0100 Subject: [PATCH v8 12/20] drm/rockchip: vop2: Set correct output format for RK3576 YUV422 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-12-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli , Andy Yan X-Mailer: b4 0.14.3 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. Reviewed-by: Andy Yan Signed-off-by: Nicolas Frattaroli --- 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 130fd1ac3cd5..fe0766b96551 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1686,6 +1686,22 @@ static void vop2_crtc_atomic_enable(struct drm_crtc = *crtc, if (vcstate->output_mode =3D=3D ROCKCHIP_OUT_MODE_AAAA && !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT)) out_mode =3D ROCKCHIP_OUT_MODE_P888; + else if (vcstate->output_mode =3D=3D ROCKCHIP_OUT_MODE_YUV422 && + vop2->version =3D=3D VOP_VERSION_RK3576) + switch (vcstate->output_type) { + case DRM_MODE_CONNECTOR_DisplayPort: + case DRM_MODE_CONNECTOR_eDP: + out_mode =3D ROCKCHIP_OUT_MODE_YUV422_RK3576_DP; + break; + case DRM_MODE_CONNECTOR_HDMIA: + out_mode =3D 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 =3D vcstate->output_mode; =20 --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A8D92FFDFC; Mon, 16 Feb 2026 13:04:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247041; cv=pass; b=O7R+gnJC3UDiIfz7xWXSjJn3nsXGF4nvaY0BZnW+Znq+Yv686qBXIa8M8XQLoOpIXZ9Ex8KhX69Ij6CbjFlehnhHctji2ccfrQM2pN8urPsA2RnyBPwR2L1syjoYjUtUGwE0tG4bzBNtg/mLvmBCEqOmIrJP4X0tRF1Y7hlu/7c= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247041; c=relaxed/simple; bh=j+uQ0/qK2Ovg/uCiyPT7rgN5Mo+gbVTwyPuC9ku8te4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cGZo2/p5SQbZzt07gI0blk0g+GcQvenovlcY+IVK6QnaPXXrCUuBGdhtbGJk0XSFliAmt5e4L5vXpdut/QwYlqeGNcj+5Yqqq9yrynMYM4WR7u4d/JM+GKZvV47DoCl84fTWddA9qUez6E5VRbM0GO5jKusr1za6oNggaDNyj0c= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=QnHSAO8p; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="QnHSAO8p" ARC-Seal: i=1; a=rsa-sha256; t=1771246993; cv=none; d=zohomail.com; s=zohoarc; b=mAWObq6MZgJ36ToIxOtOeHBGuQQEqoD/NhcJjCl+LdP+3iQIhFFi6DlL20ObQZt13rEVtWlpKsnBlLANhf1H7hmp/iVTRYGkfoH2ocQCj7UxVB6HoAObCDbWNljZEVU0MbVf8dkNNwr0XDn0s99R64tnBGUxVHhhp9iPTAW+wcU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771246993; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=L4TB1VZvZtMLKUs37afR6aj+cqotV2KSEgyNjdp9AC0=; b=LxwFXJfQGhhTEl8Dc4cCNKnSUb6INmQLT6fxjKpRhOdbegbtvEyL9yKaZKtSnBSIqtBq7XXAsodHllL3RhX/1ktCSfXT5OPC6C3Ij7wx+9pcuqWXsMyzB1eJB+CDLPsAGrqGDgKtCVG5FmPC8xuISw0VoHJneuhxMp6MYwR8ruE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771246993; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=L4TB1VZvZtMLKUs37afR6aj+cqotV2KSEgyNjdp9AC0=; b=QnHSAO8pYsKzoV16mt7Uwwf3HpGMSnzo2lnx6b9y8KVo/+sXO8AW/9pItxSZjbFs QfUTGzJLwZSeahb6h4/eiPD0XaQ/FiSJBUfTvkSOF2YR0Xs648o5jF+m/XB9UvkDyh+ AHWSP50/BeuQD1OlXwhkTizk4usUX07cu/af1seY= Received: by mx.zohomail.com with SMTPS id 177124699234966.93187605725814; Mon, 16 Feb 2026 05:03:12 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:27 +0100 Subject: [PATCH v8 13/20] drm/bridge: dw-hdmi-qp: Implement atomic_get_output_bus_fmts Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-13-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 The atomic_get_output_bus_fmts callback is used by the DRM bridge layer to recursively select a suitable output format in a bridge chain. As a bridge that outputs to HDMI, dw-hdmi-qp will have its output formats determined by which formats the platform-specific integration of the hardware supports, and the chosen HDMI output bit depth. Implement this callback. The returned u32* buffer is supposed to be freed by the caller of this callback, as specified by the callback's documentation. Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 178 +++++++++++++++++++++++= ++++ 1 file changed, 178 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm= /bridge/synopsys/dw-hdmi-qp.c index d649a1cf07f5..4c00218e5fd7 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -749,6 +750,182 @@ static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(str= uct dw_hdmi_qp *hdmi) return adap; } =20 +static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi, + const u8 *buffer, size_t len) +{ + u32 val, i, j; + + if (len !=3D HDMI_INFOFRAME_SIZE(AVI)) { + dev_err(hdmi->dev, "failed to configure avi infoframe\n"); + return -EINVAL; + } + + /* + * DW HDMI QP IP uses a different byte format from standard AVI info + * frames, though generally the bits are in the correct bytes. + */ + val =3D buffer[1] << 8 | buffer[2] << 16; + dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0); + + for (i =3D 0; i < 4; i++) { + for (j =3D 0; j < 4; j++) { + if (i * 4 + j >=3D 14) + break; + if (!j) + val =3D buffer[i * 4 + j + 3]; + val |=3D buffer[i * 4 + j + 3] << (8 * j); + } + + dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4); + } + + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1); + + dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, + PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN); + + return 0; +} + +static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi, + const u8 *buffer, size_t len) +{ + u32 val, i; + + if (len !=3D HDMI_INFOFRAME_SIZE(DRM)) { + dev_err(hdmi->dev, "failed to configure drm infoframe\n"); + return -EINVAL; + } + + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); + + val =3D buffer[1] << 8 | buffer[2] << 16; + dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0); + + for (i =3D 0; i <=3D buffer[2]; i++) { + if (i % 4 =3D=3D 0) + val =3D buffer[3 + i]; + val |=3D buffer[3 + i] << ((i % 4) * 8); + + if ((i % 4 =3D=3D 3) || i =3D=3D buffer[2]) + dw_hdmi_qp_write(hdmi, val, + PKT_DRMI_CONTENTS1 + ((i / 4) * 4)); + } + + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1); + dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN, + PKTSCHED_PKT_EN); + + return 0; +} + +/* + * Static values documented in the TRM + * Different values are only used for debug purposes + */ +#define DW_HDMI_QP_AUDIO_INFOFRAME_HB1 0x1 +#define DW_HDMI_QP_AUDIO_INFOFRAME_HB2 0xa + +static int dw_hdmi_qp_config_audio_infoframe(struct dw_hdmi_qp *hdmi, + const u8 *buffer, size_t len) +{ + /* + * AUDI_CONTENTS0: { RSV, HB2, HB1, RSV } + * AUDI_CONTENTS1: { PB3, PB2, PB1, PB0 } + * AUDI_CONTENTS2: { PB7, PB6, PB5, PB4 } + * + * PB0: CheckSum + * PB1: | CT3 | CT2 | CT1 | CT0 | F13 | CC2 | CC1 | CC0 | + * PB2: | F27 | F26 | F25 | SF2 | SF1 | SF0 | SS1 | SS0 | + * PB3: | F37 | F36 | F35 | F34 | F33 | F32 | F31 | F30 | + * PB4: | CA7 | CA6 | CA5 | CA4 | CA3 | CA2 | CA1 | CA0 | + * PB5: | DM_INH | LSV3 | LSV2 | LSV1 | LSV0 | F52 | F51 | F50 | + * PB6~PB10: Reserved + * + * AUDI_CONTENTS0 default value defined by HDMI specification, + * and shall only be changed for debug purposes. + */ + u32 header_bytes =3D (DW_HDMI_QP_AUDIO_INFOFRAME_HB1 << 8) | + (DW_HDMI_QP_AUDIO_INFOFRAME_HB2 << 16); + + regmap_bulk_write(hdmi->regm, PKT_AUDI_CONTENTS0, &header_bytes, 1); + regmap_bulk_write(hdmi->regm, PKT_AUDI_CONTENTS1, &buffer[3], 1); + regmap_bulk_write(hdmi->regm, PKT_AUDI_CONTENTS2, &buffer[4], 1); + + /* Enable ACR, AUDI, AMD */ + dw_hdmi_qp_mod(hdmi, + PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN, + PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN, + PKTSCHED_PKT_EN); + + /* Enable AUDS */ + dw_hdmi_qp_mod(hdmi, PKTSCHED_AUDS_TX_EN, PKTSCHED_AUDS_TX_EN, PKTSCHED_P= KT_EN); + + return 0; +} + +static u32* +dw_hdmi_qp_bridge_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + unsigned int *num_output_fmts) +{ + unsigned int num_fmts =3D 0; + u32 *out_fmts; + + /* + * bridge->supported_formats is a bit field of the HDMI_COLORSPACE_* enum= s. + * These enums are defined by the HDMI standard, and currently top out at + * 7. Consequently, BIT(7) is the highest bit that will be set here, unle= ss + * the standard runs out of reserved pixel formats. Therefore, hweight8() + * will give an accurate count of how many bus formats we'll output. + */ + out_fmts =3D kmalloc_array(hweight8(bridge->supported_formats), sizeof(u3= 2), + GFP_KERNEL); + if (!out_fmts) { + *num_output_fmts =3D 0; + return NULL; + } + + switch (conn_state->hdmi.output_bpc) { + case 12: + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_RGB)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_RGB121212_1X36; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV444)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_YUV12_1X36; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV422)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_UYVY12_1X24; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV420)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_UYYVYY12_0_5X36; + break; + case 10: + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_RGB)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_RGB101010_1X30; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV444)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_YUV10_1X30; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV422)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_UYVY10_1X20; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV420)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_UYYVYY10_0_5X30; + break; + default: + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_RGB)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_RGB888_1X24; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV444)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_YUV8_1X24; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV422)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_UYVY8_1X16; + if (bridge->supported_formats & BIT(HDMI_COLORSPACE_YUV420)) + out_fmts[num_fmts++] =3D MEDIA_BUS_FMT_UYYVYY8_0_5X24; + break; + } + + *num_output_fmts =3D num_fmts; + + return out_fmts; +} + static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_atomic_state *state) { @@ -1192,6 +1369,7 @@ static int dw_hdmi_qp_cec_transmit(struct drm_bridge = *bridge, u8 attempts, #endif /* CONFIG_DRM_DW_HDMI_QP_CEC */ =20 static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs =3D { + .atomic_get_output_bus_fmts =3D dw_hdmi_qp_bridge_get_output_bus_fmts, .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, .atomic_reset =3D drm_atomic_helper_bridge_reset, --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF0D11DDC37; Mon, 16 Feb 2026 13:04:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247050; cv=pass; b=KUtDW2biJ/kwfesPiisuEKrL6o88D5IDUF+nPb4I4oSLUOBfrLG7Dgb1yiz2V+7rqu/4SJ4bhS6nk9zhFqXExmkiOsYeh+y5+RThjnwfhDmfb8eiUf6TomoOMePFpqlLMjoh2SO4KMl3Jo5YB3aX+wHoeFOi4AGmGa+aHLhFeT0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247050; c=relaxed/simple; bh=TCh04P9mYsqOrcyx/wt7GmcSAIbBSZQMM/gwC+h8lpQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RjtnDXAjhDDJD8dn5R4VXB31iMQ6q1OqNpC3tmmMuVo5K1JVF/uPJHjPB0l2EIWg55QR1bEXopfkou3H6zTzZe1So3ziBnWpK/gzr4IgQ/MdzjNdevNwPO+M5E7bFCYBcGIvh7zpTaulS8SynqFGZoWft3bwDXLWrR1KQB/OUyo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=OzL7AXPv; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="OzL7AXPv" ARC-Seal: i=1; a=rsa-sha256; t=1771247001; cv=none; d=zohomail.com; s=zohoarc; b=Ju4u/R9VFHvRc4eFYAJ940nCfQai7uTtLse9wAmk7atHiaPy+ID9zQcuAPOGdJhbx3up2bKtzNZX7DaYmkNCzWDjwjSKikFnSMIGDFrs5kNTJQyakliFWUZNKIgiOdi4jH7fmMG+oZYMhj68G744QX6hNemig4LSa99PQqbvzyA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771247001; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=aAKo1twm4zvOU57OmqnMmeCHmOgUWQwHKdY/derPNZ0=; b=eu/KPwydHyYdKSnpS7L3A2RnsyC5Gk0nZ0+rAVbfCltzh6DXMMFMe8kcGrm9dN3EYvTfJUy/2TUXISpxaU+kFIoPCDZ9/pw6eC0KsRYZLiQa2p2G51CYOst5Xzx5jYDGKa0NEiabTMXy6jKiCjzLMuh0scXq6UHAR6A8Gw3KTYI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771247001; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=aAKo1twm4zvOU57OmqnMmeCHmOgUWQwHKdY/derPNZ0=; b=OzL7AXPvNUoDGRUQZxdxi8/vIDs3Zd3rYVpoRUwXa2y+riED8BUmJu9rJ33U3qOS zbSRPvDUPmpBxVxENAfoNdKNydYPmAZCbszSNnuUjRdpSGra2THzTixGLP0IW2tw8cI gSDsskGdn3TDuo3vRzgFY2/3eGTHjqPIzYTV3kYU= Received: by mx.zohomail.com with SMTPS id 1771246999224749.212783556211; Mon, 16 Feb 2026 05:03:19 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:28 +0100 Subject: [PATCH v8 14/20] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-14-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 Switch between requested color formats by setting the right bus formats, configuring the VO GRF registers, and setting the right output mode. To do this, the encoder's atomic_check queries the bus format of the first bridge, which was determined by the bridge chain recursive format selection. Pick the input format if it's !FIXED, otherwise, pick the output format. The previously unused GRF register color format defines are redone as well. Both RK3588 and RK3576 use the same defines; it didn't look like this as there was a typo in the previously (unused) definition. Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 107 +++++++++++++++++++++= +--- 1 file changed, 98 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/d= rm/rockchip/dw_hdmi_qp-rockchip.c index 1a09bcc96c3e..e2fa1aa53394 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 #include #include +#include #include #include #include @@ -43,10 +44,6 @@ #define RK3576_8BPC 0x0 #define RK3576_10BPC 0x6 #define RK3576_COLOR_FORMAT_MASK GENMASK(7, 4) -#define RK3576_RGB 0x9 -#define RK3576_YUV422 0x1 -#define RK3576_YUV444 0x2 -#define RK3576_YUV420 0x3 #define RK3576_CECIN_MASK BIT(3) =20 #define RK3576_VO0_GRF_SOC_CON14 0x0038 @@ -74,8 +71,6 @@ #define RK3588_8BPC 0x0 #define RK3588_10BPC 0x6 #define RK3588_COLOR_FORMAT_MASK GENMASK(3, 0) -#define RK3588_RGB 0x0 -#define RK3588_YUV420 0x3 #define RK3588_SCLIN_MASK BIT(9) #define RK3588_SDAIN_MASK BIT(10) #define RK3588_MODE_MASK BIT(11) @@ -87,6 +82,11 @@ #define HOTPLUG_DEBOUNCE_MS 150 #define MAX_HDMI_PORT_NUM 2 =20 +#define RK_COLOR_FMT_RGB 0x0 +#define RK_COLOR_FMT_YUV422 0x1 +#define RK_COLOR_FMT_YUV444 0x2 +#define RK_COLOR_FMT_YUV420 0x3 + struct rockchip_hdmi_qp { struct device *dev; struct regmap *regmap; @@ -115,6 +115,33 @@ static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(st= ruct drm_encoder *encoder) return container_of(rkencoder, struct rockchip_hdmi_qp, encoder); } =20 +/** + * dw_hdmi_qp_rockchip_bus_fmt_to_reg - converts a bus format to a GRF reg= value + * @bus_fmt: One of the MEDIA_BUS_FMT_s allowed by this driver's atomic_ch= eck + * + * Returns: an unshifted value to be written to the COLOR_FORMAT GRF regis= ter + * on success, or %-EINVAL if the bus format is not supported. + */ +static int __pure dw_hdmi_qp_rockchip_bus_fmt_to_reg(u32 bus_fmt) +{ + switch (bus_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB101010_1X30: + return RK_COLOR_FMT_RGB; + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY10_1X20: + return RK_COLOR_FMT_YUV422; + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + return RK_COLOR_FMT_YUV444; + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + return RK_COLOR_FMT_YUV420; + } + + return -EINVAL; +} + static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) { struct rockchip_hdmi_qp *hdmi =3D to_rockchip_hdmi_qp(encoder); @@ -130,29 +157,83 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct= drm_encoder *encoder) hdmi->ctrl_ops->enc_init(hdmi, to_rockchip_crtc_state(crtc->state)); } =20 +/** + * dw_hdmi_qp_rockchip_get_vop_format - get the bus format VOP should outp= ut + * @encoder: pointer to a &struct drm_encoder + * @conn_state: pointer to the current atomic &struct drm_connector_state + * + * Determines which bus format the Rockchip video processor should output = as + * to feed into the bridge chain. + * + * Returns a MEDIA_BUS_FMT_* on success, or %0 on error. + */ +static u32 dw_hdmi_qp_rockchip_get_vop_format(struct drm_encoder *encoder, + struct drm_connector_state *conn_state) +{ + struct drm_bridge *bridge __free(drm_bridge_put) =3D NULL; + struct drm_bridge_state *bstate; + + bridge =3D drm_bridge_chain_get_first_bridge(encoder); + if (!bridge) + return 0; + + bstate =3D drm_atomic_get_bridge_state(conn_state->state, bridge); + if (!bstate) + return 0; + + if (bstate->input_bus_cfg.format !=3D MEDIA_BUS_FMT_FIXED) + return bstate->input_bus_cfg.format; + + return bstate->output_bus_cfg.format; +} + static int 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 =3D to_rockchip_hdmi_qp(encoder); struct rockchip_crtc_state *s =3D to_rockchip_crtc_state(crtc_state); + struct rockchip_hdmi_qp *hdmi =3D to_rockchip_hdmi_qp(encoder); union phy_configure_opts phy_cfg =3D {}; + u32 ingest_fmt; int ret; =20 + ingest_fmt =3D dw_hdmi_qp_rockchip_get_vop_format(encoder, conn_state); + if (!ingest_fmt) + return -EINVAL; + if (hdmi->tmds_char_rate =3D=3D conn_state->hdmi.tmds_char_rate && - s->output_bpc =3D=3D conn_state->hdmi.output_bpc) + s->output_bpc =3D=3D conn_state->hdmi.output_bpc && + s->bus_format =3D=3D ingest_fmt) return 0; =20 + switch (ingest_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + s->output_mode =3D ROCKCHIP_OUT_MODE_AAAA; + break; + case MEDIA_BUS_FMT_UYVY8_1X16: + s->output_mode =3D ROCKCHIP_OUT_MODE_YUV422; + break; + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + s->output_mode =3D ROCKCHIP_OUT_MODE_YUV420; + break; + default: + return -EINVAL; + } + phy_cfg.hdmi.tmds_char_rate =3D conn_state->hdmi.tmds_char_rate; phy_cfg.hdmi.bpc =3D conn_state->hdmi.output_bpc; =20 ret =3D phy_configure(hdmi->phy, &phy_cfg); if (!ret) { hdmi->tmds_char_rate =3D conn_state->hdmi.tmds_char_rate; - s->output_mode =3D ROCKCHIP_OUT_MODE_AAAA; s->output_type =3D DRM_MODE_CONNECTOR_HDMIA; s->output_bpc =3D conn_state->hdmi.output_bpc; + s->bus_format =3D ingest_fmt; } else { dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret); } @@ -382,6 +463,7 @@ static void dw_hdmi_qp_rk3588_io_init(struct rockchip_h= dmi_qp *hdmi) static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi, struct rockchip_crtc_state *state) { + int color =3D dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format); u32 val; =20 if (state->output_bpc =3D=3D 10) @@ -389,12 +471,16 @@ static void dw_hdmi_qp_rk3576_enc_init(struct rockchi= p_hdmi_qp *hdmi, else val =3D FIELD_PREP_WM16(RK3576_COLOR_DEPTH_MASK, RK3576_8BPC); =20 + if (likely(color >=3D 0)) + val |=3D FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, color); + regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON8, val); } =20 static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi, struct rockchip_crtc_state *state) { + int color =3D dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format); u32 val; =20 if (state->output_bpc =3D=3D 10) @@ -402,6 +488,9 @@ static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_= hdmi_qp *hdmi, else val =3D FIELD_PREP_WM16(RK3588_COLOR_DEPTH_MASK, RK3588_8BPC); =20 + if (likely(color >=3D 0)) + val |=3D 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); --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 49A472E62B3; Mon, 16 Feb 2026 13:04:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247050; cv=pass; b=fDZZLOTzq51Yj3triOociTHFBG1c782MHl9zn7PlXTXHBhNMGyrvVJzz+uic2tWcCB7Y2IIyeXwnAhdZZqucj7SwQkhL+LOQWx9IQJo8wyLOm+6b69fzGTo+D9S9Z/IsfhyDgCBXFFXE0FoY+IZX45+3oFKyEZ3R9OmKuQlwdio= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247050; c=relaxed/simple; bh=ClLe55IhwWTIFJjkYYqQGnWcIUKIFXXk7B+QDkvbhYQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ItVhyP2eKtlnmyeYuKJRX1DZWTHaibvd++ZwQnDLmWiJV9a4UJlQPmrRiQ7juydrgmQ9usrCFB/HPUm89DRAruMNOssbY5XKeeNfXQuvKjvV3eq1ZC+LIn0YvlYyOE/Qg2cw/7gBuyWQDLklvVpywkI2nAkkkUTIBJGqWleK1ao= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=eErv4N2x; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="eErv4N2x" ARC-Seal: i=1; a=rsa-sha256; t=1771247007; cv=none; d=zohomail.com; s=zohoarc; b=BoQ7frQ/lbCOQ3R53OiYoa/p+9XQx0KVcOhi/2KL2a2mPzt3Y671r+xJTuehKTkIwBMMme/8DihfINW6od64kG8D5+qA7kHgRfvogVyNpFLeHQOGnbgQIYOV2VUsE/TmqQh80/mTcaThmJ8pVZOivp+cMTyzaBio/ez0nV66AfI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771247007; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=sZmW2NPYujZEBxA8nnT64f1BC+nomHSZxQc73mGD0fw=; b=aXmqc40ua9Ors80bNLCAY3oi39reMyuEhDzdH6ol4d0E7dFKhHXBU/o8afoU/+LxjBIuXh/DfyJeVi0Fi3tLLtYkGZB+o4hRBaYN87VJqZD/spp1S8IyTbF9o+CWQ0TnvW32EPsEDrq7dHkNWGc41RIvpzYqmxpceBWhAjHDFTs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771247007; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=sZmW2NPYujZEBxA8nnT64f1BC+nomHSZxQc73mGD0fw=; b=eErv4N2xk29bwRxGTGpjH+9ZvC4/aMiOfLzu2fWPB2T6GPmV36yMB1RFg/uydPPn n2RiqrpssY5khZTU1dL1kKaz3X9AvJS4wNEgWUy1mlosPgJOOJAXlrI2U4cB0Xy4SJN OnMdqio+HCApxB5VzCP6J2+OjohTE4spj5aeVVis= Received: by mx.zohomail.com with SMTPS id 17712470061111.3434452027062207; Mon, 16 Feb 2026 05:03:26 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:29 +0100 Subject: [PATCH v8 15/20] drm/rockchip: dw_hdmi_qp: Set supported_formats platdata Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-15-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 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 --- 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/d= rm/rockchip/dw_hdmi_qp-rockchip.c index e2fa1aa53394..de03d74d36a3 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -601,6 +601,10 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev= , struct device *master, plat_data.phy_data =3D hdmi; plat_data.max_bpc =3D 10; =20 + plat_data.supported_formats =3D BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV444) | + BIT(HDMI_COLORSPACE_YUV422); + encoder =3D &hdmi->encoder.encoder; encoder->possible_crtcs =3D drm_of_find_possible_crtcs(drm, dev->of_node); =20 --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 74C292F12C6; Mon, 16 Feb 2026 13:04:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247069; cv=pass; b=A8c2soL53L9Eom7wm6uFJig83b5kKMPxGOsuzxx9ckFOWbIVKhPzLbMyqavywJcM4YHkvwZOCg4Jsp6jJwq97WxcdiAGDf0VHNaAAeHe3qquCNM4swirDnZPQGjB4B8LA4rqlf5Yb5CGVjtAW6xrN3nlTURQztK4TNWr4tROQB4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247069; c=relaxed/simple; bh=LVVhvkoKq+6cgnmVF2R9/6ld4B/SNMB8QtyxfEmb+WY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n1acegCHVgsiqtsRUFNPIwNMLZyE3Z919PfGHA4+g8Qjte5+/QFeSdKvaw46DpySRNdpUoctU5BqFN9tYMSKT817fAYLgPtTgJ++8gWZhJXnDxgRYd/cmWxknYUQofU2lEmPLdIhlukafY9Wvq8shsl+++6451/lIEG1lYJrEUo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=XGb4hAvN; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="XGb4hAvN" ARC-Seal: i=1; a=rsa-sha256; t=1771247013; cv=none; d=zohomail.com; s=zohoarc; b=X3zsDLV5a8962IGdHDtyBhrtORXm8oZj9/dLlcuV7j1sKXVndBYVVmS2ZD/zyJzkeVTl71rH2PF6IwfqDZ54mZ/2QthoM7Q5CQJ3eMI3/wQzEtedAgm/7G1FGLwjbI/7KNaQcoysZa/x3k1fCZbF/P/Mkwaqdp4cs4oCvSwxzH8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771247013; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=HmIhAgr+tm1a7is75gZxhYFtYwpF5h9t9yTJ+rDVzqI=; b=E+aRuHoQRYgOByYdK8JwU+i36fRUHTdiwBKr/UJligAFF6n3zyDdN0uKw1ZGBFpkBbkynP/KcqcEWVMZUmUf06vCT1X1Z8/UIp2pEkosjVPzLlHfjIKoJRtVebgoaiFJsga8cSkA3RlhKdxrxjmMhs2mbwzTTxWMQ39yV5C3+m8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771247013; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=HmIhAgr+tm1a7is75gZxhYFtYwpF5h9t9yTJ+rDVzqI=; b=XGb4hAvNRRF0ZDfN1WAN2Eanp5Ib7Hd/GLjvkH0SxR6/PB8A67SaMmC+0cEYjlec wi19JSo8+lcbQpEPg/4FahnQirwxtHbUPvAApr2UdLhP6pjmZnw0IUtFLJbmLod9JP0 sBgrpGPyOGXI9rP6aYLJv/FzJWxFMkfxNVaQfm1k= Received: by mx.zohomail.com with SMTPS id 1771247012992913.1286817983655; Mon, 16 Feb 2026 05:03:32 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:30 +0100 Subject: [PATCH v8 16/20] drm/connector: Register color format property on HDMI connectors Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-16-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 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 Signed-off-by: Nicolas Frattaroli --- 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_connecto= r.c index 4d85add60d92..894811cd69d6 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 =3D 0; int ret; =20 if (!vendor || !product) @@ -627,6 +628,18 @@ int drmm_connector_hdmi_init(struct drm_device *dev, if (max_bpc > 8) drm_connector_attach_hdr_output_metadata_property(connector); =20 + if (supported_formats & BIT(HDMI_COLORSPACE_RGB)) + supported_drm_formats |=3D DRM_COLOR_FORMAT_RGB444; + if (supported_formats & BIT(HDMI_COLORSPACE_YUV444)) + supported_drm_formats |=3D DRM_COLOR_FORMAT_YCBCR444; + if (supported_formats & BIT(HDMI_COLORSPACE_YUV422)) + supported_drm_formats |=3D DRM_COLOR_FORMAT_YCBCR422; + if (supported_formats & BIT(HDMI_COLORSPACE_YUV420)) + supported_drm_formats |=3D DRM_COLOR_FORMAT_YCBCR420; + + if (!drm_mode_create_color_format_property(connector, supported_drm_forma= ts)) + drm_connector_attach_color_format_property(connector); + connector->hdmi.funcs =3D hdmi_funcs; =20 return 0; --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E24CF2D63F6; Mon, 16 Feb 2026 13:05:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247145; cv=pass; b=DSItPGlBuMEZpghtODm9OdHxj6wRT+Kt6FgzD5vpesZaHREiePiA32+4wQL5TQfprVkalnAVOOwnLuwlTQTUoa7zf7QQIGua48/EoXI1q7bGe47l8CyNB90tHYBy15h78FkWvs3QwHPQykwhtVUKnJOJJQmUTZV5k24FNM1TXdo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247145; c=relaxed/simple; bh=L8aMMB6mylu3VVwN8AMZpf0k3raXPBRv783HhmBHNqM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KBKliLzCECEAslEdE4gNynBawk9q9fl++0C3vRcSMmRr9zlri8ETnB+xmmLTl8w9OcD9lf2K4cJhL3hJYk7GT5a/Lc+KgwDWMLTrqFT4sIzjyPOwNg9zlqf4gEglFVdJ3/747ge2bd0UGEAcRAW0ov7fInE8+L6AIFHQcpoPri4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=bJSaoYD9; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="bJSaoYD9" ARC-Seal: i=1; a=rsa-sha256; t=1771247021; cv=none; d=zohomail.com; s=zohoarc; b=NGQfBtnjZbt/p4D7JrbOyWK6/+8UvD07V4ECHcPKsFiPtfZDz4TLvU7y3WmudSFMQ5ikk2WjVRVJyh8Exkwujwiku7Rc63U6J4yWr6ENgEN12sk5Yy0ipRGDsy1IIZZGUNO4pCXt4RlJr9PXiLcF6slFQMISi5rIbwNVBLsCL6s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771247021; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=krJOw5h5lbOayJ5j+vw4w7ppzo8kI13dRsld+HZTM7c=; b=dSTpi1hPPCazjJDjDgTzy4QPjlKSngllEfI0lRfN1JcCb7nrEjX49K6g7YDy8K9pDkYUx77UyqmKKFnw0AlEdwLPfvOJ4WcWnwWgHznHWVS6AU7PAJP50gwlDa4zYb/h9K8Iz3dpqTOk3lt4/La3dHXGu05Wh2J4Z37RQAzMGoU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771247021; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=krJOw5h5lbOayJ5j+vw4w7ppzo8kI13dRsld+HZTM7c=; b=bJSaoYD9h//A3xsFRxmdvAhje/vxpmjPwST+wBv7xYtDs+GAqQqsM3UdhYt3jFJ2 EMXw/Udpp3A2q5bcO8XGjQZ2sGGrIMG0oal3LNjVhN1ZppOEoIWG+WWwvTcn0hJG3gY gPtU6hSiX4418PIaJlgDy4uk7DgvstgR6TpVbEPE= Received: by mx.zohomail.com with SMTPS id 1771247019867674.2264377110861; Mon, 16 Feb 2026 05:03:39 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:31 +0100 Subject: [PATCH v8 17/20] drm/tests: hdmi: Add tests for the color_format property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-17-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 Add some KUnit tests to check the color_format property is working as expected with the HDMI state helper. Existing tests are extended to also test the DRM_COLOR_FORMAT_ENUM_AUTO case, in order to avoid duplicating test cases. For the explicitly selected color format cases, parameterized tests are added. Reviewed-by: Maxime Ripard Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 191 +++++++++++++++++= ++++ 1 file changed, 191 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/g= pu/drm/tests/drm_hdmi_state_helper_test.c index 4bdcea3c7435..013f9bb61b25 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -60,6 +60,23 @@ static struct drm_display_mode *find_preferred_mode(stru= ct drm_connector *connec return preferred; } =20 +static struct drm_display_mode *find_420_only_mode(struct drm_connector *c= onnector) +{ + struct drm_device *drm =3D 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 *co= nnector, const void *edid, size_t edid_len) { @@ -1547,6 +1564,7 @@ static void drm_test_check_max_tmds_rate_bpc_fallback= _yuv420(struct kunit *test) * RGB/10bpc * - The chosen mode has a TMDS character rate lower than the display * supports in YUV422/12bpc. + * - The HDMI connector state's color format property is unset (i.e. AUTO) * * Then we will prefer to keep the RGB format with a lower bpc over * picking YUV422. @@ -1609,6 +1627,7 @@ static void drm_test_check_max_tmds_rate_bpc_fallback= _ignore_yuv422(struct kunit =20 conn_state =3D conn->state; KUNIT_ASSERT_NOT_NULL(test, conn_state); + KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_COLOR_FORMAT_ENUM_AUT= O); =20 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB= ); @@ -1626,6 +1645,7 @@ static void drm_test_check_max_tmds_rate_bpc_fallback= _ignore_yuv422(struct kunit * RGB/8bpc * - The chosen mode has a TMDS character rate lower than the display * supports in YUV420/12bpc. + * - The HDMI connector state's color format property is unset (i.e. AUTO) * * Then we will prefer to keep the RGB format with a lower bpc over * picking YUV420. @@ -1687,6 +1707,7 @@ static void drm_test_check_max_tmds_rate_bpc_fallback= _ignore_yuv420(struct kunit =20 conn_state =3D conn->state; KUNIT_ASSERT_NOT_NULL(test, conn_state); + KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_COLOR_FORMAT_ENUM_AUT= O); =20 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB= ); @@ -2198,6 +2219,172 @@ static void drm_test_check_disable_connector(struct= kunit *test) drm_modeset_acquire_fini(&ctx); } =20 +struct color_format_test_param { + enum drm_color_format_enum fmt; + enum hdmi_colorspace expected; + int expected_ret; + const char *desc; +}; + +/* Test that if: + * - an HDMI connector supports RGB, YUV444, YUV422, and YUV420 + * - the display supports RGB, YUV444, YUV422, and YUV420 + * - the "color format" property is set + * then, for the preferred mode, for a given "color format" option: + * - DRM_COLOR_FORMAT_AUTO results in an HDMI output format of RGB + * - DRM_COLOR_FORMAT_YCBCR422 results in an HDMI output format of YUV422 + * - DRM_COLOR_FORMAT_YCBCR420 results in an HDMI output format of YUV420 + * - DRM_COLOR_FORMAT_YCBCR444 results in an HDMI output format of YUV444 + * - DRM_COLOR_FORMAT_RGB results in an HDMI output format of RGB + */ +static void drm_test_check_hdmi_color_format(struct kunit *test) +{ + const struct color_format_test_param *param =3D test->param_value; + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + int ret; + + priv =3D 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); + + drm_modeset_acquire_init(&ctx, 0); + + KUNIT_ASSERT_TRUE(test, priv->connector.ycbcr_420_allowed); + + info =3D &priv->connector.display_info; + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, info); + preferred =3D find_preferred_mode(&priv->connector); + KUNIT_ASSERT_TRUE(test, drm_mode_is_420(info, preferred)); + + state =3D drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state =3D drm_atomic_get_connector_state(state, &priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + conn_state->color_format =3D param->fmt; + + ret =3D drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state =3D drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret =3D drm_atomic_set_mode_for_crtc(crtc_state, preferred); + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable =3D true; + crtc_state->active =3D true; + + ret =3D drm_atomic_check_only(state); + KUNIT_EXPECT_EQ(test, ret, param->expected_ret); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, param->expected); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +static const struct color_format_test_param hdmi_color_format_params[] =3D= { + { DRM_COLOR_FORMAT_ENUM_AUTO, HDMI_COLORSPACE_RGB, 0, "AUTO -> RGB" }, + { DRM_COLOR_FORMAT_ENUM_YCBCR422, HDMI_COLORSPACE_YUV422, 0, "YCBCR422 ->= YUV422" }, + { DRM_COLOR_FORMAT_ENUM_YCBCR420, HDMI_COLORSPACE_YUV420, 0, "YCBCR420 ->= YUV420" }, + { DRM_COLOR_FORMAT_ENUM_YCBCR444, HDMI_COLORSPACE_YUV444, 0, "YCBCR444 ->= YUV444" }, + { DRM_COLOR_FORMAT_ENUM_RGB444, HDMI_COLORSPACE_RGB, 0, "RGB -> RGB" }, +}; + +KUNIT_ARRAY_PARAM_DESC(check_hdmi_color_format, hdmi_color_format_params, = desc); + +/* Test that if: + * - the HDMI connector supports RGB, YUV422, YUV420, and YUV444 + * - the display has a YUV420-only mode + * - the "color format" property is explicitly set (i.e. !AUTO) + * then: + * - color format DRM_COLOR_FORMAT_RGB will fail drm_atomic_check_only for= the + * YUV420-only mode with -EINVAL + * - color format DRM_COLOR_FORMAT_YCBCR444 will fail drm_atomic_check_onl= y for + * the YUV420-only mode with -EINVAL + * - color format DRM_COLOR_FORMAT_YCBCR422 will fail drm_atomic_check_onl= y for + * the YUV420-only mode with -EINVAL + * - color format DRM_COLOR_FORMAT_YCBCR420 passes drm_atomic_check_only f= or + * the YUV420-only mode + */ +static void drm_test_check_hdmi_color_format_420_only(struct kunit *test) +{ + const struct color_format_test_param *param =3D test->param_value; + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *dank; + int ret; + + priv =3D 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); + + drm_modeset_acquire_init(&ctx, 0); + + dank =3D find_420_only_mode(&priv->connector); + KUNIT_ASSERT_NOT_NULL(test, dank); + + state =3D drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state =3D drm_atomic_get_connector_state(state, &priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + conn_state->color_format =3D param->fmt; + + ret =3D drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state =3D drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret =3D drm_atomic_set_mode_for_crtc(crtc_state, dank); + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable =3D true; + crtc_state->active =3D true; + + ret =3D drm_atomic_check_only(state); + KUNIT_EXPECT_EQ(test, ret, param->expected_ret); + if (!param->expected_ret) + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, param->expected); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +}; + +static const struct color_format_test_param hdmi_color_format_420_only_par= ams[] =3D { + { DRM_COLOR_FORMAT_ENUM_RGB444, HDMI_COLORSPACE_RGB, -EINVAL, "RGB should= fail" }, + { DRM_COLOR_FORMAT_ENUM_YCBCR444, HDMI_COLORSPACE_YUV444, -EINVAL, "YUV44= 4 should fail" }, + { DRM_COLOR_FORMAT_ENUM_YCBCR422, HDMI_COLORSPACE_YUV422, -EINVAL, "YUV42= 2 should fail" }, + { DRM_COLOR_FORMAT_ENUM_YCBCR420, HDMI_COLORSPACE_YUV420, 0, "YUV420 shou= ld work" }, +}; + +KUNIT_ARRAY_PARAM_DESC(check_hdmi_color_format_420_only, + hdmi_color_format_420_only_params, desc); + static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = =3D { KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode), KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1), @@ -2227,6 +2414,10 @@ static struct kunit_case drm_atomic_helper_connector= _hdmi_check_tests[] =3D { 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_PARAM(drm_test_check_hdmi_color_format_420_only, + check_hdmi_color_format_420_only_gen_params), /* * TODO: We should have tests to check that a change in the * format triggers a CRTC mode change just like we do for the --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEC942236FA; Mon, 16 Feb 2026 13:04:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247068; cv=pass; b=LJvtFtbRGSRTM7/ZelrvCRyWnje2LkhNatGXPhKsqYzo8vw1r5OUsnzwZtb0CuQxSCXRQ5ju04OM5J2Ke4nzFoAi5cTdkhGuiUBBtGX+mLSCiYTslPU5RGjQ8X46XuEU6G+G40uiq6i/TAiHrgiWvCDXXHQIx+oHWqbWTniYabI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247068; c=relaxed/simple; bh=sG2Oye3s6IjllhQTkieANukQcWtAxRfdjDtI4/C7vbQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Xqgp+LK6PN8bLx0dwprQqKwvYoX/DHV2EuhBHxsl6ECaJriqlaxA7gG9bN5exI5PFEdSqKBce8IurG8/mX7I0zOcWza+k/fAdPc3OsOvny5+w3PmnBlA68834VBeZYABVqmyUkUFNpt1xAxXUtw9zMMM5++zVy9RpsVgf++39VM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=KQRBRgIW; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="KQRBRgIW" ARC-Seal: i=1; a=rsa-sha256; t=1771247027; cv=none; d=zohomail.com; s=zohoarc; b=G2Gp0ngKZSBJLlYsxZ19h7uKIqKIrCphnRVn8LfZD2C2uOTkVBsSC1GLQGZelrROD3oH5p0ASOi3+65Z/+Lskd9nBZj3J0O+kQT9IzUVHNcYv8KQvC82tGkd1AFkBotd3r/j/6WZC/vHKUCx+Q12n++VHCHfivqftyQimROLg4c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771247027; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=nIaYMQNzlU8laBlOyJCxLGkpBE3iykG94U1GZ2YZC3E=; b=OjE9G1QUZzm8kPKU5yi8H6JMgFmG/4nEGTf2Rpdsfp42sdBvZ7a8+QlhZfnlLU2mEjc1gn8wm+A7HwG2uXCAskp6btbD/tu89UCiE5E44EEkuZAsNueQs08BtEjJpJDzFY8dMc7LQUOUbWY/xC6yLB3MlskcdA3NgHwxxUAE37E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771247027; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=nIaYMQNzlU8laBlOyJCxLGkpBE3iykG94U1GZ2YZC3E=; b=KQRBRgIWQzU+WckQt2qqaxbIn9icpoDz9IMaVatJEAIRVkKUs2dXZYYAFrRm94ER m80rx+Wg8NTmsbYHLZGpDW9U0phHXLuyMTLWZJSeEfaix53ghZ8AaWkq024NK46tKl7 KOpHa+DAnHBZ4U63gR0QMzQS/AY4cYEzsVFH8l7U= Received: by mx.zohomail.com with SMTPS id 1771247026749226.06644662704707; Mon, 16 Feb 2026 05:03:46 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:32 +0100 Subject: [PATCH v8 18/20] drm/tests: hdmi: Add tests for HDMI helper's mode_valid Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-18-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 Add some KUnit tests to verify that the HDMI state helper's mode_valid implementation does not improperly reject chroma subsampled modes on the basis of their clock rate not being satisfiable in RGB. Reviewed-by: Maxime Ripard Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 +++++++++++++++++= ++++ 1 file changed, 109 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/g= pu/drm/tests/drm_hdmi_state_helper_test.c index 013f9bb61b25..90ae810fbfea 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -77,6 +77,23 @@ static struct drm_display_mode *find_420_only_mode(struc= t drm_connector *connect return NULL; } =20 +static struct drm_display_mode *find_420_also_mode(struct drm_connector *c= onnector) +{ + struct drm_device *drm =3D 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_also(&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 *co= nnector, const void *edid, size_t edid_len) { @@ -2700,11 +2717,103 @@ static void drm_test_check_mode_valid_reject_max_c= lock(struct kunit *test) KUNIT_EXPECT_EQ(test, preferred->clock, 25200); } =20 +/* + * Test that drm_hdmi_connector_mode_valid() will accept modes that requir= e a + * 4:2:0 chroma subsampling, even if said mode would violate maximum clock + * constraints if it used RGB 4:4:4. + */ +static void drm_test_check_mode_valid_yuv420_only_max_clock(struct kunit *= test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_display_mode *dank; + struct drm_connector *conn; + + priv =3D drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV420), + 8, + &dummy_connector_hdmi_funcs, + test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn =3D &priv->connector; + KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 200 * 1000); + + dank =3D find_420_only_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, dank); + KUNIT_EXPECT_EQ(test, dank->hdisplay, 3840); + KUNIT_EXPECT_EQ(test, dank->vdisplay, 2160); + + /* + * Note: The mode's "clock" here is not accurate to the actual TMDS + * clock that HDMI will use for a subsampled mode. Hence, why the mode's + * clock is above the .max_tmds_clock of 200MHz. + */ + KUNIT_EXPECT_EQ(test, dank->clock, 297000); +} + +/* + * Test that drm_hdmi_connector_mode_valid() will reject modes that require + * 4:2:0 chroma subsampling, if the connector does not support 4:2:0. + */ +static void +drm_test_check_mode_valid_reject_yuv420_only_connector(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_display_mode *dank; + struct drm_connector *conn; + + priv =3D drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &dummy_connector_hdmi_funcs, + test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn =3D &priv->connector; + KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 200 * 1000); + + dank =3D find_420_only_mode(conn); + KUNIT_EXPECT_NULL(test, dank); +} + +/* + * Test that drm_hdmi_connector_mode_valid() will accept modes that allow = (among + * other color formats) 4:2:0 chroma subsampling, even if the connector do= es not + * support 4:2:0, but the mode's clock works for RGB 4:4:4. + */ +static void +drm_test_check_mode_valid_accept_yuv420_also_connector_rgb(struct kunit *t= est) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_display_mode *mode; + struct drm_connector *conn; + + priv =3D drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &dummy_connector_hdmi_funcs, + test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn =3D &priv->connector; + KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 340 * 1000); + + mode =3D find_420_also_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, mode); + KUNIT_EXPECT_EQ(test, mode->hdisplay, 3840); + KUNIT_EXPECT_EQ(test, mode->vdisplay, 2160); + KUNIT_EXPECT_EQ(test, mode->clock, 297000); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_mode_valid_tests= [] =3D { KUNIT_CASE(drm_test_check_mode_valid), KUNIT_CASE(drm_test_check_mode_valid_reject), KUNIT_CASE(drm_test_check_mode_valid_reject_rate), KUNIT_CASE(drm_test_check_mode_valid_reject_max_clock), + KUNIT_CASE(drm_test_check_mode_valid_yuv420_only_max_clock), + KUNIT_CASE(drm_test_check_mode_valid_reject_yuv420_only_connector), + KUNIT_CASE(drm_test_check_mode_valid_accept_yuv420_also_connector_rgb), { } }; =20 --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A61282F0C79; Mon, 16 Feb 2026 13:05:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247150; cv=pass; b=HxQH9WFpd+1zsFqNYqXdaa5GcnGx3kvVwiogmY3sMCd0Lh8qElS0O6UZXr5Nk2EkCh9w8cuuMFM4sLPVj5FlpwDtgRV4p4mKRkkeWGphAGJuLyBm3y0A8AD+Cm4VvXkSr5oQFeC29CNIIM6vEy2hgZdo6t/K7B7s/0l0329pePQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247150; c=relaxed/simple; bh=m8AoEMahdAYXX+C0DY8sjoHFM51TWaeGaYb1qDGz1go=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hrAYVLnx0dBcNzWxQc6g3auMZ2Zq5abkyPxUiBtR78/wu9RpiyxMX3ZLJfzNqklI+Ya2dWF/3LF7jBkGKXA8XA0+QN2av4eR9YoYPjyFEwu+HHwpEZ/IgOTViaKiIDMTK07Ap7jEmxMP5RbbtfFp7860eyWD4xbiZEOhLGfAk8w= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=UMhH9LNh; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="UMhH9LNh" ARC-Seal: i=1; a=rsa-sha256; t=1771247035; cv=none; d=zohomail.com; s=zohoarc; b=gAYg4ZUYr7k3Jbiy9pkkSq2oWxW3Z5oEnO0pxRx1ypu8NChZAfjUoaRYb4omqF29fTVDv15y+p0m5sfvkbC9Ct0d3TH3gj+3WISKlIP/pP3+LWdTxngX03mIPZZF1SZy6zEjdmRQ4ZWqTqhWS9XKyTsMOialXQjdR8BDufB/kIc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771247035; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ia0vtBf7Hnezwy6KHM8b1coA0aO+S0F1jHSbeeABSIQ=; b=AR2iARd8GGDFvikcu/jfk2ZMuB2QFurx6mQGmWFQw9X9AGN6lTeSZ0cA4XvLbKo3zBW/Lc3h7xX4H/Wh/z88ehNxvMIKk4am8esfV8/pIN7hhULb9Wjvmq/tSqCwpwup8b0tm+UOQpry4r8tOJTqDri+U7ENQcGEXPaU3YDbbEE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771247035; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=Ia0vtBf7Hnezwy6KHM8b1coA0aO+S0F1jHSbeeABSIQ=; b=UMhH9LNhb/aFLJExKEBmp1gOkydYlaEPkf7sI4PbNSiLZrzr1DQUOvMnq0EiltyU wvRz7AP9TkTjXTYDQ8v2OlgEk7M/tveblBlQNDq9eKYH6RaYwZHEviEjOFB68iiUH7b BN9V7JN5eaa+/f+Aiu6ld4ERhdIbxVudD7ZRgL8k= Received: by mx.zohomail.com with SMTPS id 1771247033822778.2328575803281; Mon, 16 Feb 2026 05:03:53 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:33 +0100 Subject: [PATCH v8 19/20] drm/tests: bridge: Add KUnit tests for bridge chain format selection Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-19-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 With the "color format" property, the bridge chain format selection has gained increased complexity. Instead of simply finding any sequence of bus formats that works, the bridge chain format selection needs to pick a sequence that results in the requested color format. Add KUnit tests for this new logic. These take the form of some pleasant preprocessor macros to make it less cumbersome to define test bridges with a set of possible input and output formats. The input and output formats are defined for bridges in the form of tuples, where the first member defines the input format, and the second member defines the output format that can be produced from this input format. This means the tests can construct scenarios in which not all inputs can be converted to all outputs. Some tests are added to test interesting scenarios to exercise the bus format selection in the presence of a specific color format request. Furthermore, tests are added to verify that bridge chains that end in an HDMI connector will always prefer RGB when the color format is DRM_COLOR_FORMAT_ENUM_AUTO, as is the behaviour in the HDMI state helpers. Reviewed-by: Maxime Ripard Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/tests/drm_bridge_test.c | 786 ++++++++++++++++++++++++++++= ++++ 1 file changed, 786 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_bridge_test.c b/drivers/gpu/drm/test= s/drm_bridge_test.c index 887020141c7f..4e6eade03cd5 100644 --- a/drivers/gpu/drm/tests/drm_bridge_test.c +++ b/drivers/gpu/drm/tests/drm_bridge_test.c @@ -2,15 +2,23 @@ /* * Kunit test for drm_bridge functions */ +#include +#include + #include +#include #include #include #include +#include #include +#include =20 #include #include =20 +#include "drm_kunit_edid.h" + /* * Mimick the typical "private" struct defined by a bridge driver, which * embeds a bridge plus other fields. @@ -37,6 +45,21 @@ struct drm_bridge_init_priv { bool destroyed; }; =20 +struct drm_bridge_chain_priv { + struct drm_device drm; + struct drm_encoder encoder; + struct drm_plane *plane; + struct drm_crtc *crtc; + struct drm_connector *connector; + unsigned int num_bridges; + + /** + * @test_bridges: array of pointers to &struct drm_bridge_priv entries + * of which the first @num_bridges entries are valid. + */ + struct drm_bridge_priv **test_bridges; +}; + static struct drm_bridge_priv *bridge_to_priv(struct drm_bridge *bridge) { return container_of(bridge, struct drm_bridge_priv, bridge); @@ -95,6 +118,229 @@ static const struct drm_bridge_funcs drm_test_bridge_a= tomic_funcs =3D { .atomic_reset =3D drm_atomic_helper_bridge_reset, }; =20 +/** + * struct fmt_tuple - a tuple of input/output MEDIA_BUS_FMT_* + */ +struct fmt_tuple { + u32 in_fmt; + u32 out_fmt; +}; + +/* + * Format mapping that only accepts RGB888, and outputs only RGB888 + */ +static const struct fmt_tuple rgb8_passthrough[] =3D { + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, +}; + +/* + * Format mapping that only accepts YUV444, and outputs only YUV444 + */ +static const struct fmt_tuple yuv8_passthrough[] =3D { + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, +}; + +/* + * Format mapping where 8bpc RGB -> 8bpc YUV444, or ID(RGB) or ID(YUV444) + */ +static const struct fmt_tuple rgb8_to_yuv8_or_id[] =3D { + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, +}; + +static const struct fmt_tuple rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420[] = =3D { + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_UYVY8_1X16 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_UYYVYY8_0_5X24 }, +}; + +/* + * Format mapping where 8bpc YUV444 -> 8bpc RGB, or ID(YUV444) + */ +static const struct fmt_tuple yuv8_to_rgb8_or_id[] =3D { + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, +}; + +/* + * A format mapping that acts like a video processor that generates an RGB= signal + */ +static const struct fmt_tuple rgb_producer[] =3D { + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB101010_1X30 }, + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB121212_1X36 }, +}; + +/* + * A format mapping that acts like a video processor that generates an 8-b= it RGB, + * YUV444 or YUV420 signal + */ +static const struct fmt_tuple rgb_yuv444_yuv420_producer[] =3D { + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_UYYVYY8_0_5X24 }, +}; + +static const struct fmt_tuple rgb8_yuv444_yuv422_passthrough[] =3D { + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16 }, +}; + +static const struct fmt_tuple yuv444_yuv422_rgb8_passthrough[] =3D { + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16 }, + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, +}; + +static bool fmt_in_list(const u32 fmt, const u32 *out_fmts, const size_t n= um_fmts) +{ + size_t i; + + for (i =3D 0; i < num_fmts; i++) + if (out_fmts[i] =3D=3D fmt) + return true; + + return false; +} + +/** + * get_tuples_out_fmts - Get unique output formats of a &struct fmt_tuple = list + * @fmt_tuples: array of &struct fmt_tuple + * @num_fmt_tuples: number of entries in @fmt_tuples + * @out_fmts: target array to store the unique output bus formats + * + * Returns the number of unique output formats, i.e. the number of entries= in + * @out_fmts that were populated with sensible values. + */ +static size_t get_tuples_out_fmts(const struct fmt_tuple *fmt_tuples, + const size_t num_fmt_tuples, u32 *out_fmts) +{ + size_t num_unique =3D 0; + size_t i; + + for (i =3D 0; i < num_fmt_tuples; i++) + if (!fmt_in_list(fmt_tuples[i].out_fmt, out_fmts, num_unique)) + out_fmts[num_unique++] =3D fmt_tuples[i].out_fmt; + + return num_unique; +} + +#define DEFINE_FMT_FUNCS_FROM_TUPLES(name) \ +static u32 *drm_test_bridge_ ## name ## _out_fmts(struct drm_bridge *bridg= e, \ + struct drm_bridge_state *bridge_state, \ + struct drm_crtc_state *crtc_state, \ + struct drm_connector_state *conn_state, \ + unsigned int *num_output_fmts) \ +{ \ + u32 *out_fmts =3D kcalloc(ARRAY_SIZE((name)), sizeof(u32), GFP_KERNEL); = \ + \ + if (out_fmts) \ + *num_output_fmts =3D get_tuples_out_fmts((name), ARRAY_SIZE((name)), out= _fmts); \ + else \ + *num_output_fmts =3D 0; \ + \ + return out_fmts; \ +} \ + \ +static u32 *drm_test_bridge_ ## name ## _in_fmts(struct drm_bridge *bridge= , \ + struct drm_bridge_state *bridge_state, \ + struct drm_crtc_state *crtc_state, \ + struct drm_connector_state *conn_state, \ + u32 output_fmt, \ + unsigned int *num_input_fmts) \ +{ \ + u32 *in_fmts =3D kcalloc(ARRAY_SIZE((name)), sizeof(u32), GFP_KERNEL); \ + unsigned int num_fmts =3D 0; \ + size_t i; \ + \ + if (!in_fmts) { \ + *num_input_fmts =3D 0; \ + return NULL; \ + } \ + \ + for (i =3D 0; i < ARRAY_SIZE((name)); i++) \ + if ((name)[i].out_fmt =3D=3D output_fmt) \ + in_fmts[num_fmts++] =3D (name)[i].in_fmt; \ + \ + *num_input_fmts =3D num_fmts; \ + \ + return in_fmts; \ +} + +#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI_FUNC(ident, input_fmts_func, o= utput_fmts_func, \ + hdmi_write_infoframe_func, \ + hdmi_clear_infoframe_func) \ +static const struct drm_bridge_funcs (ident) =3D { \ + .atomic_enable =3D drm_test_bridge_atomic_enable, \ + .atomic_disable =3D drm_test_bridge_atomic_disable, \ + .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, \ + .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, \ + .atomic_reset =3D drm_atomic_helper_bridge_reset, \ + .atomic_get_input_bus_fmts =3D (input_fmts_func), \ + .atomic_get_output_bus_fmts =3D (output_fmts_func), \ + .hdmi_write_avi_infoframe =3D (hdmi_write_infoframe_func), \ + .hdmi_clear_avi_infoframe =3D (hdmi_clear_infoframe_func), \ + .hdmi_write_hdmi_infoframe =3D (hdmi_write_infoframe_func), \ + .hdmi_clear_hdmi_infoframe =3D (hdmi_clear_infoframe_func), \ +} + +#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_FUNC(ident, input_fmts_func, output= _fmts_func) \ + DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI_FUNC(ident, input_fmts_func, output_f= mts_func, \ + NULL, NULL) + +#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(_name) \ + DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_FUNC(_name ## _funcs, \ + drm_test_bridge_ ## _name ## _in_fmts, \ + drm_test_bridge_ ## _name ## _out_fmts) + +static int drm_test_bridge_write_infoframe_stub(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + return 0; +} + +static int drm_test_bridge_clear_infoframe_stub(struct drm_bridge *bridge) +{ + return 0; +} + +#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI(_name) \ + DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI_FUNC(_name ## _hdmi ## _funcs, \ + drm_test_bridge_ ## _name ## _in_fmts, \ + drm_test_bridge_ ## _name ## _out_fmts, \ + drm_test_bridge_write_infoframe_stub, \ + drm_test_bridge_clear_infoframe_stub) +DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_passthrough) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_passthrough); + +DEFINE_FMT_FUNCS_FROM_TUPLES(yuv8_passthrough) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(yuv8_passthrough); + +DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_to_yuv8_or_id) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_to_yuv8_or_id); + +DEFINE_FMT_FUNCS_FROM_TUPLES(yuv8_to_rgb8_or_id) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(yuv8_to_rgb8_or_id); + +DEFINE_FMT_FUNCS_FROM_TUPLES(rgb_producer) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb_producer); + +DEFINE_FMT_FUNCS_FROM_TUPLES(rgb_yuv444_yuv420_producer) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb_yuv444_yuv420_producer); + +DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420); + +DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_yuv444_yuv422_passthrough) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_yuv444_yuv422_passthrough); + +DEFINE_FMT_FUNCS_FROM_TUPLES(yuv444_yuv422_rgb8_passthrough) +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(yuv444_yuv422_rgb8_passthrough); +DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI(yuv444_yuv422_rgb8_passthrough); + KUNIT_DEFINE_ACTION_WRAPPER(drm_bridge_remove_wrapper, drm_bridge_remove, struct drm_bridge *); @@ -180,6 +426,119 @@ drm_test_bridge_init(struct kunit *test, const struct= drm_bridge_funcs *funcs) return priv; } =20 +static struct drm_bridge_chain_priv * +drm_test_bridge_chain_init(struct kunit *test, unsigned int num_bridges, + const struct drm_bridge_funcs **funcs) +{ + struct drm_bridge_chain_priv *priv; + const struct drm_edid *edid; + struct drm_bridge *prev; + struct drm_encoder *enc; + struct drm_bridge *bridge; + struct drm_device *drm; + bool has_hdmi =3D false; + struct device *dev; + unsigned int i; + int ret; + + dev =3D drm_kunit_helper_alloc_device(test); + if (IS_ERR(dev)) + return ERR_CAST(dev); + + priv =3D drm_kunit_helper_alloc_drm_device(test, dev, struct drm_bridge_c= hain_priv, + drm, DRIVER_MODESET | DRIVER_ATOMIC); + if (IS_ERR(priv)) + return ERR_CAST(priv); + + drm =3D &priv->drm; + + priv->test_bridges =3D drmm_kmalloc_array(drm, num_bridges, sizeof(*priv-= >test_bridges), + GFP_KERNEL); + if (!priv->test_bridges) + return ERR_PTR(-ENOMEM); + + priv->num_bridges =3D num_bridges; + + for (i =3D 0; i < num_bridges; i++) { + priv->test_bridges[i] =3D devm_drm_bridge_alloc(dev, struct drm_bridge_p= riv, + bridge, funcs[i]); + if (IS_ERR(priv->test_bridges[i])) + return ERR_CAST(priv->test_bridges[i]); + + priv->test_bridges[i]->data =3D priv; + } + + priv->plane =3D drm_kunit_helper_create_primary_plane(test, drm, NULL, NU= LL, + NULL, 0, NULL); + if (IS_ERR(priv->plane)) + return ERR_CAST(priv->plane); + + priv->crtc =3D drm_kunit_helper_create_crtc(test, drm, priv->plane, NULL, + NULL, NULL); + if (IS_ERR(priv->crtc)) + return ERR_CAST(priv->crtc); + + enc =3D &priv->encoder; + ret =3D drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL); + if (ret) + return ERR_PTR(ret); + + enc->possible_crtcs =3D drm_crtc_mask(priv->crtc); + + prev =3D NULL; + for (i =3D 0; i < num_bridges; i++) { + bridge =3D &priv->test_bridges[i]->bridge; + bridge->type =3D DRM_MODE_CONNECTOR_VIRTUAL; + + if (bridge->funcs->hdmi_write_hdmi_infoframe) { + has_hdmi =3D true; + bridge->ops |=3D DRM_BRIDGE_OP_HDMI; + bridge->type =3D DRM_MODE_CONNECTOR_HDMIA; + bridge->vendor =3D "LNX"; + bridge->product =3D "KUnit"; + bridge->supported_formats =3D (BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV444) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV420)); + } + + ret =3D drm_kunit_bridge_add(test, bridge); + if (ret) + return ERR_PTR(ret); + + ret =3D drm_bridge_attach(enc, bridge, prev, 0); + if (ret) + return ERR_PTR(ret); + + prev =3D bridge; + } + + priv->connector =3D drm_bridge_connector_init(drm, enc); + if (IS_ERR(priv->connector)) + return ERR_CAST(priv->connector); + + drm_connector_attach_encoder(priv->connector, enc); + + drm_mode_config_reset(drm); + + if (!has_hdmi) + return priv; + + scoped_guard(mutex, &drm->mode_config.mutex) { + edid =3D drm_edid_alloc(test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_20= 0mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz)); + if (!edid) + return ERR_PTR(-EINVAL); + + drm_edid_connector_update(priv->connector, edid); + KUNIT_ASSERT_GT(test, drm_edid_connector_add_modes(priv->connector), 0); + + ret =3D priv->connector->funcs->fill_modes(priv->connector, 4096, 4096); + } + + return priv; +} + /* * Test that drm_bridge_get_current_state() returns the last committed * state for an atomic bridge. @@ -508,14 +867,441 @@ static struct kunit_suite drm_bridge_alloc_test_suit= e =3D { .test_cases =3D drm_bridge_alloc_tests, }; =20 +/** + * drm_test_bridge_chain_verify_fmt - Verify bridge chain format selection + * @test: pointer to KUnit test object + * @priv: pointer to a &struct drm_bridge_chain_priv for this chain + * @expected: constant array of &struct fmt_tuple describing the expected + * input and output bus formats + * @num_expected: number of entries in @expected + * + * Runs the KUNIT_EXPECT clauses to verify the bridge chain format selecti= on + * resulted in the expected formats. If %0 is given as a format in a + * &struct fmt_tuple, then it is understood to mean "any". + * + * Must be called with the modeset lock held. + */ +static void drm_test_bridge_chain_verify_fmt(struct kunit *test, + struct drm_bridge_chain_priv *priv, + const struct fmt_tuple *const expected, + const unsigned int num_expected) +{ + struct drm_bridge_state *bstate; + unsigned int i =3D 0; + + drm_for_each_bridge_in_chain_scoped(&priv->encoder, bridge) { + KUNIT_ASSERT_LT(test, i, num_expected); + + bstate =3D drm_bridge_get_current_state(bridge); + if (expected[i].in_fmt) + KUNIT_EXPECT_EQ(test, bstate->input_bus_cfg.format, + expected[i].in_fmt); + if (expected[i].out_fmt) + KUNIT_EXPECT_EQ(test, bstate->output_bus_cfg.format, + expected[i].out_fmt); + + i++; + } + + KUNIT_ASSERT_EQ_MSG(test, i, num_expected, + "Fewer bridges (%u) than expected (%u)\n", i, num_expected); +} + +/* + * Test that constructs a bridge chain in which an RGB888 producer is chai= ned to + * two bridges that will convert from RGB to YUV and from YUV to RGB respe= ctively. + * + * The test requests an output color_format of RGB using the color_format = property, + * so to satisfy this request, the bridge chain must take a detour over YU= V. + */ +static void drm_test_bridge_rgb_yuv_rgb(struct kunit *test) +{ + static const struct drm_bridge_funcs *funcs[] =3D { + &rgb_producer_funcs, + &rgb8_to_yuv8_or_id_funcs, + &yuv8_to_rgb8_or_id_funcs, + }; + static const struct fmt_tuple expected[] =3D { + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, + }; + struct drm_connector_state *conn_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_bridge_chain_priv *priv; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + int ret; + + priv =3D drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + drm_modeset_acquire_init(&ctx, 0); + + state =3D drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_commit: + conn_state =3D drm_atomic_get_connector_state(state, priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + mode =3D drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); + + conn_state->color_format =3D DRM_COLOR_FORMAT_ENUM_RGB444; + + ret =3D drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state =3D drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret =3D drm_atomic_set_mode_for_crtc(crtc_state, mode); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable =3D true; + crtc_state->active =3D true; + + ret =3D drm_atomic_commit(state); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expecte= d)); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +/* + * Test in which a bridge capable of producing RGB, YUV444 and YUV420 has = to + * produce RGB and convert with a downstream bridge in the chain to reach = the + * requested YUV444 color format, as no direct path exists between its YUV= 444 + * and the last bridge. + * + * The rationale behind this test is to devise a scenario in which naively + * assuming any format the video processor can output, and the connector + * requests, is the right format to pick, does not work. + */ +static void drm_test_bridge_must_convert_to_yuv444(struct kunit *test) +{ + static const struct drm_bridge_funcs *funcs[] =3D { + &rgb_yuv444_yuv420_producer_funcs, + &rgb8_passthrough_funcs, + &rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420_funcs, + &rgb8_yuv444_yuv422_passthrough_funcs, + }; + static const struct fmt_tuple expected[] =3D { + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + }; + struct drm_connector_state *conn_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_bridge_chain_priv *priv; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + int ret; + + priv =3D drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + drm_modeset_acquire_init(&ctx, 0); + + state =3D drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_commit: + conn_state =3D drm_atomic_get_connector_state(state, priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + mode =3D drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); + + conn_state->color_format =3D DRM_COLOR_FORMAT_ENUM_YCBCR444; + + ret =3D drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state =3D drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret =3D drm_atomic_set_mode_for_crtc(crtc_state, mode); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable =3D true; + crtc_state->active =3D true; + + ret =3D drm_atomic_commit(state); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expecte= d)); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +/* + * Test which checks that no matter the order of bus formats returned by an + * HDMI bridge, RGB is preferred on DRM_COLOR_FORMAT_AUTO if it's availabl= e. + */ +static void drm_test_bridge_hdmi_auto_rgb(struct kunit *test) +{ + static const struct drm_bridge_funcs *funcs[] =3D { + &rgb_yuv444_yuv420_producer_funcs, + &yuv444_yuv422_rgb8_passthrough_hdmi_funcs, + }; + static const struct fmt_tuple expected[] =3D { + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 }, + { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 }, + }; + struct drm_connector_state *conn_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_bridge_chain_priv *priv; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + int ret; + + priv =3D drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + drm_modeset_acquire_init(&ctx, 0); + + state =3D drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_commit: + conn_state =3D drm_atomic_get_connector_state(state, priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + mode =3D drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); + + KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_COLOR_FORMAT_ENUM_AUT= O); + + ret =3D drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state =3D drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret =3D drm_atomic_set_mode_for_crtc(crtc_state, mode); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable =3D true; + crtc_state->active =3D true; + + ret =3D drm_atomic_commit(state); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB= ); + + drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expecte= d)); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +/* + * Test which checks that DRM_COLOR_FORMAT_AUTO on non-HDMI connectors will + * result in the first bus format on the output to be picked. + */ +static void drm_test_bridge_auto_first(struct kunit *test) +{ + static const struct drm_bridge_funcs *funcs[] =3D { + &rgb_yuv444_yuv420_producer_funcs, + &yuv444_yuv422_rgb8_passthrough_funcs, + }; + static const struct fmt_tuple expected[] =3D { + { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_YUV8_1X24 }, + { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 }, + }; + struct drm_connector_state *conn_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_bridge_chain_priv *priv; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + int ret; + + priv =3D drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + drm_modeset_acquire_init(&ctx, 0); + + state =3D drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_commit: + conn_state =3D drm_atomic_get_connector_state(state, priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + mode =3D drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); + + KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_COLOR_FORMAT_ENUM_AUT= O); + + ret =3D drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state =3D drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret =3D drm_atomic_set_mode_for_crtc(crtc_state, mode); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable =3D true; + crtc_state->active =3D true; + + ret =3D drm_atomic_commit(state); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expecte= d)); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +/* + * Test which checks that in a configuration of bridge chains where an RGB + * producer is hooked to a YUV444-only pass-through, the atomic commit fai= ls as + * the bridge format selection cannot find a valid sequence of bus formats. + */ +static void drm_test_bridge_rgb_yuv_no_path(struct kunit *test) +{ + static const struct drm_bridge_funcs *funcs[] =3D { + &rgb_producer_funcs, + &yuv8_passthrough_funcs, + &rgb8_yuv444_yuv422_passthrough_funcs, + }; + struct drm_connector_state *conn_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_bridge_chain_priv *priv; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + int ret; + + priv =3D drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + drm_modeset_acquire_init(&ctx, 0); + + state =3D drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_commit: + conn_state =3D drm_atomic_get_connector_state(state, priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + mode =3D drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); + + ret =3D drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state =3D drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret =3D drm_atomic_set_mode_for_crtc(crtc_state, mode); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable =3D true; + crtc_state->active =3D true; + + ret =3D drm_atomic_commit(state); + if (ret =3D=3D -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_EXPECT_EQ(test, ret, -ENOTSUPP); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +static struct kunit_case drm_bridge_bus_fmt_tests[] =3D { + KUNIT_CASE(drm_test_bridge_rgb_yuv_rgb), + KUNIT_CASE(drm_test_bridge_must_convert_to_yuv444), + KUNIT_CASE(drm_test_bridge_hdmi_auto_rgb), + KUNIT_CASE(drm_test_bridge_auto_first), + KUNIT_CASE(drm_test_bridge_rgb_yuv_no_path), + { } +}; + +static struct kunit_suite drm_bridge_bus_fmt_test_suite =3D { + .name =3D "drm_bridge_bus_fmt", + .test_cases =3D drm_bridge_bus_fmt_tests, +}; + kunit_test_suites( &drm_bridge_get_current_state_test_suite, &drm_bridge_helper_reset_crtc_test_suite, &drm_bridge_alloc_test_suite, + &drm_bridge_bus_fmt_test_suite, ); =20 MODULE_AUTHOR("Maxime Ripard "); MODULE_AUTHOR("Luca Ceresoli "); +MODULE_AUTHOR("Nicolas Frattaroli "); =20 MODULE_DESCRIPTION("Kunit test for drm_bridge functions"); MODULE_LICENSE("GPL"); --=20 2.53.0 From nobody Thu Mar 19 02:06:34 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 221092F7478; Mon, 16 Feb 2026 13:05:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247145; cv=pass; b=UaQ//GMEwgA/hENuyY9+K89Tt9kia6UxRonCdn7+x4pU6r2M3xaB+b+U2bg8vlDtwrDa7VdfMbf40ZtHYVVVwgp+Be9TsdR3k6NXlKtn4KefWfd/lp6SX7UPqpJ6aSIqnT+6XEsrqSheoYlamZH4yriIsLKEGR8WMrPSdLEy8v8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771247145; c=relaxed/simple; bh=/URkidl3+6ChhKo9c9FLA5j1KSHZariG0I8xvDpJ6mQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DHsXJDY4lwKRACa1yHvfDWv6D8ftNt8Qg85a/G8S3ihw9lamp3DWexHpFYR4D3st6L0C1AxWS3VqJEebUYdlZiMrirPdvvJlaRxypGCKtpZkKFmadC02GkZAwZJF0y/5U0M08x6fxUcYqrS2Z5gn4Bt0UMIkIVXUl+1XDJTOukE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=TpI+HGfu; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="TpI+HGfu" ARC-Seal: i=1; a=rsa-sha256; t=1771247041; cv=none; d=zohomail.com; s=zohoarc; b=aO0ol4Xm+xfSjJiCg+KyUrIbHnPu1MP5NQXAn+fpRSArMd6fOLQYeoPXXZFu4kXkCkYHWZ/uwS5YarOe+IAmPSz197YyErZu17YYGSpslD0YqZWnZ7Q+EUb5RVM+pN3oQ030629G6+VWS1/ebTo36oot4cFbqDhTC21a2bcVHyA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771247041; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=BLlh5tMdDTOTAyn9YXs6jsTluhyEk/QVY+om/HYDdXE=; b=ZlUC/2ufWjGMMl2ldxRbthgi1flf0CzzrE4/v7aIbmaaFtLfdRT7cmUjVC1qZw4BaiBEW/dqAeGBgOkOkIshe40sd+6cumfi6FN6IXsT5Hr1MD/gBgzM7fdKwFyIAeZm9WTdlauOfOdebp/ME/Z8EDfIUwAjLvIxzzOhE1qmB5g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1771247041; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=BLlh5tMdDTOTAyn9YXs6jsTluhyEk/QVY+om/HYDdXE=; b=TpI+HGfux3uM6fju3juoVVawKSOOV0jpAVViySf0ijaf9LfryH8gpsfApa/jfs0T njFbv9/MpcCNi+e8oDL4aWVI2hIGx8j144YeGxhN3L1qbcrC4xWk/HQtHdGy0hP5Gw/ cA/WBxu0VwXUvswYeqwv2/Pu6eSbpDxt2oqfnkSo= Received: by mx.zohomail.com with SMTPS id 1771247040667463.91219852265397; Mon, 16 Feb 2026 05:04:00 -0800 (PST) From: Nicolas Frattaroli Date: Mon, 16 Feb 2026 14:01:34 +0100 Subject: [PATCH v8 20/20] drm/bridge: Document bridge chain format selection Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-color-format-v8-20-5722ce175dd5@collabora.com> References: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> In-Reply-To: <20260216-color-format-v8-0-5722ce175dd5@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 The bridge chain format selection behaviour was, until now, undocumented. With the addition of the "color format" DRM property, it's not sufficiently complex enough that documentation is warranted, especially for driver authors trying to do the right thing. Add a high-level overview of how the process is supposed to work, and mention what the display driver is supposed to do if it wants to make use of this functionality. Reviewed-by: Maxime Ripard Signed-off-by: Nicolas Frattaroli --- Documentation/gpu/drm-kms-helpers.rst | 6 ++++++ drivers/gpu/drm/drm_bridge.c | 39 +++++++++++++++++++++++++++++++= ++++ 2 files changed, 45 insertions(+) diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-= kms-helpers.rst index 781129f78b06..47c4f593cf9d 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -181,6 +181,12 @@ Bridge Operations .. kernel-doc:: drivers/gpu/drm/drm_bridge.c :doc: bridge operations =20 +Bridge Chain Format Selection +----------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :doc: bridge chain format selection + Bridge Connector Helper ----------------------- =20 diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 36a5158f0554..93ef52c37e2c 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -198,6 +198,45 @@ * driver. */ =20 +/** + * DOC: bridge chain format selection + * + * A bridge chain, from display output processor to connector, may contain + * bridges capable of converting between bus formats on their inputs, and + * output formats on their outputs. For example, a bridge may be able to c= onvert + * from RGB to YCbCr 4:4:4, and pass through YCbCr 4:2:0 as-is, but not co= nvert + * from RGB to YCbCr 4:2:0. This means not all input formats map to all ou= tput + * formats. + * + * Further adding to this, a desired output color format, as specified wit= h the + * "color format" DRM property, might not correspond to what the display d= river + * should set at its output 1:1. The bridge chain it feeds into may only b= e able + * to reach the desired output format, if a conversion from a different st= arting + * format is performed. + * + * To deal with this complexity, the recursive bridge chain bus format sel= ection + * logic starts with the last bridge in the chain, usually the connector, = and + * then recursively walks the chain of bridges backwards to the first brid= ge, + * trying to find a path. + * + * For a display driver to work in such a scenario, it should read the fir= st + * bridge's bridge state to figure out which bus format the chain resolved= to. + * If the first bridge's input format resolved to %MEDIA_BUS_FMT_FIXED, th= en its + * output format should be used. + * + * Special handling is done for HDMI as it relates to format selection. In= stead + * of directly using the "color format" DRM property for bridge chains tha= t end + * in HDMI bridges, the bridge chain format selection logic will trust the= logic + * that set the HDMI output format. For the common HDMI state helper + * functionality, this means that %DRM_COLOR_FORMAT_ENUM_AUTO will allow + * fallbacks to YCBCr 4:2:0 if the bandwidth requirements would otherwise = be too + * high but the mode and connector allow it. + * + * For bridge chains that do not end in an HDMI bridge, + * %DRM_COLOR_FORMAT_ENUM_AUTO will be satisfied with the first output for= mat on + * the last bridge for which it can find a path back to the first bridge. + */ + /* Protect bridge_list and bridge_lingering_list */ static DEFINE_MUTEX(bridge_lock); static LIST_HEAD(bridge_list); --=20 2.53.0