|
@@ -1373,6 +1373,21 @@ void i915_hangcheck_elapsed(unsigned long data)
|
|
|
dev_priv->last_instdone1 == instdone1) {
|
|
|
if (dev_priv->hangcheck_count++ > 1) {
|
|
|
DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
|
|
|
+
|
|
|
+ if (!IS_GEN2(dev)) {
|
|
|
+ /* Is the chip hanging on a WAIT_FOR_EVENT?
|
|
|
+ * If so we can simply poke the RB_WAIT bit
|
|
|
+ * and break the hang. This should work on
|
|
|
+ * all but the second generation chipsets.
|
|
|
+ */
|
|
|
+ u32 tmp = I915_READ(PRB0_CTL);
|
|
|
+ if (tmp & RING_WAIT) {
|
|
|
+ I915_WRITE(PRB0_CTL, tmp);
|
|
|
+ POSTING_READ(PRB0_CTL);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
i915_handle_error(dev, true);
|
|
|
return;
|
|
|
}
|
|
@@ -1384,6 +1399,7 @@ void i915_hangcheck_elapsed(unsigned long data)
|
|
|
dev_priv->last_instdone1 = instdone1;
|
|
|
}
|
|
|
|
|
|
+out:
|
|
|
/* Reset timer case chip hangs without another request being added */
|
|
|
mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
|
|
|
}
|