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@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_uncore.c | 81 +++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 361d1eae3cfd..e6bb421a3dbd 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -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; } -- 1.9.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx