mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 17:41:44 +00:00
drm/msm: spin helper
Helper macro to simplify places where we need to poll with timeout waiting for gpu. Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
5b6ef08e4b
commit
0963756fe5
@ -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? */
|
||||
}
|
||||
|
@ -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;
|
||||
uint32_t wptr = get_wptr(gpu->rb);
|
||||
|
||||
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? */
|
||||
}
|
||||
@ -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;
|
||||
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;
|
||||
}
|
||||
|
||||
if (time_after(jiffies, t)) {
|
||||
DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
|
||||
break;
|
||||
}
|
||||
} while(freedwords < ndwords);
|
||||
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[] = {
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user