From: cstout <cst...@google.com>

As described in the downstream/kgsl driver:
Sometimes the RPTR shadow memory is unreliable causing timeouts
in adreno_idle().  Read it directly from the register instead.

Change-Id: I1617a670e1da0ae25528c37f3424654d5bedd169
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 34 +++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 0e76a21..95e582e 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -68,18 +68,15 @@ int adreno_hw_init(struct msm_gpu *gpu)
        adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL,
                        /* size is log2(quad-words): */
                        AXXX_CP_RB_CNTL_BUFSZ(ilog2(gpu->rb->size / 8)) |
-                       AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8)));
+                       AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8)) |
+                       (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE 
: 0));

        /* Setup ringbuffer address: */
        adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_BASE, gpu->rb_iova);
-       adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR,
-                       rbmemptr(adreno_gpu, rptr));

-       /* Setup scratch/timestamp: */
-       adreno_gpu_write(adreno_gpu, REG_ADRENO_SCRATCH_ADDR,
-                       rbmemptr(adreno_gpu, fence));
-
-       adreno_gpu_write(adreno_gpu, REG_ADRENO_SCRATCH_UMSK, 0x1);
+       if (!adreno_is_a430(adreno_gpu))
+               adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR,
+                                               rbmemptr(adreno_gpu, rptr));

        return 0;
 }
@@ -89,6 +86,16 @@ static uint32_t get_wptr(struct msm_ringbuffer *ring)
        return ring->cur - ring->start;
 }

+/* Use this helper to read rptr, since a430 doesn't update rptr in memory */
+static uint32_t get_rptr(struct adreno_gpu *adreno_gpu)
+{
+       if (adreno_is_a430(adreno_gpu))
+               return adreno_gpu->memptrs->rptr = adreno_gpu_read(
+                       adreno_gpu, REG_ADRENO_CP_RB_RPTR);
+       else
+               return adreno_gpu->memptrs->rptr;
+}
+
 uint32_t adreno_last_fence(struct msm_gpu *gpu)
 {
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -217,9 +224,12 @@ void adreno_idle(struct msm_gpu *gpu)
 {
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        uint32_t wptr = get_wptr(gpu->rb);
+       int ret;

        /* wait for CP to drain ringbuffer: */
-       if (spin_until(adreno_gpu->memptrs->rptr == wptr))
+       ret = spin_until(get_rptr(adreno_gpu) == wptr);
+
+       if (ret)
                DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", 
gpu->name);

        /* TODO maybe we need to reset GPU here to recover from hang? */
@@ -238,7 +248,7 @@ void adreno_show(struct msm_gpu *gpu, struct seq_file *m)

        seq_printf(m, "fence:    %d/%d\n", adreno_gpu->memptrs->fence,
                        gpu->submitted_fence);
-       seq_printf(m, "rptr:     %d\n", adreno_gpu->memptrs->rptr);
+       seq_printf(m, "rptr:     %d\n", get_rptr(adreno_gpu));
        seq_printf(m, "wptr:     %d\n", adreno_gpu->memptrs->wptr);
        seq_printf(m, "rb wptr:  %d\n", get_wptr(gpu->rb));

@@ -279,7 +289,7 @@ void adreno_dump_info(struct msm_gpu *gpu)

        printk("fence:    %d/%d\n", adreno_gpu->memptrs->fence,
                        gpu->submitted_fence);
-       printk("rptr:     %d\n", adreno_gpu->memptrs->rptr);
+       printk("rptr:     %d\n", get_rptr(adreno_gpu));
        printk("wptr:     %d\n", adreno_gpu->memptrs->wptr);
        printk("rb wptr:  %d\n", get_wptr(gpu->rb));

@@ -314,7 +324,7 @@ static uint32_t ring_freewords(struct msm_gpu *gpu)
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        uint32_t size = gpu->rb->size / 4;
        uint32_t wptr = get_wptr(gpu->rb);
-       uint32_t rptr = adreno_gpu->memptrs->rptr;
+       uint32_t rptr = get_rptr(adreno_gpu);
        return (rptr + (size - 1) - wptr) % size;
 }

-- 
2.1.4

Reply via email to