diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1ce4ad4626e4f1114bf7e6b957d9b0c781db4e77..bcbd742149c64bd6beb61cb52d7d7cf219167d02 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -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. diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0de04983501e12969fcc127293a053a8c10452f4..8ce90d621c204f5b420574f6a774fa6bb21d1fcf 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -973,7 +973,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); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7a4798f52fa1312add4b9254588e9e4dbe1191d9..25caf8fb66567640d8b293f3db4f3073012fda88 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5708,10 +5708,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; @@ -5744,6 +5743,14 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv, 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) {