Message ID | 1394470062-27442-4-git-send-email-robdclark@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
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) > { >
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) {
Helper macro to simplify places where we need to poll with timeout waiting for gpu. Signed-off-by: Rob Clark <robdclark@gmail.com> --- 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(-)