diff mbox series

[12/14] drm/i915/dp_mst: Reprobe the MST topology after a link parameter change

Message ID 20240722165503.2084999-13-imre.deak@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/dp_mst: Enable LT fallback for UHBR<->non-UHBR rates | expand

Commit Message

Imre Deak July 22, 2024, 4:55 p.m. UTC
The MST link BW reported by branch devices via the ENUM_PATH_RESOURCES
message depends on the channel coding and link rate/lane count
parameters programmed to DPCD. This is the case at least for some branch
devices, while for others the reported BW is independent of the link
parameters. In any case the DP standard requires the branch device to
adjust the returned value to both account for the different way the BW
for FEC is accounted for (included in the returned value for non-UHBR
and not included for UHBR rates) and to limit the returned value to the
(trained) link BW between the source and first downstreaam branch
device, see DP v2.0/v2.1 Figure 2-94, DP v2.1 5.9.7. Presumedly this is
also the reason why the standard requires the DPCD link rate/lane count
values being up-to-date before sending the ENUM_PATH_RESOURCES message,
see DP v2.1 2.14.9.4.

Based on the above reprobe the MST topology after the link is retrained
with new link parameters to make sure that the MST link BW tracked in
the MST topology state (via each topology port's full_pbn value) is
up-to-date.

The next patch will make sure that the MST link BW is also kept
up-to-date if the link is disabled.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  8 +++++
 drivers/gpu/drm/i915/display/intel_dp.c       |  2 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   | 32 ++++++++++++++++++-
 3 files changed, 41 insertions(+), 1 deletion(-)

Comments

Kandpal, Suraj July 24, 2024, 8:48 a.m. UTC | #1
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces@lists.freedesktop.org> On Behalf Of Imre
> Deak
> Sent: Monday, July 22, 2024 10:25 PM
> To: intel-gfx@lists.freedesktop.org
> Subject: [PATCH 12/14] drm/i915/dp_mst: Reprobe the MST topology after a
> link parameter change
> 
> The MST link BW reported by branch devices via the
> ENUM_PATH_RESOURCES message depends on the channel coding and link
> rate/lane count parameters programmed to DPCD. This is the case at least
> for some branch devices, while for others the reported BW is independent
> of the link parameters. In any case the DP standard requires the branch
> device to adjust the returned value to both account for the different way
> the BW for FEC is accounted for (included in the returned value for non-
> UHBR and not included for UHBR rates) and to limit the returned value to
> the
> (trained) link BW between the source and first downstreaam branch device,
> see DP v2.0/v2.1 Figure 2-94, DP v2.1 5.9.7. Presumedly this is also the
> reason why the standard requires the DPCD link rate/lane count values
> being up-to-date before sending the ENUM_PATH_RESOURCES message, see
> DP v2.1 2.14.9.4.
> 
> Based on the above reprobe the MST topology after the link is retrained
> with new link parameters to make sure that the MST link BW tracked in the
> MST topology state (via each topology port's full_pbn value) is up-to-date.
> 
> The next patch will make sure that the MST link BW is also kept up-to-date if
> the link is disabled.
> 
> Signed-off-by: Imre Deak <imre.deak@intel.com>

LGTM,
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
> ---
>  .../drm/i915/display/intel_display_types.h    |  8 +++++
>  drivers/gpu/drm/i915/display/intel_dp.c       |  2 ++
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 32 ++++++++++++++++++-
>  3 files changed, 41 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 51e2151315977..afd8329e3ed6e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1794,6 +1794,14 @@ struct intel_dp {
>  		int max_lane_count;
>  		/* Max rate for the current link */
>  		int max_rate;
> +		/*
> +		 * Link parameters for which the MST topology was probed.
> +		 * Tracking these ensures that the MST path resources are
> +		 * re-enumerated whenever the link is retrained with new
> link
> +		 * parameters, as required by the DP standard.
> +		 */
> +		int mst_probed_lane_count;
> +		int mst_probed_rate;
>  		int force_lane_count;
>  		int force_rate;
>  		bool retrain_disabled;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 1c6d1db1d2690..0771e4c6357ba 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -3134,6 +3134,8 @@ void intel_dp_reset_link_params(struct intel_dp
> *intel_dp)  {
>  	intel_dp->link.max_lane_count =
> intel_dp_max_common_lane_count(intel_dp);
>  	intel_dp->link.max_rate = intel_dp_max_common_rate(intel_dp);
> +	intel_dp->link.mst_probed_lane_count = 0;
> +	intel_dp->link.mst_probed_rate = 0;
>  	intel_dp->link.retrain_disabled = false;
>  	intel_dp->link.seq_train_failures = 0;  } diff --git
> a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 57f29906fa28f..19c8b6878b030 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -1113,6 +1113,33 @@ static void intel_mst_pre_pll_enable_dp(struct
> intel_atomic_state *state,
>  					     to_intel_crtc(pipe_config-
> >uapi.crtc));
>  }
> 
> +static bool intel_mst_probed_link_params_valid(struct intel_dp *intel_dp,
> +					       int link_rate, int lane_count) {
> +	return intel_dp->link.mst_probed_rate == link_rate &&
> +		intel_dp->link.mst_probed_lane_count == lane_count; }
> +
> +static void intel_mst_set_probed_link_params(struct intel_dp *intel_dp,
> +					     int link_rate, int lane_count) {
> +	intel_dp->link.mst_probed_rate = link_rate;
> +	intel_dp->link.mst_probed_lane_count = lane_count; }
> +
> +static void intel_mst_reprobe_topology(struct intel_dp *intel_dp,
> +				       const struct intel_crtc_state *crtc_state) {
> +	if (intel_mst_probed_link_params_valid(intel_dp,
> +					       crtc_state->port_clock, crtc_state-
> >lane_count))
> +		return;
> +
> +	drm_dp_mst_topology_queue_probe(&intel_dp->mst_mgr);
> +
> +	intel_mst_set_probed_link_params(intel_dp,
> +					 crtc_state->port_clock, crtc_state-
> >lane_count); }
> +
>  static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
>  				    struct intel_encoder *encoder,
>  				    const struct intel_crtc_state *pipe_config,
> @@ -1149,10 +1176,13 @@ static void intel_mst_pre_enable_dp(struct
> intel_atomic_state *state,
> 
>  	intel_dp_sink_enable_decompression(state, connector, pipe_config);
> 
> -	if (first_mst_stream)
> +	if (first_mst_stream) {
>  		dig_port->base.pre_enable(state, &dig_port->base,
>  						pipe_config, NULL);
> 
> +		intel_mst_reprobe_topology(intel_dp, pipe_config);
> +	}
> +
>  	intel_dp->active_mst_links++;
> 
>  	ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state,
> --
> 2.44.2
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 51e2151315977..afd8329e3ed6e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1794,6 +1794,14 @@  struct intel_dp {
 		int max_lane_count;
 		/* Max rate for the current link */
 		int max_rate;
+		/*
+		 * Link parameters for which the MST topology was probed.
+		 * Tracking these ensures that the MST path resources are
+		 * re-enumerated whenever the link is retrained with new link
+		 * parameters, as required by the DP standard.
+		 */
+		int mst_probed_lane_count;
+		int mst_probed_rate;
 		int force_lane_count;
 		int force_rate;
 		bool retrain_disabled;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 1c6d1db1d2690..0771e4c6357ba 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3134,6 +3134,8 @@  void intel_dp_reset_link_params(struct intel_dp *intel_dp)
 {
 	intel_dp->link.max_lane_count = intel_dp_max_common_lane_count(intel_dp);
 	intel_dp->link.max_rate = intel_dp_max_common_rate(intel_dp);
+	intel_dp->link.mst_probed_lane_count = 0;
+	intel_dp->link.mst_probed_rate = 0;
 	intel_dp->link.retrain_disabled = false;
 	intel_dp->link.seq_train_failures = 0;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 57f29906fa28f..19c8b6878b030 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1113,6 +1113,33 @@  static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state,
 					     to_intel_crtc(pipe_config->uapi.crtc));
 }
 
+static bool intel_mst_probed_link_params_valid(struct intel_dp *intel_dp,
+					       int link_rate, int lane_count)
+{
+	return intel_dp->link.mst_probed_rate == link_rate &&
+		intel_dp->link.mst_probed_lane_count == lane_count;
+}
+
+static void intel_mst_set_probed_link_params(struct intel_dp *intel_dp,
+					     int link_rate, int lane_count)
+{
+	intel_dp->link.mst_probed_rate = link_rate;
+	intel_dp->link.mst_probed_lane_count = lane_count;
+}
+
+static void intel_mst_reprobe_topology(struct intel_dp *intel_dp,
+				       const struct intel_crtc_state *crtc_state)
+{
+	if (intel_mst_probed_link_params_valid(intel_dp,
+					       crtc_state->port_clock, crtc_state->lane_count))
+		return;
+
+	drm_dp_mst_topology_queue_probe(&intel_dp->mst_mgr);
+
+	intel_mst_set_probed_link_params(intel_dp,
+					 crtc_state->port_clock, crtc_state->lane_count);
+}
+
 static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 				    struct intel_encoder *encoder,
 				    const struct intel_crtc_state *pipe_config,
@@ -1149,10 +1176,13 @@  static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 
 	intel_dp_sink_enable_decompression(state, connector, pipe_config);
 
-	if (first_mst_stream)
+	if (first_mst_stream) {
 		dig_port->base.pre_enable(state, &dig_port->base,
 						pipe_config, NULL);
 
+		intel_mst_reprobe_topology(intel_dp, pipe_config);
+	}
+
 	intel_dp->active_mst_links++;
 
 	ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state,