[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210128210332.1690609-2-eric@anholt.net>
Date: Thu, 28 Jan 2021 13:03:30 -0800
From: Eric Anholt <eric@...olt.net>
To: dri-devel@...ts.freedesktop.org, linux-arm-msm@...r.kernel.org,
freedreno@...ts.freedesktop.org, Rob Clark <robdclark@...il.com>,
Sean Paul <sean@...rly.run>,
Jordan Crouse <jcrouse@...eaurora.org>
Cc: linux-kernel@...r.kernel.org, Eric Anholt <eric@...olt.net>
Subject: [PATCH v3 1/3] drm/msm: Fix race of GPU init vs timestamp power management.
We were using the same force-poweron bit in the two codepaths, so they
could race to have one of them lose GPU power early.
freedreno CI was seeing intermittent errors like:
[drm:_a6xx_gmu_set_oob] *ERROR* Timeout waiting for GMU OOB set GPU_SET: 0x0
and this issue could have contributed to it.
Signed-off-by: Eric Anholt <eric@...olt.net>
Fixes: 4b565ca5a2cb ("drm/msm: Add A6XX device support")
Reviewed-by: Jordan Crouse <jcrouse@...eaurora.org>
---
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 25 ++++++++++++++++++++++---
drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 8 ++++++++
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 ++--
3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index e6703ae98760..b3318f86aabc 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -264,6 +264,16 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
}
name = "GPU_SET";
break;
+ case GMU_OOB_PERFCOUNTER_SET:
+ if (gmu->legacy) {
+ request = GMU_OOB_PERFCOUNTER_REQUEST;
+ ack = GMU_OOB_PERFCOUNTER_ACK;
+ } else {
+ request = GMU_OOB_PERFCOUNTER_REQUEST_NEW;
+ ack = GMU_OOB_PERFCOUNTER_ACK_NEW;
+ }
+ name = "PERFCOUNTER";
+ break;
case GMU_OOB_BOOT_SLUMBER:
request = GMU_OOB_BOOT_SLUMBER_REQUEST;
ack = GMU_OOB_BOOT_SLUMBER_ACK;
@@ -301,9 +311,14 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
{
if (!gmu->legacy) {
- WARN_ON(state != GMU_OOB_GPU_SET);
- gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
- 1 << GMU_OOB_GPU_SET_CLEAR_NEW);
+ if (state == GMU_OOB_GPU_SET) {
+ gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
+ 1 << GMU_OOB_GPU_SET_CLEAR_NEW);
+ } else {
+ WARN_ON(state != GMU_OOB_PERFCOUNTER_SET);
+ gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
+ 1 << GMU_OOB_PERFCOUNTER_CLEAR_NEW);
+ }
return;
}
@@ -312,6 +327,10 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
1 << GMU_OOB_GPU_SET_CLEAR);
break;
+ case GMU_OOB_PERFCOUNTER_SET:
+ gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
+ 1 << GMU_OOB_PERFCOUNTER_CLEAR);
+ break;
case GMU_OOB_BOOT_SLUMBER:
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
1 << GMU_OOB_BOOT_SLUMBER_CLEAR);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index c6d2bced8e5d..9fa278de2106 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -156,6 +156,7 @@ enum a6xx_gmu_oob_state {
GMU_OOB_BOOT_SLUMBER = 0,
GMU_OOB_GPU_SET,
GMU_OOB_DCVS_SET,
+ GMU_OOB_PERFCOUNTER_SET,
};
/* These are the interrupt / ack bits for each OOB request that are set
@@ -190,6 +191,13 @@ enum a6xx_gmu_oob_state {
#define GMU_OOB_GPU_SET_ACK_NEW 31
#define GMU_OOB_GPU_SET_CLEAR_NEW 31
+#define GMU_OOB_PERFCOUNTER_REQUEST 17
+#define GMU_OOB_PERFCOUNTER_ACK 25
+#define GMU_OOB_PERFCOUNTER_CLEAR 25
+
+#define GMU_OOB_PERFCOUNTER_REQUEST_NEW 28
+#define GMU_OOB_PERFCOUNTER_ACK_NEW 30
+#define GMU_OOB_PERFCOUNTER_CLEAR_NEW 30
void a6xx_hfi_init(struct a6xx_gmu *gmu);
int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c8a9010c1a1d..7424a70b9d35 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1177,12 +1177,12 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
/* Force the GPU power on so we can read this register */
- a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
+ a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
*value = gpu_read64(gpu, REG_A6XX_RBBM_PERFCTR_CP_0_LO,
REG_A6XX_RBBM_PERFCTR_CP_0_HI);
- a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
+ a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
return 0;
}
--
2.30.0
Powered by blists - more mailing lists