aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c14
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c41
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h15
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
327static void a3xx_idle(struct msm_gpu *gpu) 327static 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)
225void adreno_idle(struct msm_gpu *gpu) 225void 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
281void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords) 273static 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; 282void 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
299static const char *iommu_ports[] = { 288static 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
81static inline bool adreno_is_a3xx(struct adreno_gpu *gpu) 94static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
82{ 95{