Commit 286fed41 authored by Keith Packard's avatar Keith Packard

drm/i915: Hold gt_lock during reset

This ensures that no register reads occur while the forcewake state of
the hardware is indeterminate during the reset operation.
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent b6e45f86
...@@ -603,12 +603,31 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags) ...@@ -603,12 +603,31 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags)
int ret; int ret;
unsigned long irqflags; unsigned long irqflags;
I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); /* Hold gt_lock across reset to prevent any register access
ret = wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); * with forcewake not set correctly
/* If reset with a user forcewake, try to restore */ */
spin_lock_irqsave(&dev_priv->gt_lock, irqflags); spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
/* Reset the chip */
/* GEN6_GDRST is not in the gt power well, no need to check
* for fifo space for the write or forcewake the chip for
* the read
*/
I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
/* Spin waiting for the device to ack the reset request */
ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
/* If reset with a user forcewake, try to restore, otherwise turn it off */
if (dev_priv->forcewake_count) if (dev_priv->forcewake_count)
dev_priv->display.force_wake_get(dev_priv); dev_priv->display.force_wake_get(dev_priv);
else
dev_priv->display.force_wake_put(dev_priv);
/* Restore fifo count */
dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment