/* reset completed fence seqno, just discard anything pending: */
adreno_gpu->memptrs->fence = gpu->submitted_fence;
+ adreno_gpu->memptrs->rptr = 0;
+ adreno_gpu->memptrs->wptr = 0;
gpu->funcs->pm_resume(gpu);
ret = gpu->funcs->hw_init(gpu);
return;
} while(time_before(jiffies, t));
- DRM_ERROR("timeout waiting for %s to drain ringbuffer!\n", gpu->name);
+ DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
/* TODO maybe we need to reset GPU here to recover from hang? */
}
{
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);
}
gpu->hangcheck_fence = fence;
} else if (fence < gpu->submitted_fence) {
/* no progress and not done.. hung! */
- struct msm_drm_private *priv = gpu->dev->dev_private;
+ struct drm_device *dev = gpu->dev;
+ struct msm_drm_private *priv = dev->dev_private;
gpu->hangcheck_fence = fence;
+ dev_err(dev->dev, "%s: hangcheck detected gpu lockup!\n",
+ gpu->name);
+ dev_err(dev->dev, "%s: completed fence: %u\n",
+ gpu->name, fence);
+ dev_err(dev->dev, "%s: submitted fence: %u\n",
+ gpu->name, gpu->submitted_fence);
queue_work(priv->wq, &gpu->recover_work);
}