diff mbox series

[2/2] drm/i915/lttpr: Enable Extended Wake Timeout

Message ID 20250117054850.1189650-3-suraj.kandpal@intel.com (mailing list archive)
State New
Headers show
Series Extended Wake Timeout | expand

Commit Message

Suraj Kandpal Jan. 17, 2025, 5:48 a.m. UTC
Usually retimers take around 30 to 40ms to exit all devices from
sleep state. Extended wake timeout request helps to give additional
time by reading the DPCD register through which sink requests the
minimal amount of time required to wake the sink up.
Source  device shall keep retying  the AUX tansaction till the extended
timeout that is being granted for LTTPRs from the sink device

--v2
-Grant the requested time only if greater than 1ms [Arun]
-Reframe commit message [Arun]

Spec: DP v2.1 Section 3.6.12.3
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  2 +
 .../drm/i915/display/intel_dp_link_training.c | 49 +++++++++++++++++++
 .../drm/i915/display/intel_dp_link_training.h |  1 +
 3 files changed, 52 insertions(+)

Comments

Dmitry Baryshkov Jan. 17, 2025, 6:19 a.m. UTC | #1
On Fri, Jan 17, 2025 at 11:18:50AM +0530, Suraj Kandpal wrote:
> Usually retimers take around 30 to 40ms to exit all devices from
> sleep state. Extended wake timeout request helps to give additional
> time by reading the DPCD register through which sink requests the
> minimal amount of time required to wake the sink up.
> Source  device shall keep retying  the AUX tansaction till the extended
> timeout that is being granted for LTTPRs from the sink device
> 
> --v2
> -Grant the requested time only if greater than 1ms [Arun]
> -Reframe commit message [Arun]
> 
> Spec: DP v2.1 Section 3.6.12.3
> Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  2 +
>  .../drm/i915/display/intel_dp_link_training.c | 49 +++++++++++++++++++
>  .../drm/i915/display/intel_dp_link_training.h |  1 +
>  3 files changed, 52 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index acb986bc1f33..96cabe618678 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2645,6 +2645,8 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
>  	if (!is_mst)
>  		intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>  
> +	intel_dp_lttpr_wake_timeout_setup(intel_dp);
> +
>  	intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>  	if (!is_mst)
>  		intel_dp_sink_enable_decompression(state,
> 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 8b1977cfec50..c113b0be259e 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> @@ -135,6 +135,55 @@ static bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp)
>  		DP_PHY_REPEATER_MODE_TRANSPARENT;
>  }
>  
> +void intel_dp_lttpr_wake_timeout_setup(struct intel_dp *intel_dp)

Please move this function to drivers/gpu/drm/display/drm_dp_helper.c
Except for the intel_dp_lttpr_transparent_mode_enabled() call there is
nothing Intel-specific there.

> +{
> +	struct intel_display *display = to_intel_display(intel_dp);
> +	u8 val = 1;
> +	int ret;
> +
> +	if (intel_dp_lttpr_transparent_mode_enabled(intel_dp)) {
> +		static const u8 timeout_mapping[] = {
> +			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_1_MS] = 1,
> +			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_20_MS] = 20,
> +			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_40_MS] = 40,
> +			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_20_MS] = 20,
> +			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_80_MS] = 80,
> +			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_100_MS] = 100,
> +		};
> +
> +		ret = drm_dp_dpcd_readb(&intel_dp->aux,
> +					DP_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST, &val);
> +		if (ret != 1) {
> +			drm_dbg_kms(display->drm,
> +				    "Failed to read Extended sleep wake timeout request\n");
> +			return;
> +		}
> +
> +		val = (val < sizeof(timeout_mapping) && timeout_mapping[val]) ?
> +			timeout_mapping[val] : 1;
> +
> +		if (val > 1)
> +			drm_dp_dpcd_writeb(&intel_dp->aux,
> +					   DP_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_GRANT,
> +					   DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_GRANTED);
> +	} else {
> +		ret = drm_dp_dpcd_readb(&intel_dp->aux,
> +					DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &val);
> +		if (ret != 1) {
> +			drm_dbg_kms(display->drm,
> +				    "Failed to read Extended sleep wake timeout request\n");
> +			return;
> +		}
> +
> +		val = (val & DP_EXTENDED_WAKE_TIMEOUT_REQUEST_MASK) ?
> +			(val & DP_EXTENDED_WAKE_TIMEOUT_REQUEST_MASK) * 10 : 1;
> +
> +		if (val > 1)
> +			drm_dp_dpcd_writeb(&intel_dp->aux, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT,
> +					   DP_EXTENDED_WAKE_TIMEOUT_GRANT);
> +	}
> +}
> +
>  /*
>   * Read the LTTPR common capabilities and switch the LTTPR PHYs to
>   * non-transparent mode if this is supported. Preserve the
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
> index 2066b9146762..cd4e0d6db6ed 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
> @@ -15,6 +15,7 @@ struct intel_dp;
>  
>  int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE]);
>  int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
> +void intel_dp_lttpr_wake_timeout_setup(struct intel_dp *intel_dp);
>  
>  void intel_dp_link_training_set_mode(struct intel_dp *intel_dp,
>  				     int link_rate, bool is_vrr);
> -- 
> 2.34.1
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index acb986bc1f33..96cabe618678 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2645,6 +2645,8 @@  static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	if (!is_mst)
 		intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
 
+	intel_dp_lttpr_wake_timeout_setup(intel_dp);
+
 	intel_dp_configure_protocol_converter(intel_dp, crtc_state);
 	if (!is_mst)
 		intel_dp_sink_enable_decompression(state,
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 8b1977cfec50..c113b0be259e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -135,6 +135,55 @@  static bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp)
 		DP_PHY_REPEATER_MODE_TRANSPARENT;
 }
 
+void intel_dp_lttpr_wake_timeout_setup(struct intel_dp *intel_dp)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+	u8 val = 1;
+	int ret;
+
+	if (intel_dp_lttpr_transparent_mode_enabled(intel_dp)) {
+		static const u8 timeout_mapping[] = {
+			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_1_MS] = 1,
+			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_20_MS] = 20,
+			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_40_MS] = 40,
+			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_20_MS] = 20,
+			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_80_MS] = 80,
+			[DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_100_MS] = 100,
+		};
+
+		ret = drm_dp_dpcd_readb(&intel_dp->aux,
+					DP_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_REQUEST, &val);
+		if (ret != 1) {
+			drm_dbg_kms(display->drm,
+				    "Failed to read Extended sleep wake timeout request\n");
+			return;
+		}
+
+		val = (val < sizeof(timeout_mapping) && timeout_mapping[val]) ?
+			timeout_mapping[val] : 1;
+
+		if (val > 1)
+			drm_dp_dpcd_writeb(&intel_dp->aux,
+					   DP_EXTENDED_DPRX_SLEEP_WAKE_TIMEOUT_GRANT,
+					   DP_DPRX_SLEEP_WAKE_TIMEOUT_PERIOD_GRANTED);
+	} else {
+		ret = drm_dp_dpcd_readb(&intel_dp->aux,
+					DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &val);
+		if (ret != 1) {
+			drm_dbg_kms(display->drm,
+				    "Failed to read Extended sleep wake timeout request\n");
+			return;
+		}
+
+		val = (val & DP_EXTENDED_WAKE_TIMEOUT_REQUEST_MASK) ?
+			(val & DP_EXTENDED_WAKE_TIMEOUT_REQUEST_MASK) * 10 : 1;
+
+		if (val > 1)
+			drm_dp_dpcd_writeb(&intel_dp->aux, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT,
+					   DP_EXTENDED_WAKE_TIMEOUT_GRANT);
+	}
+}
+
 /*
  * Read the LTTPR common capabilities and switch the LTTPR PHYs to
  * non-transparent mode if this is supported. Preserve the
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 2066b9146762..cd4e0d6db6ed 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -15,6 +15,7 @@  struct intel_dp;
 
 int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE]);
 int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
+void intel_dp_lttpr_wake_timeout_setup(struct intel_dp *intel_dp);
 
 void intel_dp_link_training_set_mode(struct intel_dp *intel_dp,
 				     int link_rate, bool is_vrr);