[PATCH] drm: rcar-du: Fix DU3 start/stop on M3-N
Kieran Bingham
kieran.bingham at ideasonboard.com
Fri Nov 23 14:02:15 UTC 2018
Hi Laurent,
Thank you for the patch.
On 23/11/2018 11:48, Laurent Pinchart wrote:
> Group start/stop is controlled by the DRES and DEN bits of DSYSR0 for
> the first group and DSYSR2 for the second group. On most DU instances,
> this maps to the first CRTC of the group. On M3-N, however, DU2 doesn't
> exist, but DSYSR2 does. There is no CRTC object there that maps to the
> correct DSYSR register.
>
> Commit 9144adc5e5a9 ("drm: rcar-du: Cache DSYSR value to ensure known
> initial value") switched group start/stop from using group read/write
> access to DSYSR to a CRTC-based API to cache the DSYSR value. While
> doing so, it introduced a regression on M3-N by accessing DSYSR3 instead
> of DSYSR2 to start/stop the second group.
>
> To fix this, access the DSYSR register directly through group read/write
> if the SoC is missing the first DU channel of the group. Keep using the
> rcar_du_crtc_dsysr_clr_set() function otherwise, to retain the DSYSR
> caching feature.
>
> Fixes: 9144adc5e5a9 ("drm: rcar-du: Cache DSYSR value to ensure known initial value")
> Reported-by: Hoan Nguyen An <na-hoan at jinso.co.jp>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Second in the series of 'ouch's :-D
Well I'm afraid I can't see any simpler way to work around this. And
instantiating a CRTC object at dev->crtcs to cover the non-existent DU
is overkill (and would incorrectly re-index the CRTCs)
So,
Acked-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
> ---
> drivers/gpu/drm/rcar-du/rcar_du_group.c | 21 ++++++++++++++++++---
> 1 file changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index d85f0a1c1581..cebf313c6e1f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -202,10 +202,25 @@ void rcar_du_group_put(struct rcar_du_group *rgrp)
>
> static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
> {
> - struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
> + struct rcar_du_device *rcdu = rgrp->dev;
> +
> + /*
> + * Group start/stop is controlled by the DRES and DEN bits of DSYSR0
> + * for the first group and DSYSR2 for the second group. On most DU
> + * instances, this maps to the first CRTC of the group, and we can just
> + * use rcar_du_crtc_dsysr_clr_set() to access the correct DSYSR. On
> + * M3-N, however, DU2 doesn't exist, but DSYSR2 does. We thus need to
> + * access the register directly using group read/write.
> + */
> + if (rcdu->info->channels_mask & BIT(rgrp->index * 2)) {
> + struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
>
> - rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
> - start ? DSYSR_DEN : DSYSR_DRES);
> + rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
> + start ? DSYSR_DEN : DSYSR_DRES);
> + } else {
> + rcar_du_group_write(rgrp, DSYSR,
> + start ? DSYSR_DEN : DSYSR_DRES);
> + }
> }
>
> void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
>
--
Regards
--
Kieran
More information about the dri-devel
mailing list