Message ID | 1486031230-4914-1-git-send-email-shawn.c.lee@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, 02 Feb 2017, "Lee, Shawn C" <shawn.c.lee@intel.com> wrote: > From: "Lee, Shawn C" <shawn.c.lee@intel.com> > > When user space link status, display driver read DPCD register > 0x202, 0x203 and 0x204 to identify sink status. When PSR exit > is ongoing before EQ done. Panel will report EQ & symbol lock > not done. Both of them are under progressing at the same time > to cause this issue. > > This WA try to read link status more times if EQ not done. > Panel spec request at least 1000us for fast link train when > PSR exit. So driver will wait 1000us~1500us then retrieve > sink link status again. I'm not sure about the patch, but no matter what it needs to be rebased on top of current drm-tip to even be considered. If you're working around a specific eDP PSR issue, why do this on *all* DP? BR, Jani. > > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99639 > TEST=Reboot DUT and no flicking on local display at login screen > > Cc: Cooper Chiou <cooper.chiou@intel.com> > Cc: Wei Shun Chen <wei.shun.chang@intel.com> > Cc: Gary C Wang <gary.c.wang@intel.com> > Cc: Jani Nikula <jani.nikula@intel.com> > > Signed-off-by: Lee, Shawn C <shawn.c.lee@intel.com> > --- > drivers/gpu/drm/i915/intel_dp.c | 33 ++++++++++++++++++++++++++++----- > 1 file changed, 28 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index e80d620846c8..a9a6ce476438 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -4136,13 +4136,36 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp) > return; > > /* if link training is requested we should perform it always */ > - if ((intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) || > - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { > - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", > - intel_encoder->base.name); > + if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { > + DRM_DEBUG_KMS("%s: compliance test mode, retraining\n", > + intel_encoder->base.name); > + } else { > + u8 retry; > + > + for (retry = 0; retry < 3; retry++) { > + if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) { > + /* > + * EQ not ok may caused by fast link train while exit PSR active, > + * wait at least 1000 us then read it again. > + */ > + DRM_DEBUG_KMS("%s: channel EQ not ok, retry = %d, DPCD 0x202 = 0x%x, 0x203 = 0x%x, 0x204 = 0x%x\n", > + intel_encoder->base.name, retry, link_status[0], link_status[1], link_status[2]); > + usleep_range(1000, 1500); > + if (!intel_dp_get_link_status(intel_dp, link_status)) { > + DRM_ERROR("Failed to get link status\n"); > + return; > + } > + } else { > + /* channel EQ is fine */ > + return; > + } > + } > > - intel_dp_retrain_link(intel_dp); > + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", > + intel_encoder->base.name); > } > + > + intel_dp_retrain_link(intel_dp); > } > > /*
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e80d620846c8..a9a6ce476438 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4136,13 +4136,36 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp) return; /* if link training is requested we should perform it always */ - if ((intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) || - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - intel_encoder->base.name); + if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { + DRM_DEBUG_KMS("%s: compliance test mode, retraining\n", + intel_encoder->base.name); + } else { + u8 retry; + + for (retry = 0; retry < 3; retry++) { + if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) { + /* + * EQ not ok may caused by fast link train while exit PSR active, + * wait at least 1000 us then read it again. + */ + DRM_DEBUG_KMS("%s: channel EQ not ok, retry = %d, DPCD 0x202 = 0x%x, 0x203 = 0x%x, 0x204 = 0x%x\n", + intel_encoder->base.name, retry, link_status[0], link_status[1], link_status[2]); + usleep_range(1000, 1500); + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + } else { + /* channel EQ is fine */ + return; + } + } - intel_dp_retrain_link(intel_dp); + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", + intel_encoder->base.name); } + + intel_dp_retrain_link(intel_dp); } /*