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

Reply via email to