]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm/i915/vlv: assert and de-assert sideband reset at boot and resume v3
authorJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 23 May 2014 20:16:40 +0000 (13:16 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 27 May 2014 20:17:08 +0000 (22:17 +0200)
This is a bit like the CMN reset de-assert we do in DPIO_CTL, except
that it resets the whole common lane section of the PHY.  This is
required on machines where the BIOS doesn't do this for us on boot or
resume to properly re-calibrate and get the PHY ready to transmit data.

Without this patch, such machines won't resume correctly much of the time,
with the symptom being a 'port ready' timeout and/or a link training
failure.

Note that simply asserting reset at suspend and de-asserting at resume
is not sufficient, nor is simply de-asserting at boot.  Both of these
cases have been tested and have still been found to have failures on
some configurations.

v2: extract simpler set_power_well function for use in reset_dpio (Imre)
    move to reset_dpio (Daniel & Ville)
v3: don't reset if DPIO reset is already de-asserted (Imre)

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c

index 33d7f679e41c59b4e36d7edafe9715dcce87eb6b..153888eec25d596de57ac97e90aea611920baeca 100644 (file)
@@ -1515,6 +1515,25 @@ static void intel_reset_dpio(struct drm_device *dev)
                }
 
        } else {
+               /*
+                * If DPIO has already been reset, e.g. by BIOS, just skip all
+                * this.
+                */
+               if (I915_READ(DPIO_CTL) & DPIO_CMNRST)
+                       return;
+
+               /*
+                * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
+                * Need to assert and de-assert PHY SB reset by gating the
+                * common lane power, then un-gating it.
+                * Simply ungating isn't enough to reset the PHY enough to get
+                * ports and lanes running.
+                */
+               __vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
+                                    false);
+               __vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
+                                    true);
+
                /*
                 * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
                 *  6.  De-assert cmn_reset/side_reset. Same as VLV X0.
index edecf89b7dba2f9226171c5aefec4024adf81ba7..9bb70dc88046497ad3dde998b818b04f0ac59db7 100644 (file)
@@ -970,7 +970,8 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
 void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
 void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
 void ilk_wm_get_hw_state(struct drm_device *dev);
-
+void __vlv_set_power_well(struct drm_i915_private *dev_priv,
+                         enum punit_power_well power_well_id, bool enable);
 
 /* intel_sdvo.c */
 bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
index 8e909455e80a3f0cb9a35cc4c6f1a756a68a71e0..d14bd6f0fc444dcb2f840e31c5feaf57af4f0411 100644 (file)
@@ -5901,10 +5901,9 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
        return true;
 }
 
-static void vlv_set_power_well(struct drm_i915_private *dev_priv,
-                              struct i915_power_well *power_well, bool enable)
+void __vlv_set_power_well(struct drm_i915_private *dev_priv,
+                         enum punit_power_well power_well_id, bool enable)
 {
-       enum punit_power_well power_well_id = power_well->data;
        u32 mask;
        u32 state;
        u32 ctrl;
@@ -5937,6 +5936,14 @@ out:
        mutex_unlock(&dev_priv->rps.hw_lock);
 }
 
+static void vlv_set_power_well(struct drm_i915_private *dev_priv,
+                              struct i915_power_well *power_well, bool enable)
+{
+       enum punit_power_well power_well_id = power_well->data;
+
+       __vlv_set_power_well(dev_priv, power_well_id, enable);
+}
+
 static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {