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
