[PATCH v9 10/22] drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED
Sebastian Reichel <[email protected]> Mon, 03 Aug 2026 20:05:11 +0200
| Newsgroups | org.infradead.lists.linux-rockchip,org.freedesktop.lists.dri-devel,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260803-synopsys-dw-dp-improvements-v9-10-2e6e46135312@collabora.com> |
Add support for MEDIA_BUS_FMT_FIXED, which is e.g. requested for USB-C DP chains as the last bridge in the chain (aux-hpd-bridge) does not implement atomic_get_output_bus_fmts(), which results in the generic drm_atomic_bridge_chain_select_bus_fmts() code using MEDIA_BUS_FMT_FIXED instead. For decent support of this, two areas are changed: 1. In atomic_check, resolving MEDIA_BUS_FMT_FIXED output format by using the negotiated input format. 2. Implementing a custom .atomic_get_input_bus_fmts hook that, on MEDIA_BUS_FMT_FIXED, advertises all bandwidth-validated formats from dw_dp_bridge_atomic_get_output_bus_fmts(). This lets the upstream encoder negotiate the best mutually supported format. Signed-off-by: Sebastian Reichel <[email protected]> --- drivers/gpu/drm/bridge/synopsys/dw-dp.c | 34 +++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c index bde938b0d116..e60dab0d3b9d 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c @@ -1537,6 +1537,7 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge, struct drm_connector_state *conn_state) { struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; + unsigned int out_bus_format = bridge_state->output_bus_cfg.format; struct dw_dp *dp = bridge_to_dp(bridge); struct dw_dp_bridge_state *state; const struct dw_dp_output_format *fmt; @@ -1547,7 +1548,10 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge, state = to_dw_dp_bridge_state(bridge_state); mode = &state->mode; - fmt = dw_dp_get_output_format(bridge_state->output_bus_cfg.format); + if (out_bus_format == MEDIA_BUS_FMT_FIXED) + out_bus_format = bridge_state->input_bus_cfg.format; + + fmt = dw_dp_get_output_format(out_bus_format); if (!fmt) return -EINVAL; @@ -1823,6 +1827,32 @@ static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, return output_fmts; } +static u32 * +dw_dp_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + /* + * MEDIA_BUS_FMT_FIXED means the downstream bridge does not constrain + * the bus format. In that case, advertise all formats supported by the + * DP link so the upstream encoder can negotiate the best match. + */ + if (output_fmt == MEDIA_BUS_FMT_FIXED) + return dw_dp_bridge_atomic_get_output_bus_fmts(bridge, + bridge_state, + crtc_state, + conn_state, + num_input_fmts); + + return drm_atomic_helper_bridge_propagate_bus_fmt(bridge, bridge_state, + crtc_state, conn_state, + output_fmt, + num_input_fmts); +} + static struct drm_bridge_state *dw_dp_bridge_atomic_duplicate_state(struct drm_bridge *bridge) { struct dw_dp_bridge_state *state; @@ -1869,7 +1899,7 @@ static const struct drm_bridge_funcs dw_dp_bridge_funcs = { .atomic_duplicate_state = dw_dp_bridge_atomic_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_create_state = drm_atomic_helper_bridge_create_state, - .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt, + .atomic_get_input_bus_fmts = dw_dp_bridge_atomic_get_input_bus_fmts, .atomic_get_output_bus_fmts = dw_dp_bridge_atomic_get_output_bus_fmts, .atomic_check = dw_dp_bridge_atomic_check, .mode_valid = dw_dp_bridge_mode_valid, -- 2.53.0 _______________________________________________ Linux-rockchip mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-rockchip