On a SoC with several DU instances an output can be reachable from more than one of them, but a drm_bridge can only be attached to one encoder.
In preparation for supporting RZ/G3E, where the DSI and the LVDS channel 1 are reachable from both instances, let the first instance create the encoder and the others add their CRTC to its possible_crtcs mask, which rzg2l_du_modeset_init_finish() then extends rather than overwrites. Without this the second drm_bridge_attach() fails with -EBUSY, leaving behind the encoder allocated just before it. SoCs with a single instance are unaffected, as no encoder is ever already attached. Signed-off-by: Tommaso Merciai <[email protected]> --- v8->v9: - New patch drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c | 12 ++++++++++++ drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c index 5c21c5f9fbaf..45f980ea3c20 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c @@ -129,6 +129,18 @@ int rzg2l_du_encoder_init(struct rzg2l_du_device *rcdu, return -EPROBE_DEFER; } + /* + * A bridge can only be attached to one encoder. If another DU instance + * has already attached it, add this instance's CRTC to that encoder. + */ + if (bridge->dev == rcdu->ddev && bridge->encoder) { + const struct rzg2l_du_output_routing *route = + &rcdu->info->routes[output]; + + bridge->encoder->possible_crtcs |= route->possible_outputs << rcdu->index; + return 0; + } + dev_dbg(rcdu->dev, "initializing encoder %pOF for output %s\n", enc_node, rzg2l_du_output_name(output)); diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c index cad378418b38..c20c0e0188ea 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c @@ -480,7 +480,7 @@ int rzg2l_du_modeset_init_finish(struct drm_device *dev) const struct rzg2l_du_output_routing *route = &renc->dev->info->routes[renc->output]; - encoder->possible_crtcs = route->possible_outputs << renc->dev->index; + encoder->possible_crtcs |= route->possible_outputs << renc->dev->index; encoder->possible_clones = (1 << num_encoders) - 1; } -- 2.54.0
