diff options
| author | Rob Clark <robdclark@gmail.com> | 2014-01-11 16:11:59 -0500 |
|---|---|---|
| committer | Rob Clark <robdclark@gmail.com> | 2014-03-31 10:27:45 -0400 |
| commit | 0963756fe51313a1e2d76885cd21624d3b2cfbf2 (patch) | |
| tree | ddb5bdc7770c2a386bfdf78f0463d8e1c228c9f4 /drivers/gpu/drm/msm/adreno | |
| parent | 5b6ef08e4b4e1bcb6b3ac4172c054e4462e2c767 (diff) | |
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>
Diffstat (limited to 'drivers/gpu/drm/msm/adreno')
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.c | 41 | ||||
| -rw-r--r-- | 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 8b6fb847789e..59ed7620fc1a 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) | |||
| 326 | 326 | ||
| 327 | static void a3xx_idle(struct msm_gpu *gpu) | 327 | static void a3xx_idle(struct msm_gpu *gpu) |
| 328 | { | 328 | { |
| 329 | unsigned long t; | ||
| 330 | |||
| 331 | /* wait for ringbuffer to drain: */ | 329 | /* wait for ringbuffer to drain: */ |
| 332 | adreno_idle(gpu); | 330 | adreno_idle(gpu); |
| 333 | 331 | ||
| 334 | t = jiffies + ADRENO_IDLE_TIMEOUT; | ||
| 335 | |||
| 336 | /* then wait for GPU to finish: */ | 332 | /* then wait for GPU to finish: */ |
| 337 | do { | 333 | if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) & |
| 338 | uint32_t rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS); | 334 | A3XX_RBBM_STATUS_GPU_BUSY))) |
| 339 | if (!(rbbm_status & A3XX_RBBM_STATUS_GPU_BUSY)) | 335 | DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name); |
| 340 | return; | ||
| 341 | } while(time_before(jiffies, t)); | ||
| 342 | |||
| 343 | DRM_ERROR("timeout waiting for %s to idle!\n", gpu->name); | ||
| 344 | 336 | ||
| 345 | /* TODO maybe we need to reset GPU here to recover from hang? */ | 337 | /* TODO maybe we need to reset GPU here to recover from hang? */ |
| 346 | } | 338 | } |
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index cf6eb976dda7..7a11563379b8 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) | |||
| 225 | void adreno_idle(struct msm_gpu *gpu) | 225 | void adreno_idle(struct msm_gpu *gpu) |
| 226 | { | 226 | { |
| 227 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | 227 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 228 | uint32_t rptr, wptr = get_wptr(gpu->rb); | 228 | uint32_t wptr = get_wptr(gpu->rb); |
| 229 | unsigned long t; | ||
| 230 | |||
| 231 | t = jiffies + ADRENO_IDLE_TIMEOUT; | ||
| 232 | |||
| 233 | /* then wait for CP to drain ringbuffer: */ | ||
| 234 | do { | ||
| 235 | rptr = adreno_gpu->memptrs->rptr; | ||
| 236 | if (rptr == wptr) | ||
| 237 | return; | ||
| 238 | } while(time_before(jiffies, t)); | ||
| 239 | 229 | ||
| 240 | DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name); | 230 | /* wait for CP to drain ringbuffer: */ |
| 231 | if (spin_until(adreno_gpu->memptrs->rptr == wptr)) | ||
| 232 | DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name); | ||
| 241 | 233 | ||
| 242 | /* TODO maybe we need to reset GPU here to recover from hang? */ | 234 | /* TODO maybe we need to reset GPU here to recover from hang? */ |
| 243 | } | 235 | } |
| @@ -278,22 +270,19 @@ void adreno_dump(struct msm_gpu *gpu) | |||
| 278 | 270 | ||
| 279 | } | 271 | } |
| 280 | 272 | ||
| 281 | void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords) | 273 | static uint32_t ring_freewords(struct msm_gpu *gpu) |
| 282 | { | 274 | { |
| 283 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | 275 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 284 | uint32_t freedwords; | 276 | uint32_t size = gpu->rb->size / 4; |
| 285 | unsigned long t = jiffies + ADRENO_IDLE_TIMEOUT; | 277 | uint32_t wptr = get_wptr(gpu->rb); |
| 286 | do { | 278 | uint32_t rptr = adreno_gpu->memptrs->rptr; |
| 287 | uint32_t size = gpu->rb->size / 4; | 279 | return (rptr + (size - 1) - wptr) % size; |
| 288 | uint32_t wptr = get_wptr(gpu->rb); | 280 | } |
| 289 | uint32_t rptr = adreno_gpu->memptrs->rptr; | 281 | |
| 290 | freedwords = (rptr + (size - 1) - wptr) % size; | 282 | void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords) |
| 291 | 283 | { | |
| 292 | if (time_after(jiffies, t)) { | 284 | if (spin_until(ring_freewords(gpu) >= ndwords)) |
| 293 | DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name); | 285 | DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name); |
| 294 | break; | ||
| 295 | } | ||
| 296 | } while(freedwords < ndwords); | ||
| 297 | } | 286 | } |
| 298 | 287 | ||
| 299 | static const char *iommu_ports[] = { | 288 | 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 e16200ddc60b..63c36ce33020 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 { | |||
| 76 | #endif | 76 | #endif |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | #define ADRENO_IDLE_TIMEOUT (20 * 1000) | 79 | #define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000) |
| 80 | |||
| 81 | #define spin_until(X) ({ \ | ||
| 82 | int __ret = -ETIMEDOUT; \ | ||
| 83 | unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \ | ||
| 84 | do { \ | ||
| 85 | if (X) { \ | ||
| 86 | __ret = 0; \ | ||
| 87 | break; \ | ||
| 88 | } \ | ||
| 89 | } while (time_before(jiffies, __t)); \ | ||
| 90 | __ret; \ | ||
| 91 | }) | ||
| 92 | |||
| 80 | 93 | ||
| 81 | static inline bool adreno_is_a3xx(struct adreno_gpu *gpu) | 94 | static inline bool adreno_is_a3xx(struct adreno_gpu *gpu) |
| 82 | { | 95 | { |
