[PATCH v11 10/21] drm/bridge: synopsys: dw-dp: Add follow-up bridge support

Chaoyi Chen chaoyi.chen at rock-chips.com
Thu Aug 6 19:50:25 PDT 2026


On 8/7/2026 1:02 AM, Sebastian Reichel wrote:
> 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;
> +

To be nitpicky, this field would be better placed before the u8.

Reviewed-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>


>  	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);
> 



-- 
Best, 
Chaoyi



More information about the linux-arm-kernel mailing list