aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c32
3 files changed, 41 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index ac98bb57456e..327a4133030f 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 d707ad666993..5523469404f9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3126,6 +3126,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 57f29906fa28..19c8b6878b03 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,