> Subject: [PATCH] drm/i915/display/dp: On dpcd init/caps wake the dprx >
Just "drm/i915/dp" *DPCD *DPRx > Before reading the dpcd caps for eDP wake the sink device and for DP after *DPCD > reading the lttpr caps and before reading the dpcd caps wake up the sink > device. > Also add the why. So What happens when this is not there, and how the spec state we handle this > Signed-off-by: Arun R Murthy <[email protected]> > --- > drivers/gpu/drm/i915/display/intel_dp.c | 28 +++++++++++++++++++ > drivers/gpu/drm/i915/display/intel_dp.h | 1 + > .../drm/i915/display/intel_dp_link_training.c | 3 ++ > 3 files changed, 32 insertions(+) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 454e6144ee4e..4d86826dba1b 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -4705,6 +4705,32 @@ intel_edp_set_sink_rates(struct intel_dp > *intel_dp) > intel_edp_set_data_override_rates(intel_dp); > } > > +void intel_dp_wake_sink(struct intel_dp *intel_dp) { > + u8 value = 0; > + int ret = 0, try = 0; > + > + intel_dp_dpcd_set_probe(intel_dp, false); > + > + /* > + * Wake the sink device > + * Spec section 2.3.1.2 if AUX CH is powered down by writing 0x02 to * DP 1.x Spec > + * DP_SET_POWER dpcd reg, 1ms time would be required to wake it > up > + */ > + while (try < 10 && ret < 0) { > + ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_SET_POWER, > &value); We can use read_data and then we get 0 on success and negative on error should make this code a lot cleaner here > + if (value) > + break; > + fsleep(1000); > + try++; > + } Nit: New line here > + /* After setting to D0 need a min of 1ms to wake(Spec sec 2.3.1.2) */ *DP 1.x Spec Regards, Suraj Kandpal > + drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, > DP_SET_POWER_D0); > + fsleep(1000); > + > + intel_dp_dpcd_set_probe(intel_dp, true); } > + > static bool > intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector > *connector) { @@ -4713,6 +4739,8 @@ intel_edp_init_dpcd(struct intel_dp > *intel_dp, struct intel_connector *connector > /* this function is meant to be called only once */ > drm_WARN_ON(display->drm, intel_dp->dpcd[DP_DPCD_REV] != 0); > > + intel_dp_wake_sink(intel_dp); > + > if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0) > return false; > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.h > b/drivers/gpu/drm/i915/display/intel_dp.h > index b0bbd5981f57..3f16077c0cc7 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.h > +++ b/drivers/gpu/drm/i915/display/intel_dp.h > @@ -232,6 +232,7 @@ bool intel_dp_dotclk_valid(struct intel_display > *display, bool intel_dp_joiner_candidate_valid(struct intel_connector > *connector, > int hdisplay, > int num_joined_pipes); > +void intel_dp_wake_sink(struct intel_dp *intel_dp); > > #define for_each_joiner_candidate(__connector, __mode, > __num_joined_pipes) \ > for ((__num_joined_pipes) = 1; (__num_joined_pipes) <= > (I915_MAX_PIPES); (__num_joined_pipes)++) \ diff --git > a/drivers/gpu/drm/i915/display/intel_dp_link_training.c > b/drivers/gpu/drm/i915/display/intel_dp_link_training.c > index 54c585c59b90..cbb712ea9f60 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c > @@ -270,6 +270,9 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp > *intel_dp) > lttpr_count = intel_dp_init_lttpr(intel_dp, dpcd); > } > > + /* After reading LTTPR wake up the sink before reading DPRX caps */ > + intel_dp_wake_sink(intel_dp); > + > /* > * The DPTX shall read the DPRX caps after LTTPR detection, so re- > read > * it here. > -- > 2.25.1
