summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm
diff options
context:
space:
mode:
authorRob Clark <robdclark@chromium.org>2020-11-10 10:23:06 -0800
committerRob Clark <robdclark@chromium.org>2020-11-10 11:05:23 -0800
commite8b0b994c3a5881f0648d53f90435120089c56ad (patch)
treea4064b74ce1c33fc5d7036a4f0c55e6905817830 /drivers/gpu/drm/msm
parent06d65ba3db67618c0afd70a72df516dace49e7e7 (diff)
drm/msm/a6xx: Clear shadow on suspend
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@chromium.org>
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c11
1 files changed, 10 insertions, 1 deletions
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)