mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-22 09:54:43 +07:00
drm/msm: Fix race of GPU init vs timestamp power management.
[ Upstream commit 7a7cbf2a819740674455ad36155c662367261296 ]
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@anholt.net>
Fixes: 4b565ca5a2
("drm/msm: Add A6XX device support")
Reviewed-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
5c49fc7b5d
commit
b605b8d568
@ -266,6 +266,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;
|
||||
@ -303,9 +313,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;
|
||||
}
|
||||
|
||||
@ -314,6 +329,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);
|
||||
|
@ -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);
|
||||
|
@ -1068,12 +1068,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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user