Replace the hardcoded rzg2l_du_crtc_create(rcdu, 0, 0) call with a
loop over channels_mask using for_each_set_bit(), passing the correct
software and hardware indices to each invocation.

Iterate the registered CRTCs by their hardware index when building
encoder possible_crtcs masks, so that the DRM software CRTC index
correctly maps to the hardware channel.

No functional changes intended.

Signed-off-by: Tommaso Merciai <[email protected]>
---
v6->v7:
 - New patch.

 drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 28 ++++++++++++++++----
 1 file changed, 23 insertions(+), 5 deletions(-)

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 7cbdf146788e..fc5ce8c7eea0 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c
@@ -404,7 +404,10 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
 {
        struct drm_device *dev = &rcdu->ddev;
        struct drm_encoder *encoder;
+       unsigned long channels_mask;
        unsigned int num_encoders;
+       unsigned int swindex = 0;
+       unsigned int hwindex;
        int ret;
 
        ret = drmm_mode_config_init(dev);
@@ -424,7 +427,8 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
        dev->mode_config.max_width = 1920;
        dev->mode_config.max_height = 1920;
 
-       rcdu->num_crtcs = hweight8(rcdu->info->channels_mask);
+       channels_mask = rcdu->info->channels_mask;
+       rcdu->num_crtcs = hweight8(channels_mask);
 
        /*
         * Initialize vertical blanking interrupts handling. Start with vblank
@@ -440,9 +444,11 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
                return ret;
 
        /* Create the CRTCs. */
-       ret = rzg2l_du_crtc_create(rcdu, 0, 0);
-       if (ret < 0)
-               return ret;
+       for_each_set_bit(hwindex, &channels_mask, RZG2L_DU_MAX_CRTCS) {
+               ret = rzg2l_du_crtc_create(rcdu, swindex++, hwindex);
+               if (ret < 0)
+                       return ret;
+       }
 
        /* Initialize the encoders. */
        ret = rzg2l_du_encoders_init(rcdu);
@@ -461,13 +467,25 @@ int rzg2l_du_modeset_init(struct rzg2l_du_device *rcdu)
         * Set the possible CRTCs and possible clones. There's always at least
         * one way for all encoders to clone each other, set all bits in the
         * possible clones field.
+        *
+        * route->possible_outputs uses hardware channel indices, but DRM
+        * possible_crtcs uses the CRTC registration order. Convert by
+        * mapping each set bit in possible_outputs through the hw_index
+        * stored in each CRTC.
         */
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                struct rzg2l_du_encoder *renc = to_rzg2l_encoder(encoder);
                const struct rzg2l_du_output_routing *route =
                        &rcdu->info->routes[renc->output];
+               unsigned int possible_crtcs = 0;
+               unsigned int i;
+
+               for (i = 0; i < rcdu->num_crtcs; i++) {
+                       if (route->possible_outputs & 
BIT(rcdu->crtcs[i].hw_index))
+                               possible_crtcs |= BIT(i);
+               }
 
-               encoder->possible_crtcs = route->possible_outputs;
+               encoder->possible_crtcs = possible_crtcs;
                encoder->possible_clones = (1 << num_encoders) - 1;
        }
 
-- 
2.54.0

Reply via email to