Skip to content

Commit

Permalink
drm/i915: Hold gt_lock during reset
Browse files Browse the repository at this point in the history
This ensures that no register reads occur while the forcewake state of
the hardware is indeterminate during the reset operation.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Keith Packard committed Jan 19, 2012
1 parent b6e45f8 commit 286fed4
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
@@ -603,12 +603,31 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags)
int ret;
unsigned long irqflags;

I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL);
ret = wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
/* If reset with a user forcewake, try to restore */
/* Hold gt_lock across reset to prevent any register access
* with forcewake not set correctly
*/
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)
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);
return ret;
}

0 comments on commit 286fed4

Please sign in to comment.