On Tue, Nov 10, 2020 at 10:43:59AM -0800, Rob Clark wrote: > From: Rob Clark <robdclark@xxxxxxxxxxxx> > > Clear the shadow rptr on suspend. Otherwise, when we resume, we can > have a stale value until CP_WHERE_AM_I executes. If we suspend near > the ringbuffer wraparound point, this can lead to a chicken/egg > situation where we are waiting for ringbuffer space to write the > CP_WHERE_AM_I (or CP_INIT) packet, because we mistakenly believe that > the ringbuffer is full (due to stale rptr value in the shadow). > > Fixes errors like: > > [drm:adreno_wait_ring [msm]] *ERROR* timeout waiting for space in ringbuffer 0 > > in the resume path. > > Fixes: d3a569fccfa0 ("drm/msm: a6xx: Use WHERE_AM_I for eligible targets") > Signed-off-by: Rob Clark <robdclark@xxxxxxxxxxxx> Reviewed-by: Jordan Crouse <jcrouse@xxxxxxxxxxxxxx> > --- > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > index 2f236aadfa9c..fcb0aabbc985 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > @@ -1043,12 +1043,21 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) > { > struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); > struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); > + int i, ret; > > trace_msm_gpu_suspend(0); > > devfreq_suspend_device(gpu->devfreq.devfreq); > > - return a6xx_gmu_stop(a6xx_gpu); > + ret = a6xx_gmu_stop(a6xx_gpu); > + if (ret) > + return ret; > + > + if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami) > + for (i = 0; i < gpu->nr_rings; i++) > + a6xx_gpu->shadow[i] = 0; > + > + return 0; > } > > static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) > -- > 2.28.0 > -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project