On Thu, 19 Feb 2026, Arun R Murthy <[email protected]> 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.
>
> 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_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 (value)
> + break;
> + fsleep(1000);
> + try++;
> + }
I'll defer to Imre on the functional change in general, but if we were
to add this, it *must* be written using poll_timeout_us() and friends.
There needs to be an extremely good reason to hand roll new polling
loops.
The above loop isn't executed even one time. It's dead code.
BR,
Jani.
> + /* After setting to D0 need a min of 1ms to wake(Spec sec 2.3.1.2) */
> + 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.
--
Jani Nikula, Intel