diff options
-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 | { |