diff options
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_gem.c | 19 |
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 080865ec2bae..b6ccf8181643 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h | |||
@@ -92,7 +92,6 @@ struct vc4_dev { | |||
92 | struct work_struct overflow_mem_work; | 92 | struct work_struct overflow_mem_work; |
93 | 93 | ||
94 | struct { | 94 | struct { |
95 | uint32_t last_ct0ca, last_ct1ca; | ||
96 | struct timer_list timer; | 95 | struct timer_list timer; |
97 | struct work_struct reset_work; | 96 | struct work_struct reset_work; |
98 | } hangcheck; | 97 | } hangcheck; |
@@ -192,6 +191,11 @@ struct vc4_exec_info { | |||
192 | /* Sequence number for this bin/render job. */ | 191 | /* Sequence number for this bin/render job. */ |
193 | uint64_t seqno; | 192 | uint64_t seqno; |
194 | 193 | ||
194 | /* Last current addresses the hardware was processing when the | ||
195 | * hangcheck timer checked on us. | ||
196 | */ | ||
197 | uint32_t last_ct0ca, last_ct1ca; | ||
198 | |||
195 | /* Kernel-space copy of the ioctl arguments */ | 199 | /* Kernel-space copy of the ioctl arguments */ |
196 | struct drm_vc4_submit_cl *args; | 200 | struct drm_vc4_submit_cl *args; |
197 | 201 | ||
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index a9d020e7e891..1a819dd826f8 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c | |||
@@ -257,10 +257,17 @@ vc4_hangcheck_elapsed(unsigned long data) | |||
257 | struct drm_device *dev = (struct drm_device *)data; | 257 | struct drm_device *dev = (struct drm_device *)data; |
258 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 258 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
259 | uint32_t ct0ca, ct1ca; | 259 | uint32_t ct0ca, ct1ca; |
260 | unsigned long irqflags; | ||
261 | struct vc4_exec_info *exec; | ||
262 | |||
263 | spin_lock_irqsave(&vc4->job_lock, irqflags); | ||
264 | exec = vc4_first_job(vc4); | ||
260 | 265 | ||
261 | /* If idle, we can stop watching for hangs. */ | 266 | /* If idle, we can stop watching for hangs. */ |
262 | if (list_empty(&vc4->job_list)) | 267 | if (!exec) { |
268 | spin_unlock_irqrestore(&vc4->job_lock, irqflags); | ||
263 | return; | 269 | return; |
270 | } | ||
264 | 271 | ||
265 | ct0ca = V3D_READ(V3D_CTNCA(0)); | 272 | ct0ca = V3D_READ(V3D_CTNCA(0)); |
266 | ct1ca = V3D_READ(V3D_CTNCA(1)); | 273 | ct1ca = V3D_READ(V3D_CTNCA(1)); |
@@ -268,14 +275,16 @@ vc4_hangcheck_elapsed(unsigned long data) | |||
268 | /* If we've made any progress in execution, rearm the timer | 275 | /* If we've made any progress in execution, rearm the timer |
269 | * and wait. | 276 | * and wait. |
270 | */ | 277 | */ |
271 | if (ct0ca != vc4->hangcheck.last_ct0ca || | 278 | if (ct0ca != exec->last_ct0ca || ct1ca != exec->last_ct1ca) { |
272 | ct1ca != vc4->hangcheck.last_ct1ca) { | 279 | exec->last_ct0ca = ct0ca; |
273 | vc4->hangcheck.last_ct0ca = ct0ca; | 280 | exec->last_ct1ca = ct1ca; |
274 | vc4->hangcheck.last_ct1ca = ct1ca; | 281 | spin_unlock_irqrestore(&vc4->job_lock, irqflags); |
275 | vc4_queue_hangcheck(dev); | 282 | vc4_queue_hangcheck(dev); |
276 | return; | 283 | return; |
277 | } | 284 | } |
278 | 285 | ||
286 | spin_unlock_irqrestore(&vc4->job_lock, irqflags); | ||
287 | |||
279 | /* We've gone too long with no progress, reset. This has to | 288 | /* We've gone too long with no progress, reset. This has to |
280 | * be done from a work struct, since resetting can sleep and | 289 | * be done from a work struct, since resetting can sleep and |
281 | * this timer hook isn't allowed to. | 290 | * this timer hook isn't allowed to. |