Pass the entire struct drm_bus_cfg {} to select_bus_fmt_recursive() instead of only u32 out_bus_fmt which contains only the pixel format. This would permit passing more bus format data around during the bridge-to-bridge format negotiation. Signed-off-by: Marek Vasut <marex@xxxxxxx> Cc: Laurent Pinchart <Laurent.pinchart@xxxxxxxxxxxxxxxx> Cc: Maxime Ripard <maxime@xxxxxxxxxx> Cc: Neil Armstrong <narmstrong@xxxxxxxxxxxx> Cc: Sam Ravnborg <sam@xxxxxxxxxxxx> --- drivers/gpu/drm/drm_bridge.c | 39 +++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebcb..f052d50106758 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -821,11 +821,13 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, struct drm_bridge *cur_bridge, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state, - u32 out_bus_fmt) + struct drm_bus_cfg *out_bus_cfg) { struct drm_bridge_state *cur_state; unsigned int num_in_bus_fmts, i; struct drm_bridge *prev_bridge; + struct drm_bus_cfg fixed_bus_cfg; + struct drm_bus_cfg *in_bus_cfgs; u32 *in_bus_fmts; int ret; @@ -841,10 +843,11 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, */ if (!cur_bridge->funcs->atomic_get_input_bus_fmts) { if (cur_bridge != first_bridge) { + fixed_bus_cfg.format = MEDIA_BUS_FMT_FIXED; ret = select_bus_fmt_recursive(first_bridge, prev_bridge, crtc_state, conn_state, - MEDIA_BUS_FMT_FIXED); + &fixed_bus_cfg); if (ret) return ret; } @@ -855,7 +858,7 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, */ if (cur_state) { cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED; - cur_state->output_bus_cfg.format = out_bus_fmt; + cur_state->output_bus_cfg.format = out_bus_cfg->format; } return 0; @@ -872,34 +875,44 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, cur_state, crtc_state, conn_state, - out_bus_fmt, + out_bus_cfg->format, &num_in_bus_fmts); if (!num_in_bus_fmts) return -ENOTSUPP; else if (!in_bus_fmts) return -ENOMEM; + /* Transcribe in_bus_fmts to in_bus_cfgs */ + in_bus_cfgs = kcalloc(num_in_bus_fmts, sizeof(*in_bus_cfgs), GFP_KERNEL); + if (!in_bus_cfgs) + return -ENOMEM; + + for (i = 0; i < num_in_bus_fmts; i++) + in_bus_cfgs[i].format = in_bus_fmts[i]; + + kfree(in_bus_fmts); + if (first_bridge == cur_bridge) { - cur_state->input_bus_cfg.format = in_bus_fmts[0]; - cur_state->output_bus_cfg.format = out_bus_fmt; - kfree(in_bus_fmts); + cur_state->input_bus_cfg.format = in_bus_cfgs[0].format; + cur_state->output_bus_cfg.format = out_bus_cfg->format; + kfree(in_bus_cfgs); return 0; } for (i = 0; i < num_in_bus_fmts; i++) { ret = select_bus_fmt_recursive(first_bridge, prev_bridge, crtc_state, conn_state, - in_bus_fmts[i]); + &(in_bus_cfgs[i])); if (ret != -ENOTSUPP) break; } if (!ret) { - cur_state->input_bus_cfg.format = in_bus_fmts[i]; - cur_state->output_bus_cfg.format = out_bus_fmt; + cur_state->input_bus_cfg.format = in_bus_cfgs[i].format; + cur_state->output_bus_cfg.format = out_bus_cfg->format; } - kfree(in_bus_fmts); + kfree(in_bus_cfgs); return ret; } @@ -947,6 +960,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, struct drm_bridge_state *last_bridge_state; unsigned int i, num_out_bus_fmts; struct drm_bridge *last_bridge; + struct drm_bus_cfg out_bus_cfg; u32 *out_bus_fmts; int ret = 0; @@ -988,8 +1002,9 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, } for (i = 0; i < num_out_bus_fmts; i++) { + out_bus_cfg.format = out_bus_fmts[i]; ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state, - conn_state, out_bus_fmts[i]); + conn_state, &out_bus_cfg); if (ret != -ENOTSUPP) break; } -- 2.34.1