|
@@ -32,6 +32,7 @@
|
|
|
#include "drm.h"
|
|
|
#include "i915_drm.h"
|
|
|
#include "i915_drv.h"
|
|
|
+#include "i915_trace.h"
|
|
|
#include "intel_drv.h"
|
|
|
|
|
|
#include <linux/console.h>
|
|
@@ -432,36 +433,26 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
|
|
+static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
- int count;
|
|
|
-
|
|
|
- count = 0;
|
|
|
- while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
|
|
|
- udelay(10);
|
|
|
+ if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, 500))
|
|
|
+ DRM_ERROR("Force wake wait timed out\n");
|
|
|
|
|
|
I915_WRITE_NOTRACE(FORCEWAKE, 1);
|
|
|
- POSTING_READ(FORCEWAKE);
|
|
|
|
|
|
- count = 0;
|
|
|
- while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
|
|
|
- udelay(10);
|
|
|
+ if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), 500))
|
|
|
+ DRM_ERROR("Force wake wait timed out\n");
|
|
|
}
|
|
|
|
|
|
-void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
|
|
|
+static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
- int count;
|
|
|
-
|
|
|
- count = 0;
|
|
|
- while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
|
|
|
- udelay(10);
|
|
|
+ if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0, 500))
|
|
|
+ DRM_ERROR("Force wake wait timed out\n");
|
|
|
|
|
|
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1));
|
|
|
- POSTING_READ(FORCEWAKE_MT);
|
|
|
|
|
|
- count = 0;
|
|
|
- while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
|
|
|
- udelay(10);
|
|
|
+ if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1), 500))
|
|
|
+ DRM_ERROR("Force wake wait timed out\n");
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -476,7 +467,7 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
|
|
|
|
|
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
|
|
|
if (dev_priv->forcewake_count++ == 0)
|
|
|
- dev_priv->display.force_wake_get(dev_priv);
|
|
|
+ dev_priv->gt.force_wake_get(dev_priv);
|
|
|
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
|
|
|
}
|
|
|
|
|
@@ -489,14 +480,14 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
|
|
|
I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
|
|
|
}
|
|
|
|
|
|
-void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
|
|
|
+static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
I915_WRITE_NOTRACE(FORCEWAKE, 0);
|
|
|
/* The below doubles as a POSTING_READ */
|
|
|
gen6_gt_check_fifodbg(dev_priv);
|
|
|
}
|
|
|
|
|
|
-void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
|
|
|
+static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1));
|
|
|
/* The below doubles as a POSTING_READ */
|
|
@@ -512,7 +503,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
|
|
|
|
|
|
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
|
|
|
if (--dev_priv->forcewake_count == 0)
|
|
|
- dev_priv->display.force_wake_put(dev_priv);
|
|
|
+ dev_priv->gt.force_wake_put(dev_priv);
|
|
|
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
|
|
|
}
|
|
|
|
|
@@ -536,12 +527,8 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-void vlv_force_wake_get(struct drm_i915_private *dev_priv)
|
|
|
+static void vlv_force_wake_get(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
- int count;
|
|
|
-
|
|
|
- count = 0;
|
|
|
-
|
|
|
/* Already awake? */
|
|
|
if ((I915_READ(0x130094) & 0xa1) == 0xa1)
|
|
|
return;
|
|
@@ -549,18 +536,58 @@ void vlv_force_wake_get(struct drm_i915_private *dev_priv)
|
|
|
I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff);
|
|
|
POSTING_READ(FORCEWAKE_VLV);
|
|
|
|
|
|
- count = 0;
|
|
|
- while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0)
|
|
|
- udelay(10);
|
|
|
+ if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500))
|
|
|
+ DRM_ERROR("Force wake wait timed out\n");
|
|
|
}
|
|
|
|
|
|
-void vlv_force_wake_put(struct drm_i915_private *dev_priv)
|
|
|
+static void vlv_force_wake_put(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000);
|
|
|
/* FIXME: confirm VLV behavior with Punit folks */
|
|
|
POSTING_READ(FORCEWAKE_VLV);
|
|
|
}
|
|
|
|
|
|
+void intel_gt_init(struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+
|
|
|
+ spin_lock_init(&dev_priv->gt_lock);
|
|
|
+
|
|
|
+ if (IS_VALLEYVIEW(dev)) {
|
|
|
+ dev_priv->gt.force_wake_get = vlv_force_wake_get;
|
|
|
+ dev_priv->gt.force_wake_put = vlv_force_wake_put;
|
|
|
+ } else if (INTEL_INFO(dev)->gen >= 6) {
|
|
|
+ dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get;
|
|
|
+ dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put;
|
|
|
+
|
|
|
+ /* IVB configs may use multi-threaded forcewake */
|
|
|
+ if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
|
|
|
+ u32 ecobus;
|
|
|
+
|
|
|
+ /* A small trick here - if the bios hasn't configured
|
|
|
+ * MT forcewake, and if the device is in RC6, then
|
|
|
+ * force_wake_mt_get will not wake the device and the
|
|
|
+ * ECOBUS read will return zero. Which will be
|
|
|
+ * (correctly) interpreted by the test below as MT
|
|
|
+ * forcewake being disabled.
|
|
|
+ */
|
|
|
+ mutex_lock(&dev->struct_mutex);
|
|
|
+ __gen6_gt_force_wake_mt_get(dev_priv);
|
|
|
+ ecobus = I915_READ_NOTRACE(ECOBUS);
|
|
|
+ __gen6_gt_force_wake_mt_put(dev_priv);
|
|
|
+ mutex_unlock(&dev->struct_mutex);
|
|
|
+
|
|
|
+ if (ecobus & FORCEWAKE_MT_ENABLE) {
|
|
|
+ DRM_DEBUG_KMS("Using MT version of forcewake\n");
|
|
|
+ dev_priv->gt.force_wake_get =
|
|
|
+ __gen6_gt_force_wake_mt_get;
|
|
|
+ dev_priv->gt.force_wake_put =
|
|
|
+ __gen6_gt_force_wake_mt_put;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int i915_drm_freeze(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
@@ -797,9 +824,9 @@ static int gen6_do_reset(struct drm_device *dev)
|
|
|
|
|
|
/* 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);
|
|
|
+ dev_priv->gt.force_wake_get(dev_priv);
|
|
|
else
|
|
|
- dev_priv->display.force_wake_put(dev_priv);
|
|
|
+ dev_priv->gt.force_wake_put(dev_priv);
|
|
|
|
|
|
/* Restore fifo count */
|
|
|
dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
|
|
@@ -1248,10 +1275,10 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
|
|
|
unsigned long irqflags; \
|
|
|
spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
|
|
|
if (dev_priv->forcewake_count == 0) \
|
|
|
- dev_priv->display.force_wake_get(dev_priv); \
|
|
|
+ dev_priv->gt.force_wake_get(dev_priv); \
|
|
|
val = read##y(dev_priv->regs + reg); \
|
|
|
if (dev_priv->forcewake_count == 0) \
|
|
|
- dev_priv->display.force_wake_put(dev_priv); \
|
|
|
+ dev_priv->gt.force_wake_put(dev_priv); \
|
|
|
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
|
|
|
} else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \
|
|
|
val = read##y(dev_priv->regs + reg + 0x180000); \
|