On 03/10/2014 10:47 AM, Rob Clark wrote:
Helper macro to simplify places where we need to poll with timeout
waiting for gpu.

Signed-off-by: Rob Clark <[email protected]>

Acked-by: Jordan Crouse <[email protected]>
---
  drivers/gpu/drm/msm/adreno/a3xx_gpu.c   | 14 +++--------
  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 41 ++++++++++++---------------------
  drivers/gpu/drm/msm/adreno/adreno_gpu.h | 15 +++++++++++-
  3 files changed, 32 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 8b6fb84..59ed762 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -326,21 +326,13 @@ static void a3xx_destroy(struct msm_gpu *gpu)

  static void a3xx_idle(struct msm_gpu *gpu)
  {
-       unsigned long t;
-
        /* wait for ringbuffer to drain: */
        adreno_idle(gpu);

-       t = jiffies + ADRENO_IDLE_TIMEOUT;
-
        /* then wait for GPU to finish: */
-       do {
-               uint32_t rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS);
-               if (!(rbbm_status & A3XX_RBBM_STATUS_GPU_BUSY))
-                       return;
-       } while(time_before(jiffies, t));
-
-       DRM_ERROR("timeout waiting for %s to idle!\n", gpu->name);
+       if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) &
+                       A3XX_RBBM_STATUS_GPU_BUSY)))
+               DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);

        /* TODO maybe we need to reset GPU here to recover from hang? */
  }
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index cf6eb97..7a11563 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -225,19 +225,11 @@ void adreno_flush(struct msm_gpu *gpu)
  void adreno_idle(struct msm_gpu *gpu)
  {
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
-       uint32_t rptr, wptr = get_wptr(gpu->rb);
-       unsigned long t;
-
-       t = jiffies + ADRENO_IDLE_TIMEOUT;
-
-       /* then wait for CP to drain ringbuffer: */
-       do {
-               rptr = adreno_gpu->memptrs->rptr;
-               if (rptr == wptr)
-                       return;
-       } while(time_before(jiffies, t));
+       uint32_t wptr = get_wptr(gpu->rb);

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

        /* TODO maybe we need to reset GPU here to recover from hang? */
  }
@@ -278,22 +270,19 @@ void adreno_dump(struct msm_gpu *gpu)

  }

-void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
+static uint32_t ring_freewords(struct msm_gpu *gpu)
  {
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
-       uint32_t freedwords;
-       unsigned long t = jiffies + ADRENO_IDLE_TIMEOUT;
-       do {
-               uint32_t size = gpu->rb->size / 4;
-               uint32_t wptr = get_wptr(gpu->rb);
-               uint32_t rptr = adreno_gpu->memptrs->rptr;
-               freedwords = (rptr + (size - 1) - wptr) % size;
-
-               if (time_after(jiffies, t)) {
-                       DRM_ERROR("%s: timeout waiting for ringbuffer space\n", 
gpu->name);
-                       break;
-               }
-       } while(freedwords < ndwords);
+       uint32_t size = gpu->rb->size / 4;
+       uint32_t wptr = get_wptr(gpu->rb);
+       uint32_t rptr = adreno_gpu->memptrs->rptr;
+       return (rptr + (size - 1) - wptr) % size;
+}
+
+void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
+{
+       if (spin_until(ring_freewords(gpu) >= ndwords))
+               DRM_ERROR("%s: timeout waiting for ringbuffer space\n", 
gpu->name);
  }

  static const char *iommu_ports[] = {
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index e16200d..63c36ce 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -76,7 +76,20 @@ struct adreno_platform_config {
  #endif
  };

-#define ADRENO_IDLE_TIMEOUT (20 * 1000)
+#define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
+
+#define spin_until(X) ({                                   \
+       int __ret = -ETIMEDOUT;                            \
+       unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \
+       do {                                               \
+               if (X) {                                   \
+                       __ret = 0;                         \
+                       break;                             \
+               }                                          \
+       } while (time_before(jiffies, __t));               \
+       __ret;                                             \
+})
+

  static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
  {



--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to