diff options
| author | Damon Ding <damon.ding@rock-chips.com> | 2025-12-17 17:33:04 +0800 |
|---|---|---|
| committer | Luca Ceresoli <luca.ceresoli@bootlin.com> | 2026-02-03 12:43:04 +0100 |
| commit | 3c05e956b85e70cbd5042e03f615b23ca4635385 (patch) | |
| tree | 74d42827700c04b52fb2e1cc37264430f6721d6f /drivers | |
| parent | 5c323ea948ff0f9e50418119cbbb3d94f2bd6a96 (diff) | |
| download | linux-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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/display/drm_bridge_connector.c | 18 |
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); |
