#include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
+#include "i915_trace.h"
 #include "intel_drv.h"
 
 #include <linux/console.h>
        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");
 }
 
 /*
 
        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);
 }
 
                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 */
 
        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);
 }
 
        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;
        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;
 
        /* 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);
                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);         \
 
                          struct drm_i915_gem_object *obj);
        int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                            int x, int y);
-       void (*force_wake_get)(struct drm_i915_private *dev_priv);
-       void (*force_wake_put)(struct drm_i915_private *dev_priv);
        /* clock updates for mode set */
        /* cursor updates */
        /* render clock increase/decrease */
        /* pll clock increase/decrease */
 };
 
+struct drm_i915_gt_funcs {
+       void (*force_wake_get)(struct drm_i915_private *dev_priv);
+       void (*force_wake_put)(struct drm_i915_private *dev_priv);
+};
+
 struct intel_device_info {
        u8 gen;
        u8 is_mobile:1;
        int relative_constants_mode;
 
        void __iomem *regs;
+
+       struct drm_i915_gt_funcs gt;
        /** gt_fifo_count and the subsequent register write are synchronized
         * with dev->struct_mutex. */
        unsigned gt_fifo_count;
 void i915_handle_error(struct drm_device *dev, bool wedged);
 
 extern void intel_irq_init(struct drm_device *dev);
+extern void intel_gt_init(struct drm_device *dev);
 
 void i915_error_state_free(struct kref *error_ref);
 
 extern int intel_enable_rc6(const struct drm_device *dev);
 
 extern bool i915_semaphore_is_enabled(struct drm_device *dev);
-extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
-extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
-extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
-extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
-
-extern void vlv_force_wake_get(struct drm_i915_private *dev_priv);
-extern void vlv_force_wake_put(struct drm_i915_private *dev_priv);
 
 /* overlay */
 #ifdef CONFIG_DEBUG_FS
 
 
        /* For FIFO watermark updates */
        if (HAS_PCH_SPLIT(dev)) {
-               dev_priv->display.force_wake_get = __gen6_gt_force_wake_get;
-               dev_priv->display.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->display.force_wake_get =
-                                       __gen6_gt_force_wake_mt_get;
-                               dev_priv->display.force_wake_put =
-                                       __gen6_gt_force_wake_mt_put;
-                       }
-               }
-
                if (HAS_PCH_IBX(dev))
                        dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating;
                else if (HAS_PCH_CPT(dev))
                dev_priv->display.update_wm = valleyview_update_wm;
                dev_priv->display.init_clock_gating =
                        valleyview_init_clock_gating;
-               dev_priv->display.force_wake_get = vlv_force_wake_get;
-               dev_priv->display.force_wake_put = vlv_force_wake_put;
        } else if (IS_PINEVIEW(dev)) {
                if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
                                            dev_priv->is_ddr3,