drm/i915: reintroduce VLV/CHV PFI programming power domain workaround
authorGabriel Krisman Bertazi <krisman@collabora.co.uk>
Wed, 28 Jun 2017 21:06:05 +0000 (18:06 -0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 29 Jun 2017 13:13:32 +0000 (16:13 +0300)
There are still cases on these platforms where an attempt is made to
configure the CDCLK while the power domain is off, like when coming back
from a suspend.  So the workaround below is still needed.

This effectively reverts commit 63ff30442519 ("drm/i915: Nuke the
VLV/CHV PFI programming power domain workaround").

Cc: stable@vger.kernel.org
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101517
Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170628210605.4994-1-krisman@collabora.co.uk
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
drivers/gpu/drm/i915/intel_cdclk.c

index b8914db..1241e58 100644 (file)
@@ -491,6 +491,14 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
        int cdclk = cdclk_state->cdclk;
        u32 val, cmd;
 
+       /* There are cases where we can end up here with power domains
+        * off and a CDCLK frequency other than the minimum, like when
+        * issuing a modeset without actually changing any display after
+        * a system suspend.  So grab the PIPE-A domain, which covers
+        * the HW blocks needed for the following programming.
+        */
+       intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
+
        if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
                cmd = 2;
        else if (cdclk == 266667)
@@ -549,6 +557,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
        intel_update_cdclk(dev_priv);
 
        vlv_program_pfi_credits(dev_priv);
+
+       intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
 }
 
 static void chv_set_cdclk(struct drm_i915_private *dev_priv,
@@ -568,6 +578,14 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
+       /* There are cases where we can end up here with power domains
+        * off and a CDCLK frequency other than the minimum, like when
+        * issuing a modeset without actually changing any display after
+        * a system suspend.  So grab the PIPE-A domain, which covers
+        * the HW blocks needed for the following programming.
+        */
+       intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
+
        /*
         * Specs are full of misinformation, but testing on actual
         * hardware has shown that we just need to write the desired
@@ -590,6 +608,8 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
        intel_update_cdclk(dev_priv);
 
        vlv_program_pfi_credits(dev_priv);
+
+       intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
 }
 
 static int bdw_calc_cdclk(int max_pixclk)