summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamon Ding <damon.ding@rock-chips.com>2025-12-17 17:33:04 +0800
committerLuca Ceresoli <luca.ceresoli@bootlin.com>2026-02-03 12:43:04 +0100
commit3c05e956b85e70cbd5042e03f615b23ca4635385 (patch)
tree74d42827700c04b52fb2e1cc37264430f6721d6f
parent5c323ea948ff0f9e50418119cbbb3d94f2bd6a96 (diff)
downloadlinux-3c05e956b85e70cbd5042e03f615b23ca4635385.tar.gz
linux-3c05e956b85e70cbd5042e03f615b23ca4635385.zip
drm/display: bridge_connector: Ensure last bridge determines EDID/modes detection capabilities
When multiple bridges are present, EDID detection capability (DRM_BRIDGE_OP_EDID) takes precedence over modes detection (DRM_BRIDGE_OP_MODES). To ensure the above two capabilities are determined by the last bridge in the chain, we handle three cases: Case 1: The later bridge declares only DRM_BRIDGE_OP_MODES - If the previous bridge declares DRM_BRIDGE_OP_EDID, set &drm_bridge_connector.bridge_edid to NULL and set &drm_bridge_connector.bridge_modes to the later bridge. - Ensure modes detection capability of the later bridge will not be ignored. Case 2: The later bridge declares only DRM_BRIDGE_OP_EDID - If the previous bridge declares DRM_BRIDGE_OP_MODES, set &drm_bridge_connector.bridge_modes to NULL and set &drm_bridge_connector.bridge_edid to the later bridge. - Although EDID detection capability has higher priority, this operation is for balance and makes sense. Case 3: the later bridge declares both of them - Assign later bridge as &drm_bridge_connector.bridge_edid and and &drm_bridge_connector.bridge_modes to this bridge. - Just leave transfer of these two capabilities as before. Signed-off-by: Damon Ding <damon.ding@rock-chips.com> Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Tested-by: Heiko Stuebner <heiko@sntech.de> (on rk3588) Link: https://patch.msgid.link/20251217093321.3108939-2-damon.ding@rock-chips.com Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
-rw-r--r--drivers/gpu/drm/display/drm_bridge_connector.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index ba8ff113cff1..d49ccf28d2b2 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -826,9 +826,19 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
if (!bridge->ycbcr_420_allowed)
connector->ycbcr_420_allowed = false;
- if (bridge->ops & DRM_BRIDGE_OP_EDID) {
+ /*
+ * Ensure the last bridge declares OP_EDID or OP_MODES or both.
+ */
+ if (bridge->ops & DRM_BRIDGE_OP_EDID || bridge->ops & DRM_BRIDGE_OP_MODES) {
drm_bridge_put(bridge_connector->bridge_edid);
- bridge_connector->bridge_edid = drm_bridge_get(bridge);
+ bridge_connector->bridge_edid = NULL;
+ drm_bridge_put(bridge_connector->bridge_modes);
+ bridge_connector->bridge_modes = NULL;
+
+ if (bridge->ops & DRM_BRIDGE_OP_EDID)
+ bridge_connector->bridge_edid = drm_bridge_get(bridge);
+ if (bridge->ops & DRM_BRIDGE_OP_MODES)
+ bridge_connector->bridge_modes = drm_bridge_get(bridge);
}
if (bridge->ops & DRM_BRIDGE_OP_HPD) {
drm_bridge_put(bridge_connector->bridge_hpd);
@@ -838,10 +848,6 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
drm_bridge_put(bridge_connector->bridge_detect);
bridge_connector->bridge_detect = drm_bridge_get(bridge);
}
- if (bridge->ops & DRM_BRIDGE_OP_MODES) {
- drm_bridge_put(bridge_connector->bridge_modes);
- bridge_connector->bridge_modes = drm_bridge_get(bridge);
- }
if (bridge->ops & DRM_BRIDGE_OP_HDMI) {
if (bridge_connector->bridge_hdmi)
return ERR_PTR(-EBUSY);