| From 664a84d2c77cbff2945ed7f96d08afbba42b6293 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> |
| Date: Fri, 13 May 2016 20:53:56 +0300 |
| Subject: drm/i915: Refresh cached DP port register value on resume |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| |
| commit 664a84d2c77cbff2945ed7f96d08afbba42b6293 upstream. |
| |
| During hibernation the cached DP port register value will be left with |
| whatever value we have there when we create the hibernation image. |
| Currently that means the port (and eDP PLL) will be off in the cached |
| value. However when we resume there is no guarantee that the value |
| in the actual register will match the cached value. If i915 isn't |
| loaded in the kernel that loads the hibernation image, the port may |
| well be on (eg. left on by the BIOS). The encoder state readout |
| does the right thing in this case and updates our encoder state |
| to reflect the actual hardware state. However the post-resume modeset |
| will then use the stale cached port register value in |
| intel_dp_link_down() and potentially confuse the hardware. |
| |
| This was caught by the following assert |
| WARNING: CPU: 3 PID: 5288 at ../drivers/gpu/drm/i915/intel_dp.c:2184 assert_edp_pll+0x99/0xa0 [i915] |
| eDP PLL state assertion failure (expected on, current off) |
| on account of the eDP PLL getting prematurely turned off when |
| shutting down the port, since the DP_PLL_ENABLE bit wasn't set |
| in the cached register value. |
| |
| Presumably I introduced this problem in |
| commit 6fec76628333 ("drm/i915: Use intel_dp->DP in eDP PLL setup") |
| as before that we didn't update the cached value after shuttting the |
| port down. That's assuming the port got enabled at least once prior |
| to hibernating. If that didn't happen then the cached value would |
| still have been totally out of sync with reality (eg. first boot w/o |
| eDP on, then hibernate, and then resume with eDP on). |
| |
| So, let's fix this properly and refresh the cached register value from |
| the hardware register during resume. |
| |
| DDI platforms shouldn't use the cached value during port disable at |
| least, so shouldn't have this particular issue. They might still have |
| issues if we skip the initial modeset and then try to retrain the link |
| or something. But untangling this DP vs. DDI mess is a bigger topic, |
| so let's jut punt on DDI for now. |
| |
| Cc: Jani Nikula <jani.nikula@intel.com> |
| Fixes: 6fec76628333 ("drm/i915: Use intel_dp->DP in eDP PLL setup") |
| Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Link: http://patchwork.freedesktop.org/patch/msgid/1463162036-27931-1-git-send-email-ville.syrjala@linux.intel.com |
| Reviewed-by: Imre Deak <imre.deak@intel.com> |
| (cherry picked from commit 64989ca4b27acb026b6496ec21e43bee66f86a5b) |
| Signed-off-by: Jani Nikula <jani.nikula@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/i915/intel_dp.c | 8 +++++--- |
| 1 file changed, 5 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/gpu/drm/i915/intel_dp.c |
| +++ b/drivers/gpu/drm/i915/intel_dp.c |
| @@ -5079,13 +5079,15 @@ static void intel_edp_panel_vdd_sanitize |
| |
| void intel_dp_encoder_reset(struct drm_encoder *encoder) |
| { |
| - struct intel_dp *intel_dp; |
| + struct drm_i915_private *dev_priv = to_i915(encoder->dev); |
| + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| + |
| + if (!HAS_DDI(dev_priv)) |
| + intel_dp->DP = I915_READ(intel_dp->output_reg); |
| |
| if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP) |
| return; |
| |
| - intel_dp = enc_to_intel_dp(encoder); |
| - |
| pps_lock(intel_dp); |
| |
| /* |