Commit 0963756f authored by Rob Clark's avatar Rob Clark

drm/msm: spin helper

Helper macro to simplify places where we need to poll with timeout
waiting for gpu.
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 5b6ef08e
...@@ -326,21 +326,13 @@ static void a3xx_destroy(struct msm_gpu *gpu) ...@@ -326,21 +326,13 @@ static void a3xx_destroy(struct msm_gpu *gpu)
static void a3xx_idle(struct msm_gpu *gpu) static void a3xx_idle(struct msm_gpu *gpu)
{ {
unsigned long t;
/* wait for ringbuffer to drain: */ /* wait for ringbuffer to drain: */
adreno_idle(gpu); adreno_idle(gpu);
t = jiffies + ADRENO_IDLE_TIMEOUT;
/* then wait for GPU to finish: */ /* then wait for GPU to finish: */
do { if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) &
uint32_t rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS); A3XX_RBBM_STATUS_GPU_BUSY)))
if (!(rbbm_status & A3XX_RBBM_STATUS_GPU_BUSY)) DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
return;
} while(time_before(jiffies, t));
DRM_ERROR("timeout waiting for %s to idle!\n", gpu->name);
/* TODO maybe we need to reset GPU here to recover from hang? */ /* TODO maybe we need to reset GPU here to recover from hang? */
} }
......
...@@ -225,19 +225,11 @@ void adreno_flush(struct msm_gpu *gpu) ...@@ -225,19 +225,11 @@ void adreno_flush(struct msm_gpu *gpu)
void adreno_idle(struct msm_gpu *gpu) void adreno_idle(struct msm_gpu *gpu)
{ {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
uint32_t rptr, wptr = get_wptr(gpu->rb); uint32_t 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));
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? */ /* TODO maybe we need to reset GPU here to recover from hang? */
} }
...@@ -278,22 +270,19 @@ void adreno_dump(struct msm_gpu *gpu) ...@@ -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); struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
uint32_t freedwords; uint32_t size = gpu->rb->size / 4;
unsigned long t = jiffies + ADRENO_IDLE_TIMEOUT; uint32_t wptr = get_wptr(gpu->rb);
do { uint32_t rptr = adreno_gpu->memptrs->rptr;
uint32_t size = gpu->rb->size / 4; return (rptr + (size - 1) - wptr) % size;
uint32_t wptr = get_wptr(gpu->rb); }
uint32_t rptr = adreno_gpu->memptrs->rptr;
freedwords = (rptr + (size - 1) - wptr) % size; void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
{
if (time_after(jiffies, t)) { if (spin_until(ring_freewords(gpu) >= ndwords))
DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name); DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
break;
}
} while(freedwords < ndwords);
} }
static const char *iommu_ports[] = { static const char *iommu_ports[] = {
......
...@@ -76,7 +76,20 @@ struct adreno_platform_config { ...@@ -76,7 +76,20 @@ struct adreno_platform_config {
#endif #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) static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment