drm/i915: Consolidate forcewake resetting to a single function
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 13 Mar 2014 12:00:29 +0000 (12:00 +0000)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 13 Mar 2014 17:21:58 +0000 (18:21 +0100)
We have two paths that try to reset the forcewake registers back to
known good values, with slightly different semantics and levels of
paranoia. Combine the two by passing a parameter to either restore the
forcewake status or to clear our bookkeeping, and raise the paranoia
level to max.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_uncore.c

index 361d1eae3cfd0b3fce40cf87dc68a58adc99f720..e6bb421a3dbd74ca30a16d16988bf61be8a7dd18 100644 (file)
@@ -308,9 +308,17 @@ static void gen6_force_wake_timer(unsigned long arg)
        intel_runtime_pm_put(dev_priv);
 }
 
-static void intel_uncore_forcewake_reset(struct drm_device *dev)
+static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       unsigned long irqflags;
+
+       del_timer_sync(&dev_priv->uncore.force_wake_timer);
+
+       /* Hold uncore.lock across reset to prevent any register access
+        * with forcewake not set correctly
+        */
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        if (IS_VALLEYVIEW(dev))
                vlv_force_wake_reset(dev_priv);
@@ -319,6 +327,35 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev)
 
        if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_GEN8(dev))
                __gen7_gt_force_wake_mt_reset(dev_priv);
+
+       if (restore) { /* If reset with a user forcewake, try to restore */
+               unsigned fw = 0;
+
+               if (IS_VALLEYVIEW(dev)) {
+                       if (dev_priv->uncore.fw_rendercount)
+                               fw |= FORCEWAKE_RENDER;
+
+                       if (dev_priv->uncore.fw_mediacount)
+                               fw |= FORCEWAKE_MEDIA;
+               } else {
+                       if (dev_priv->uncore.forcewake_count)
+                               fw = FORCEWAKE_ALL;
+               }
+
+               if (fw)
+                       dev_priv->uncore.funcs.force_wake_get(dev_priv, fw);
+
+               if (IS_GEN6(dev) || IS_GEN7(dev))
+                       dev_priv->uncore.fifo_count =
+                               __raw_i915_read32(dev_priv, GTFIFOCTL) &
+                               GT_FIFO_FREE_ENTRIES_MASK;
+       } else {
+               dev_priv->uncore.forcewake_count = 0;
+               dev_priv->uncore.fw_rendercount = 0;
+               dev_priv->uncore.fw_mediacount = 0;
+       }
+
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 void intel_uncore_early_sanitize(struct drm_device *dev)
@@ -344,7 +381,7 @@ void intel_uncore_early_sanitize(struct drm_device *dev)
                __raw_i915_write32(dev_priv, GTFIFODBG,
                                   __raw_i915_read32(dev_priv, GTFIFODBG));
 
-       intel_uncore_forcewake_reset(dev);
+       intel_uncore_forcewake_reset(dev, false);
 }
 
 void intel_uncore_sanitize(struct drm_device *dev)
@@ -798,17 +835,9 @@ void intel_uncore_init(struct drm_device *dev)
 
 void intel_uncore_fini(struct drm_device *dev)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
-       del_timer_sync(&dev_priv->uncore.force_wake_timer);
-
        /* Paranoia: make sure we have disabled everything before we exit. */
        intel_uncore_sanitize(dev);
-       intel_uncore_forcewake_reset(dev);
-
-       dev_priv->uncore.forcewake_count = 0;
-       dev_priv->uncore.fw_rendercount = 0;
-       dev_priv->uncore.fw_mediacount = 0;
+       intel_uncore_forcewake_reset(dev, false);
 }
 
 static const struct register_whitelist {
@@ -957,13 +986,6 @@ static int gen6_do_reset(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int     ret;
-       unsigned long irqflags;
-       u32 fw_engine = 0;
-
-       /* Hold uncore.lock across reset to prevent any register access
-        * with forcewake not set correctly
-        */
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        /* Reset the chip */
 
@@ -976,29 +998,8 @@ static int gen6_do_reset(struct drm_device *dev)
        /* Spin waiting for the device to ack the reset request */
        ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
 
-       intel_uncore_forcewake_reset(dev);
-
-       /* If reset with a user forcewake, try to restore */
-       if (IS_VALLEYVIEW(dev)) {
-               if (dev_priv->uncore.fw_rendercount)
-                       fw_engine |= FORCEWAKE_RENDER;
-
-               if (dev_priv->uncore.fw_mediacount)
-                       fw_engine |= FORCEWAKE_MEDIA;
-       } else {
-               if (dev_priv->uncore.forcewake_count)
-                       fw_engine = FORCEWAKE_ALL;
-       }
-
-       if (fw_engine)
-               dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine);
+       intel_uncore_forcewake_reset(dev, true);
 
-       if (IS_GEN6(dev) || IS_GEN7(dev))
-               dev_priv->uncore.fifo_count =
-                       __raw_i915_read32(dev_priv, GTFIFOCTL) &
-                       GT_FIFO_FREE_ENTRIES_MASK;
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
        return ret;
 }