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 robdclark@gmail.com
Acked-by: Jordan Crouse jcrouse@codeaurora.org
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) {