Skip to content

Commit 77ad507

Browse files
robclarkAbhinav Kumar
authored andcommitted
drm/msm/a6xx+: Insert a fence wait before SMMU table update
The CP_SMMU_TABLE_UPDATE _should_ be waiting for idle, but on some devices (x1-85, possibly others), it seems to pass that barrier while there are still things in the event completion FIFO waiting to be written back to memory. Work around that by adding a fence wait before context switch. The CP_EVENT_WRITE that writes the fence is the last write from a submit, so seeing this value hit memory is a reliable indication that it is safe to proceed with the context switch. v2: Only emit CP_WAIT_TIMESTAMP on a7xx, as it is not supported on a6xx. Conversely, I've not been able to reproduce this issue on a6xx, so hopefully it is limited to a7xx, or perhaps just certain a7xx devices. Fixes: af66706 ("drm/msm/a6xx: Add skeleton A7xx support") Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/63 Signed-off-by: Rob Clark <[email protected]> Reviewed-by: Akhil P Oommen <[email protected]> Signed-off-by: Abhinav Kumar <[email protected]>
1 parent f87f3b8 commit 77ad507

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

drivers/gpu/drm/msm/adreno/a6xx_gpu.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter,
101101
}
102102

103103
static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
104-
struct msm_ringbuffer *ring, struct msm_file_private *ctx)
104+
struct msm_ringbuffer *ring, struct msm_gem_submit *submit)
105105
{
106106
bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
107+
struct msm_file_private *ctx = submit->queue->ctx;
107108
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
108109
phys_addr_t ttbr;
109110
u32 asid;
@@ -115,6 +116,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
115116
if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
116117
return;
117118

119+
if (adreno_gpu->info->family >= ADRENO_7XX_GEN1) {
120+
/* Wait for previous submit to complete before continuing: */
121+
OUT_PKT7(ring, CP_WAIT_TIMESTAMP, 4);
122+
OUT_RING(ring, 0);
123+
OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
124+
OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
125+
OUT_RING(ring, submit->seqno - 1);
126+
}
127+
118128
if (!sysprof) {
119129
if (!adreno_is_a7xx(adreno_gpu)) {
120130
/* Turn off protected mode to write to special registers */
@@ -193,7 +203,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
193203
struct msm_ringbuffer *ring = submit->ring;
194204
unsigned int i, ibs = 0;
195205

196-
a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
206+
a6xx_set_pagetable(a6xx_gpu, ring, submit);
197207

198208
get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
199209
rbmemptr_stats(ring, index, cpcycles_start));
@@ -283,7 +293,7 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
283293
OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
284294
OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR);
285295

286-
a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
296+
a6xx_set_pagetable(a6xx_gpu, ring, submit);
287297

288298
get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0),
289299
rbmemptr_stats(ring, index, cpcycles_start));

0 commit comments

Comments
 (0)