On Thu, Feb 19, 2026 at 03:13:26PM +0530, Arun R Murthy wrote: > Before reading the DPCD caps for eDP wake the sink device and for DP > after reading the lttpr caps and before reading the dpcd caps wake up > the sink device.
Why? > > Closes: https://issues.redhat.com/browse/RHEL-120913 > Signed-off-by: Arun R Murthy <[email protected]> > --- > drivers/gpu/drm/i915/display/intel_dp.c | 41 +++++++++++++++++++ > drivers/gpu/drm/i915/display/intel_dp.h | 1 + > .../drm/i915/display/intel_dp_link_training.c | 3 ++ > 3 files changed, 45 insertions(+) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 454e6144ee4e..2fbb947e6cc8 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -4705,6 +4705,45 @@ 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 DP2.1 section 2.3.1.2 if AUX CH is powered down by writing 0x02 > + * to 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); > + /* > + * If sink is in D3 then it may not respond to the AUX tx so > + * wake it up to D3_AUX_ON state > + */ > + if (value == DP_SET_POWER_D3) { > + /* After setting to D0 need a min of 1ms to wake(Spec > DP2.1 sec 2.3.1.2) */ > + drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, > + DP_SET_POWER_D0); > + fsleep(1000); > + drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, > + DP_SET_POWER_D3_AUX_ON); > + break; > + } else if ((value == DP_SET_POWER_D0) || > + (value == DP_SET_POWER_D3_AUX_ON)) { > + /* if in D0 or D3_AUX_ON exit */ > + break; > + } > + /* Sink in D0 or even if read fails a minimum of 1ms is > required to wake and respond */ > + fsleep(1000); > + try++; > + } > + > + 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 +4752,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 -- Ville Syrjälä Intel
