From edb2e5301c4489d8c99b0f3d86a074df27f6f8ff Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 17 Jan 2018 21:21:49 +0200 Subject: drm/i915: Track whether the DP link is trained or not MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LSPCON likes to throw short HPDs during the enable seqeunce prior to the link being trained. These obviously result in the channel CR/EQ check failing and thus we schedule a pointless hotplug work to retrain the link. Avoid that by ignoring the bad CR/EQ status until we've actually initially trained the link. I've not actually investigated to see what LSPCON is trying to signal with the short pulse. But as long as it signals anything I think we're supposed to check the link status anyway, so I don't really see other good ways to solve this. I've not seen these short pulses being generated by normal DP sinks. Signed-off-by: Ville Syrjälä Reviewed-by: Lyude Paul Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20180117192149.17760-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 2 ++ drivers/gpu/drm/i915/intel_dp.c | 10 +++++++--- drivers/gpu/drm/i915/intel_dp_link_training.c | 2 ++ drivers/gpu/drm/i915/intel_drv.h | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index d3cbea2c136c..ac8fc2a44ac6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2508,6 +2508,8 @@ static void intel_disable_ddi_dp(struct intel_encoder *encoder, { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + intel_dp->link_trained = false; + if (old_crtc_state->has_audio) intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 153342cf5898..9a4a51e79fa1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1913,6 +1913,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, int link_rate, uint8_t lane_count, bool link_mst) { + intel_dp->link_trained = false; intel_dp->link_rate = link_rate; intel_dp->lane_count = lane_count; intel_dp->link_mst = link_mst; @@ -2761,6 +2762,8 @@ static void intel_disable_dp(struct intel_encoder *encoder, { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + intel_dp->link_trained = false; + if (old_crtc_state->has_audio) intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state); @@ -4277,10 +4280,11 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) { u8 link_status[DP_LINK_STATUS_SIZE]; - if (!intel_dp_get_link_status(intel_dp, link_status)) { - DRM_ERROR("Failed to get link status\n"); + if (!intel_dp->link_trained) + return false; + + if (!intel_dp_get_link_status(intel_dp, link_status)) return false; - } /* * Validate the cached values of intel_dp->link_rate and diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index ae849952d4b9..f59b59bb0a21 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -307,6 +307,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) void intel_dp_stop_link_train(struct intel_dp *intel_dp) { + intel_dp->link_trained = true; + intel_dp_set_link_train(intel_dp, DP_TRAINING_PATTERN_DISABLE); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index dc693b40a884..37d5412af8f5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1048,6 +1048,7 @@ struct intel_dp { uint8_t lane_count; uint8_t sink_count; bool link_mst; + bool link_trained; bool has_audio; bool detect_done; bool reset_link_params; -- cgit v1.2.3