* [PATCH RFC 1/3] drm/amd/display: quirk malformed CH7218 PCON topology
@ 2026-06-20 16:06 ` Stephen
0 siblings, 0 replies; 7+ messages in thread
From: Stephen via B4 Relay @ 2026-06-20 16:06 UTC (permalink / raw)
To: amd-gfx
Cc: Stephen, dri-devel, linux-kernel, Harry Wentland, Leo Li,
Rodrigo Siqueira, Alex Deucher, Christian König,
David Airlie, Simona Vetter, Tomasz Pakuła
From: Stephen <stevester.codes@gmail.com>
Some Chrontel CH7218 DP-to-HDMI 2.1 adapters expose a branch
device ID of 0x2b02f0 and branch name CH7218, but report no
downstream port at DPCD 0x005 and report the detailed downstream
port at 0x080 as DP.
This leaves AMDGPU treating the link as non-HDMI and bypasses the
PCON capability path.
When this malformed runtime state is detected, classify the link as a
DP-HDMI converter and restore the documented converter ceilings needed
by the existing PCON path: 12 bpc, 48 Gbps FRL, and YCbCr passthrough
capability. This does not program the PCON or synthesize source-control
FRL state.
Signed-off-by: Stephen <stevester.codes@gmail.com>
---
.../display/dc/link/protocols/link_dp_capability.c | 47 ++++++++++++++++++++--
.../drm/amd/display/include/ddc_service_types.h | 1 +
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index 47abb4066709..c2b48abfe7e6 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -1158,6 +1158,31 @@ static void read_and_intersect_post_frl_lt_status(
}
}
+static bool is_ch7218_pcon(const struct dc_link *link)
+{
+ return link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_2B02F0 &&
+ !memcmp(link->dpcd_caps.branch_dev_name, "CH7218",
+ sizeof(link->dpcd_caps.branch_dev_name));
+}
+
+static void apply_ch7218_pcon_caps_quirk(struct dc_link *link)
+{
+ if (!link->dc->caps.dp_hdmi21_pcon_support)
+ return;
+
+ /*
+ * Some CH7218 firmware reports no downstream port, or reports the
+ * detailed downstream port as DP, while the device identity and EDID
+ * describe a DP-to-HDMI 2.1 PCON. Restore only the documented converter
+ * capability ceilings here; do not touch the PCON link state.
+ */
+ link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc = 12;
+ link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = 48000000;
+ link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through = true;
+ link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through = true;
+ link->dpcd_caps.dongle_caps.extendedCapValid = true;
+}
+
static void get_active_converter_info(
uint8_t data, struct dc_link *link)
{
@@ -1166,10 +1191,19 @@ static void get_active_converter_info(
/* decode converter info*/
if (!ds_port.fields.PORT_PRESENT) {
- link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
+ if (is_ch7218_pcon(link)) {
+ link->dpcd_caps.is_branch_dev = true;
+ link->dpcd_caps.dongle_type =
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER;
+ link->dpcd_caps.dongle_caps.dongle_type =
+ link->dpcd_caps.dongle_type;
+ apply_ch7218_pcon_caps_quirk(link);
+ } else {
+ link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
+ link->dpcd_caps.is_branch_dev = false;
+ }
set_dongle_type(link->ddc,
link->dpcd_caps.dongle_type);
- link->dpcd_caps.is_branch_dev = false;
return;
}
@@ -1200,7 +1234,14 @@ static void get_active_converter_info(
switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
/*Handle DP case as DONGLE_NONE*/
case DOWN_STREAM_DETAILED_DP:
- link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
+ link->dpcd_caps.dongle_type = is_ch7218_pcon(link) ?
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER :
+ DISPLAY_DONGLE_NONE;
+ link->dpcd_caps.dongle_caps.dongle_type =
+ link->dpcd_caps.dongle_type;
+ if (link->dpcd_caps.dongle_type ==
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER)
+ apply_ch7218_pcon_caps_quirk(link);
break;
case DOWN_STREAM_DETAILED_VGA:
link->dpcd_caps.dongle_type =
diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
index 53210e3aa0e0..4164f8a5ae56 100644
--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
@@ -37,6 +37,7 @@
#define DP_BRANCH_DEVICE_ID_001CF8 0x001CF8
#define DP_BRANCH_DEVICE_ID_0060AD 0x0060AD
#define DP_BRANCH_DEVICE_ID_001FF2 0x001FF2
+#define DP_BRANCH_DEVICE_ID_2B02F0 0x2B02F0
#define DP_BRANCH_HW_REV_10 0x10
#define DP_BRANCH_HW_REV_20 0x20
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC 1/3] drm/amd/display: quirk malformed CH7218 PCON topology
@ 2026-06-20 16:06 ` Stephen
0 siblings, 0 replies; 7+ messages in thread
From: Stephen @ 2026-06-20 16:06 UTC (permalink / raw)
To: amd-gfx
Cc: Stephen, dri-devel, linux-kernel, Harry Wentland, Leo Li,
Rodrigo Siqueira, Alex Deucher, Christian König,
David Airlie, Simona Vetter, Tomasz Pakuła
Some Chrontel CH7218 DP-to-HDMI 2.1 adapters expose a branch
device ID of 0x2b02f0 and branch name CH7218, but report no
downstream port at DPCD 0x005 and report the detailed downstream
port at 0x080 as DP.
This leaves AMDGPU treating the link as non-HDMI and bypasses the
PCON capability path.
When this malformed runtime state is detected, classify the link as a
DP-HDMI converter and restore the documented converter ceilings needed
by the existing PCON path: 12 bpc, 48 Gbps FRL, and YCbCr passthrough
capability. This does not program the PCON or synthesize source-control
FRL state.
Signed-off-by: Stephen <stevester.codes@gmail.com>
---
.../display/dc/link/protocols/link_dp_capability.c | 47 ++++++++++++++++++++--
.../drm/amd/display/include/ddc_service_types.h | 1 +
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index 47abb4066709..c2b48abfe7e6 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -1158,6 +1158,31 @@ static void read_and_intersect_post_frl_lt_status(
}
}
+static bool is_ch7218_pcon(const struct dc_link *link)
+{
+ return link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_2B02F0 &&
+ !memcmp(link->dpcd_caps.branch_dev_name, "CH7218",
+ sizeof(link->dpcd_caps.branch_dev_name));
+}
+
+static void apply_ch7218_pcon_caps_quirk(struct dc_link *link)
+{
+ if (!link->dc->caps.dp_hdmi21_pcon_support)
+ return;
+
+ /*
+ * Some CH7218 firmware reports no downstream port, or reports the
+ * detailed downstream port as DP, while the device identity and EDID
+ * describe a DP-to-HDMI 2.1 PCON. Restore only the documented converter
+ * capability ceilings here; do not touch the PCON link state.
+ */
+ link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc = 12;
+ link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = 48000000;
+ link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through = true;
+ link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through = true;
+ link->dpcd_caps.dongle_caps.extendedCapValid = true;
+}
+
static void get_active_converter_info(
uint8_t data, struct dc_link *link)
{
@@ -1166,10 +1191,19 @@ static void get_active_converter_info(
/* decode converter info*/
if (!ds_port.fields.PORT_PRESENT) {
- link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
+ if (is_ch7218_pcon(link)) {
+ link->dpcd_caps.is_branch_dev = true;
+ link->dpcd_caps.dongle_type =
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER;
+ link->dpcd_caps.dongle_caps.dongle_type =
+ link->dpcd_caps.dongle_type;
+ apply_ch7218_pcon_caps_quirk(link);
+ } else {
+ link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
+ link->dpcd_caps.is_branch_dev = false;
+ }
set_dongle_type(link->ddc,
link->dpcd_caps.dongle_type);
- link->dpcd_caps.is_branch_dev = false;
return;
}
@@ -1200,7 +1234,14 @@ static void get_active_converter_info(
switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
/*Handle DP case as DONGLE_NONE*/
case DOWN_STREAM_DETAILED_DP:
- link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
+ link->dpcd_caps.dongle_type = is_ch7218_pcon(link) ?
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER :
+ DISPLAY_DONGLE_NONE;
+ link->dpcd_caps.dongle_caps.dongle_type =
+ link->dpcd_caps.dongle_type;
+ if (link->dpcd_caps.dongle_type ==
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER)
+ apply_ch7218_pcon_caps_quirk(link);
break;
case DOWN_STREAM_DETAILED_VGA:
link->dpcd_caps.dongle_type =
diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
index 53210e3aa0e0..4164f8a5ae56 100644
--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
@@ -37,6 +37,7 @@
#define DP_BRANCH_DEVICE_ID_001CF8 0x001CF8
#define DP_BRANCH_DEVICE_ID_0060AD 0x0060AD
#define DP_BRANCH_DEVICE_ID_001FF2 0x001FF2
+#define DP_BRANCH_DEVICE_ID_2B02F0 0x2B02F0
#define DP_BRANCH_HW_REV_10 0x10
#define DP_BRANCH_HW_REV_20 0x20
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC 2/3] drm/amd/display: quirk CH7218 DP DSC support bit
2026-06-20 16:06 ` Stephen
@ 2026-06-20 16:06 ` Stephen
-1 siblings, 0 replies; 7+ messages in thread
From: Stephen via B4 Relay @ 2026-06-20 16:06 UTC (permalink / raw)
To: amd-gfx
Cc: Stephen, dri-devel, linux-kernel, Harry Wentland, Leo Li,
Rodrigo Siqueira, Alex Deucher, Christian König,
David Airlie, Simona Vetter, Tomasz Pakuła
From: Stephen <stevester.codes@gmail.com>
Some CH7218 firmware clears DP_DSC_SUPPORT at DPCD 0x060 while
returning a populated DSC decoder capability block. Without the support
bit, AMDGPU rejects DSC on the DP side and cannot validate high-bandwidth
RGB modes that require DSC over the DP link.
For the malformed CH7218 PCON only, set the DSC support bit after
verifying that the DSC capability block contains non-zero decoder data.
Do not infer DSC support for other devices and do not synthesize DSC
passthrough support.
Signed-off-by: Stephen <stevester.codes@gmail.com>
---
.../display/dc/link/protocols/link_dp_capability.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index c2b48abfe7e6..ad4fb94281a8 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -1183,6 +1183,25 @@ static void apply_ch7218_pcon_caps_quirk(struct dc_link *link)
link->dpcd_caps.dongle_caps.extendedCapValid = true;
}
+static void apply_ch7218_dsc_caps_quirk(struct dc_link *link)
+{
+ struct dpcd_dsc_capabilities *dsc_caps = &link->dpcd_caps.dsc_caps;
+
+ if (!is_ch7218_pcon(link) ||
+ dsc_caps->dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
+ (!dsc_caps->dsc_basic_caps.raw[DP_DSC_REV - DP_DSC_SUPPORT] &&
+ !dsc_caps->dsc_basic_caps.raw[DP_DSC_SLICE_CAP_1 - DP_DSC_SUPPORT] &&
+ !dsc_caps->dsc_basic_caps.raw[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT]))
+ return;
+
+ /*
+ * Some CH7218 firmware clears DP_DSC_SUPPORT while returning a populated
+ * DSC decoder capability block. Do not infer DSC support for other
+ * devices and do not enable DSC passthrough here.
+ */
+ dsc_caps->dsc_basic_caps.fields.dsc_support.DSC_SUPPORT = true;
+}
+
static void get_active_converter_info(
uint8_t data, struct dc_link *link)
{
@@ -2068,6 +2087,7 @@ static bool retrieve_link_cap(struct dc_link *link)
link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
if (status == DC_OK) {
+ apply_ch7218_dsc_caps_quirk(link);
is_fec_supported = link->dpcd_caps.fec_cap.bits.FEC_CAPABLE;
is_dsc_basic_supported = link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT;
is_dsc_passthrough_supported = link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT;
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC 2/3] drm/amd/display: quirk CH7218 DP DSC support bit
@ 2026-06-20 16:06 ` Stephen
0 siblings, 0 replies; 7+ messages in thread
From: Stephen @ 2026-06-20 16:06 UTC (permalink / raw)
To: amd-gfx
Cc: Stephen, dri-devel, linux-kernel, Harry Wentland, Leo Li,
Rodrigo Siqueira, Alex Deucher, Christian König,
David Airlie, Simona Vetter, Tomasz Pakuła
Some CH7218 firmware clears DP_DSC_SUPPORT at DPCD 0x060 while
returning a populated DSC decoder capability block. Without the support
bit, AMDGPU rejects DSC on the DP side and cannot validate high-bandwidth
RGB modes that require DSC over the DP link.
For the malformed CH7218 PCON only, set the DSC support bit after
verifying that the DSC capability block contains non-zero decoder data.
Do not infer DSC support for other devices and do not synthesize DSC
passthrough support.
Signed-off-by: Stephen <stevester.codes@gmail.com>
---
.../display/dc/link/protocols/link_dp_capability.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index c2b48abfe7e6..ad4fb94281a8 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -1183,6 +1183,25 @@ static void apply_ch7218_pcon_caps_quirk(struct dc_link *link)
link->dpcd_caps.dongle_caps.extendedCapValid = true;
}
+static void apply_ch7218_dsc_caps_quirk(struct dc_link *link)
+{
+ struct dpcd_dsc_capabilities *dsc_caps = &link->dpcd_caps.dsc_caps;
+
+ if (!is_ch7218_pcon(link) ||
+ dsc_caps->dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
+ (!dsc_caps->dsc_basic_caps.raw[DP_DSC_REV - DP_DSC_SUPPORT] &&
+ !dsc_caps->dsc_basic_caps.raw[DP_DSC_SLICE_CAP_1 - DP_DSC_SUPPORT] &&
+ !dsc_caps->dsc_basic_caps.raw[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT]))
+ return;
+
+ /*
+ * Some CH7218 firmware clears DP_DSC_SUPPORT while returning a populated
+ * DSC decoder capability block. Do not infer DSC support for other
+ * devices and do not enable DSC passthrough here.
+ */
+ dsc_caps->dsc_basic_caps.fields.dsc_support.DSC_SUPPORT = true;
+}
+
static void get_active_converter_info(
uint8_t data, struct dc_link *link)
{
@@ -2068,6 +2087,7 @@ static bool retrieve_link_cap(struct dc_link *link)
link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
if (status == DC_OK) {
+ apply_ch7218_dsc_caps_quirk(link);
is_fec_supported = link->dpcd_caps.fec_cap.bits.FEC_CAPABLE;
is_dsc_basic_supported = link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT;
is_dsc_passthrough_supported = link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT;
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC 3/3] drm/amd/display: use HDMI RGB deep color for PCONs
2026-06-20 16:06 ` Stephen
@ 2026-06-20 16:06 ` Stephen
-1 siblings, 0 replies; 7+ messages in thread
From: Stephen via B4 Relay @ 2026-06-20 16:06 UTC (permalink / raw)
To: amd-gfx
Cc: Stephen, dri-devel, linux-kernel, Harry Wentland, Leo Li,
Rodrigo Siqueira, Alex Deucher, Christian König,
David Airlie, Simona Vetter, Tomasz Pakuła
From: Stephen <stevester.codes@gmail.com>
DP-to-HDMI PCON connectors are exposed to DRM as DP connectors, but the
downstream sink capability for RGB deep color is carried in the HDMI CTA
deep-color flags. If AMDGPU only uses the base EDID bpc field for RGB
output, HDMI sinks behind PCONs can be capped at 8 bpc even when the CTA
block advertises RGB 10/12 bpc support.
For RGB output through a recognized DP-HDMI converter, derive the
candidate bpc from edid_hdmi_rgb444_dc_modes before applying the
requested max bpc cap. Keep YCbCr420 on the existing y420 deep-color
path and leave native DP behavior unchanged.
Signed-off-by: Stephen <stevester.codes@gmail.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 41 ++++++++++++++++++-----
1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8f80420e9f0b..3b814b839ddf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6769,22 +6769,44 @@ static void update_stream_scaling_settings(struct drm_device *dev,
static enum dc_color_depth
convert_color_depth_from_display_info(const struct drm_connector *connector,
- bool is_y420, int requested_bpc)
+ enum dc_pixel_encoding pixel_encoding,
+ int requested_bpc)
{
+ const struct drm_display_info *info = &connector->display_info;
+ bool is_hdmi_pcon = false;
u8 bpc;
- if (is_y420) {
+ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
+ const struct amdgpu_dm_connector *aconnector =
+ to_amdgpu_dm_connector(connector);
+
+ is_hdmi_pcon = aconnector->dc_link &&
+ aconnector->dc_link->dpcd_caps.dongle_type ==
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER;
+ }
+
+ if (pixel_encoding == PIXEL_ENCODING_YCBCR420) {
bpc = 8;
/* Cap display bpc based on HDMI 2.0 HF-VSDB */
- if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
+ if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
+ bpc = 16;
+ else if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
+ bpc = 12;
+ else if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
+ bpc = 10;
+ } else if (pixel_encoding == PIXEL_ENCODING_RGB && is_hdmi_pcon) {
+ bpc = 8;
+
+ /* The downstream sink is HDMI even though DRM exposes DP. */
+ if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_48)
bpc = 16;
- else if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
+ else if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)
bpc = 12;
- else if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
+ else if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)
bpc = 10;
} else {
- bpc = (uint8_t)connector->display_info.bpc;
+ bpc = (uint8_t)info->bpc;
/* Assume 8 bpc by default if no bpc is specified. */
bpc = bpc ? bpc : 8;
}
@@ -7004,7 +7026,7 @@ static void fill_stream_properties_from_drm_display_mode(
timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
timing_out->display_color_depth = convert_color_depth_from_display_info(
connector,
- (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420),
+ timing_out->pixel_encoding,
requested_bpc);
timing_out->scan_type = SCANNING_TYPE_NODATA;
timing_out->hdmi_vic = 0;
@@ -8761,6 +8783,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
struct drm_dp_mst_port *mst_port;
struct drm_dp_mst_topology_state *mst_state;
enum dc_color_depth color_depth;
+ enum dc_pixel_encoding pixel_encoding = PIXEL_ENCODING_RGB;
int clock, bpp = 0;
bool is_y420 = false;
@@ -8801,8 +8824,10 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
is_y420 = drm_mode_is_420_also(&connector->display_info, adjusted_mode) &&
aconnector->force_yuv420_output;
+ if (is_y420)
+ pixel_encoding = PIXEL_ENCODING_YCBCR420;
color_depth = convert_color_depth_from_display_info(connector,
- is_y420,
+ pixel_encoding,
max_bpc);
bpp = convert_dc_color_depth_into_bpc(color_depth) * 3;
clock = adjusted_mode->clock;
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC 3/3] drm/amd/display: use HDMI RGB deep color for PCONs
@ 2026-06-20 16:06 ` Stephen
0 siblings, 0 replies; 7+ messages in thread
From: Stephen @ 2026-06-20 16:06 UTC (permalink / raw)
To: amd-gfx
Cc: Stephen, dri-devel, linux-kernel, Harry Wentland, Leo Li,
Rodrigo Siqueira, Alex Deucher, Christian König,
David Airlie, Simona Vetter, Tomasz Pakuła
DP-to-HDMI PCON connectors are exposed to DRM as DP connectors, but the
downstream sink capability for RGB deep color is carried in the HDMI CTA
deep-color flags. If AMDGPU only uses the base EDID bpc field for RGB
output, HDMI sinks behind PCONs can be capped at 8 bpc even when the CTA
block advertises RGB 10/12 bpc support.
For RGB output through a recognized DP-HDMI converter, derive the
candidate bpc from edid_hdmi_rgb444_dc_modes before applying the
requested max bpc cap. Keep YCbCr420 on the existing y420 deep-color
path and leave native DP behavior unchanged.
Signed-off-by: Stephen <stevester.codes@gmail.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 41 ++++++++++++++++++-----
1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8f80420e9f0b..3b814b839ddf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6769,22 +6769,44 @@ static void update_stream_scaling_settings(struct drm_device *dev,
static enum dc_color_depth
convert_color_depth_from_display_info(const struct drm_connector *connector,
- bool is_y420, int requested_bpc)
+ enum dc_pixel_encoding pixel_encoding,
+ int requested_bpc)
{
+ const struct drm_display_info *info = &connector->display_info;
+ bool is_hdmi_pcon = false;
u8 bpc;
- if (is_y420) {
+ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
+ const struct amdgpu_dm_connector *aconnector =
+ to_amdgpu_dm_connector(connector);
+
+ is_hdmi_pcon = aconnector->dc_link &&
+ aconnector->dc_link->dpcd_caps.dongle_type ==
+ DISPLAY_DONGLE_DP_HDMI_CONVERTER;
+ }
+
+ if (pixel_encoding == PIXEL_ENCODING_YCBCR420) {
bpc = 8;
/* Cap display bpc based on HDMI 2.0 HF-VSDB */
- if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
+ if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
+ bpc = 16;
+ else if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
+ bpc = 12;
+ else if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
+ bpc = 10;
+ } else if (pixel_encoding == PIXEL_ENCODING_RGB && is_hdmi_pcon) {
+ bpc = 8;
+
+ /* The downstream sink is HDMI even though DRM exposes DP. */
+ if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_48)
bpc = 16;
- else if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
+ else if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)
bpc = 12;
- else if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
+ else if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)
bpc = 10;
} else {
- bpc = (uint8_t)connector->display_info.bpc;
+ bpc = (uint8_t)info->bpc;
/* Assume 8 bpc by default if no bpc is specified. */
bpc = bpc ? bpc : 8;
}
@@ -7004,7 +7026,7 @@ static void fill_stream_properties_from_drm_display_mode(
timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
timing_out->display_color_depth = convert_color_depth_from_display_info(
connector,
- (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420),
+ timing_out->pixel_encoding,
requested_bpc);
timing_out->scan_type = SCANNING_TYPE_NODATA;
timing_out->hdmi_vic = 0;
@@ -8761,6 +8783,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
struct drm_dp_mst_port *mst_port;
struct drm_dp_mst_topology_state *mst_state;
enum dc_color_depth color_depth;
+ enum dc_pixel_encoding pixel_encoding = PIXEL_ENCODING_RGB;
int clock, bpp = 0;
bool is_y420 = false;
@@ -8801,8 +8824,10 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
is_y420 = drm_mode_is_420_also(&connector->display_info, adjusted_mode) &&
aconnector->force_yuv420_output;
+ if (is_y420)
+ pixel_encoding = PIXEL_ENCODING_YCBCR420;
color_depth = convert_color_depth_from_display_info(connector,
- is_y420,
+ pixel_encoding,
max_bpc);
bpp = convert_dc_color_depth_into_bpc(color_depth) * 3;
clock = adjusted_mode->clock;
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH RFC 3/3] drm/amd/display: use HDMI RGB deep color for PCONs
2026-06-20 16:06 ` Stephen
(?)
@ 2026-06-20 16:19 ` sashiko-bot
-1 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-06-20 16:19 UTC (permalink / raw)
To: Stephen via B4 Relay; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing DP-to-HDMI PCON capability check for deep color configuration causes atomic check failures.
- [Medium] PCON detection logic fails to correctly identify HDMI ports on MST hubs, excluding them from deep color support.
--
commit 2c95bd6347ca4e92cbbbdffd678f070e97b84a9d
Author: Stephen <stevester.codes@gmail.com>
drm/amd/display: use HDMI RGB deep color for PCONs
This commit updates the DRM AMD display driver to support HDMI RGB deep color
for PCON connectors. It derives the candidate bpc from edid_hdmi_rgb444_dc_modes
when an RGB output is routed through a recognized DP-to-HDMI converter.
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index f8c13bad4ac23..02ffc1563e699 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
[ ... ]
> @@ -6582,22 +6582,44 @@ static void update_stream_scaling_settings(struct drm_device *dev,
>
> static enum dc_color_depth
> convert_color_depth_from_display_info(const struct drm_connector *connector,
> - bool is_y420, int requested_bpc)
> + enum dc_pixel_encoding pixel_encoding,
> + int requested_bpc)
> {
> + const struct drm_display_info *info = &connector->display_info;
> + bool is_hdmi_pcon = false;
> u8 bpc;
>
> - if (is_y420) {
> + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
> + const struct amdgpu_dm_connector *aconnector =
> + to_amdgpu_dm_connector(connector);
> +
> + is_hdmi_pcon = aconnector->dc_link &&
> + aconnector->dc_link->dpcd_caps.dongle_type ==
> + DISPLAY_DONGLE_DP_HDMI_CONVERTER;
[Severity: Medium]
For MST leaf connectors, aconnector->dc_link represents the primary link
to the MST hub rather than the downstream leaf port.
Since the root link typically identifies as a branch device, will this
evaluate to false for MST setups and exclude HDMI sinks connected via
MST hubs from deep color support?
> + }
> +
> + if (pixel_encoding == PIXEL_ENCODING_YCBCR420) {
> bpc = 8;
>
> /* Cap display bpc based on HDMI 2.0 HF-VSDB */
> - if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
> + if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
> + bpc = 16;
> + else if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
> + bpc = 12;
> + else if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
> + bpc = 10;
> + } else if (pixel_encoding == PIXEL_ENCODING_RGB && is_hdmi_pcon) {
> + bpc = 8;
> +
> + /* The downstream sink is HDMI even though DRM exposes DP. */
> + if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_48)
> bpc = 16;
> - else if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
> + else if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)
> bpc = 12;
> - else if (connector->display_info.hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
> + else if (info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)
> bpc = 10;
[Severity: High]
This logic sets the bpc based on the downstream HDMI sink's capabilities, but
does it also need to be constrained by the PCON's maximum bpc limit?
If a sink supports 12 bpc but the PCON only supports 8 bpc, will skipping a
check against aconnector->dc_link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc
cause dp_active_dongle_validate_timing() to fail and reject the atomic commit?
> } else {
> - bpc = (uint8_t)connector->display_info.bpc;
> + bpc = (uint8_t)info->bpc;
> /* Assume 8 bpc by default if no bpc is specified. */
> bpc = bpc ? bpc : 8;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260620-ch7218-rfc-v1-b4-v1-1-3412debf44b6@gmail.com?part=3
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-20 16:19 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-20 16:06 [PATCH RFC 1/3] drm/amd/display: quirk malformed CH7218 PCON topology Stephen via B4 Relay
2026-06-20 16:06 ` Stephen
2026-06-20 16:06 ` [PATCH RFC 2/3] drm/amd/display: quirk CH7218 DP DSC support bit Stephen via B4 Relay
2026-06-20 16:06 ` Stephen
2026-06-20 16:06 ` [PATCH RFC 3/3] drm/amd/display: use HDMI RGB deep color for PCONs Stephen via B4 Relay
2026-06-20 16:06 ` Stephen
2026-06-20 16:19 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.