aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-01-06 14:44:11 -0500
committerKeith Packard <keithp@keithp.com>2012-01-19 15:28:42 -0500
commit286fed412a134e76be55899bc628c6fa59cb70da (patch)
treeaebb2c7db1204cbffaf40febab8770fa1acadc6e /drivers
parentb6e45f866465f42b53d803b0c574da0fc508a0e9 (diff)
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: Keith Packard <keithp@keithp.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a6fcd941e3ab..062d1d27f704 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -603,12 +603,31 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags)
603 int ret; 603 int ret;
604 unsigned long irqflags; 604 unsigned long irqflags;
605 605
606 I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); 606 /* Hold gt_lock across reset to prevent any register access
607 ret = wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); 607 * with forcewake not set correctly
608 /* If reset with a user forcewake, try to restore */ 608 */
609 spin_lock_irqsave(&dev_priv->gt_lock, irqflags); 609 spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
610
611 /* Reset the chip */
612
613 /* GEN6_GDRST is not in the gt power well, no need to check
614 * for fifo space for the write or forcewake the chip for
615 * the read
616 */
617 I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
618
619 /* Spin waiting for the device to ack the reset request */
620 ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
621
622 /* If reset with a user forcewake, try to restore, otherwise turn it off */
610 if (dev_priv->forcewake_count) 623 if (dev_priv->forcewake_count)
611 dev_priv->display.force_wake_get(dev_priv); 624 dev_priv->display.force_wake_get(dev_priv);
625 else
626 dev_priv->display.force_wake_put(dev_priv);
627
628 /* Restore fifo count */
629 dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
630
612 spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); 631 spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
613 return ret; 632 return ret;
614} 633}