[PATCH v11 10/21] drm/bridge: synopsys: dw-dp: Add follow-up bridge support
Sebastian Reichel
sebastian.reichel at collabora.com
Thu Aug 6 10:02:16 PDT 2026
Add support to use USB-C connectors with the DP altmode helper code on
devicetree based platforms. To get this working there must be a DRM
bridge chain from the DisplayPort controller to the USB-C connector.
E.g. on Rockchip RK3576:
root at rk3576 # cat /sys/kernel/debug/dri/0/encoder-0/bridges
bridge[0]: dw_dp_bridge_funcs
refcount: 7
type: [10] DP
OF: /soc/dp at 27e40000:rockchip,rk3576-dp
ops: [0x47] detect edid hpd
bridge[1]: drm_aux_bridge_funcs
refcount: 4
type: [0] Unknown
OF: /soc/phy at 2b010000:rockchip,rk3576-usbdp-phy
ops: [0x0]
bridge[2]: drm_aux_hpd_bridge_funcs
refcount: 5
type: [10] DP
OF: /soc/i2c at 2ac50000/typec-portc at 22/connector:usb-c-connector
ops: [0x4] hpd
It's fine to fatally error out when there is no follow-up bridge
as the Rockchip Designware Displayport controller is the only
user of the bridge helper and has the port marked as required
in its binding.
Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
---
drivers/gpu/drm/bridge/synopsys/dw-dp.c | 34 +++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index b9864a17c01d..a6099f7ddc87 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -330,6 +330,8 @@ struct dw_dp {
struct dw_dp_plat_data plat_data;
u8 pixel_mode;
+ struct drm_bridge *next_bridge;
+
DECLARE_BITMAP(sdp_reg_bank, SDP_REG_BANK_SIZE);
};
@@ -1894,7 +1896,22 @@ static int dw_dp_bridge_attach(struct drm_bridge *bridge,
enable_irq(dp->irq);
+ ret = drm_bridge_attach(encoder, dp->next_bridge, bridge,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ if (ret) {
+ dev_err(dev, "Failed to attach next bridge: %d\n", ret);
+ goto err_disable_irq;
+ }
+
return 0;
+
+err_disable_irq:
+ disable_irq(dp->irq);
+ cancel_work_sync(&dp->hpd_work);
+
+ drm_dp_aux_unregister(&dp->aux);
+
+ return ret;
}
static void dw_dp_bridge_detach(struct drm_bridge *bridge)
@@ -2060,6 +2077,13 @@ void dw_dp_unbind(struct dw_dp *dp)
}
EXPORT_SYMBOL_GPL(dw_dp_unbind);
+static void dw_dp_put_next_bridge(void *data)
+{
+ struct dw_dp *dp = data;
+
+ drm_bridge_put(dp->next_bridge);
+}
+
static void dw_dp_phy_exit(void *data)
{
struct dw_dp *dp = data;
@@ -2157,6 +2181,16 @@ struct dw_dp *dw_dp_probe(struct platform_device *pdev, const struct dw_dp_plat_
return ERR_PTR(ret);
}
+ dp->next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, 0);
+ if (IS_ERR(dp->next_bridge)) {
+ dev_err_probe(dev, PTR_ERR(dp->next_bridge), "failed to get follow-up bridge\n");
+ return ERR_CAST(dp->next_bridge);
+ }
+
+ ret = devm_add_action_or_reset(dev, dw_dp_put_next_bridge, dp);
+ if (ret)
+ return ERR_PTR(ret);
+
dw_dp_init_hw(dp);
ret = phy_init(dp->phy);
--
2.53.0
More information about the linux-arm-kernel
mailing list