[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201228125025.107792556@linuxfoundation.org>
Date: Mon, 28 Dec 2020 13:41:24 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Rob Clark <robdclark@...omium.org>,
Sasha Levin <sashal@...nel.org>
Subject: [PATCH 5.10 086/717] drm/msm/a6xx: Clear shadow on suspend
From: Rob Clark <robdclark@...omium.org>
[ Upstream commit e8b0b994c3a5881f0648d53f90435120089c56ad ]
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@...omium.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
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 948f3656c20ca..420ca4a0eb5f7 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1045,12 +1045,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.27.0
Powered by blists - more mailing lists