[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