drm/i915: vlv: factor out vlv_force_gfx_clock and check for pending force-off
authorImre Deak <imre.deak@intel.com>
Fri, 18 Apr 2014 13:35:02 +0000 (16:35 +0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 5 May 2014 07:09:12 +0000 (09:09 +0200)
This will be needed by the VLV runtime PM helpers too, so factor it out.

Also add a safety check for the case where the previous force-off is
still pending, since I'm not sure if Punit can handle a new setting
while the previous one hasn't settled yet.

v2:
- unchanged
v3:
- add a note to the commit message about the safety check (Ville)

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_pm.c

index e3c9c44e4bc467eb9d06f6098d655e3591be29a0..9f3e977d1877ecfaa7e13c62fcd22899f2c3917a 100644 (file)
@@ -933,6 +933,43 @@ static void hsw_runtime_resume(struct drm_i915_private *dev_priv)
        hsw_disable_pc8(dev_priv);
 }
 
+int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on)
+{
+       u32 val;
+       int err;
+
+       val = I915_READ(VLV_GTLC_SURVIVABILITY_REG);
+       WARN_ON(!!(val & VLV_GFX_CLK_FORCE_ON_BIT) == force_on);
+
+#define COND (I915_READ(VLV_GTLC_SURVIVABILITY_REG) & VLV_GFX_CLK_STATUS_BIT)
+       /* Wait for a previous force-off to settle */
+       if (force_on) {
+               err = wait_for(!COND, 5);
+               if (err) {
+                       DRM_ERROR("timeout waiting for GFX clock force-off (%08x)\n",
+                                 I915_READ(VLV_GTLC_SURVIVABILITY_REG));
+                       return err;
+               }
+       }
+
+       val = I915_READ(VLV_GTLC_SURVIVABILITY_REG);
+       val &= ~VLV_GFX_CLK_FORCE_ON_BIT;
+       if (force_on)
+               val |= VLV_GFX_CLK_FORCE_ON_BIT;
+       I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val);
+
+       if (!force_on)
+               return 0;
+
+       err = wait_for(COND, 5);
+       if (err)
+               DRM_ERROR("timeout waiting for GFX clock force-on (%08x)\n",
+                         I915_READ(VLV_GTLC_SURVIVABILITY_REG));
+
+       return err;
+#undef COND
+}
+
 static int intel_runtime_suspend(struct device *device)
 {
        struct pci_dev *pdev = to_pci_dev(device);
index 1c615cb5034e2777e74e87e43097dfee439dabb1..e81feab6b3f6e7616652715539ed3c8c0e740c9d 100644 (file)
@@ -1973,6 +1973,7 @@ extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
 extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
 extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
 extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
+int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
 
 extern void intel_console_resume(struct work_struct *work);
 
index 2b200434897d9085c2e4f941716d7283aa7f261f..d49ec02ef39b6649fa8bfe6e0fb0578c7b19ad62 100644 (file)
@@ -3129,16 +3129,7 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
        /* Mask turbo interrupt so that they will not come in between */
        I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
 
-       /* Bring up the Gfx clock */
-       I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
-               I915_READ(VLV_GTLC_SURVIVABILITY_REG) |
-                               VLV_GFX_CLK_FORCE_ON_BIT);
-
-       if (wait_for(((VLV_GFX_CLK_STATUS_BIT &
-               I915_READ(VLV_GTLC_SURVIVABILITY_REG)) != 0), 5)) {
-                       DRM_ERROR("GFX_CLK_ON request timed out\n");
-               return;
-       }
+       vlv_force_gfx_clock(dev_priv, true);
 
        dev_priv->rps.cur_freq = dev_priv->rps.min_freq_softlimit;
 
@@ -3149,10 +3140,7 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
                                & GENFREQSTATUS) == 0, 5))
                DRM_ERROR("timed out waiting for Punit\n");
 
-       /* Release the Gfx clock */
-       I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
-               I915_READ(VLV_GTLC_SURVIVABILITY_REG) &
-                               ~VLV_GFX_CLK_FORCE_ON_BIT);
+       vlv_force_gfx_clock(dev_priv, false);
 
        I915_WRITE(GEN6_PMINTRMSK,
                   gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));