diff mbox series

[v3,10/21] drm/i915/dp: Send a link training modeset-retry uevent to all MST connectors

Message ID 20240610164933.2947366-11-imre.deak@intel.com (mailing list archive)
State New
Headers show
Series drm/i915/dp_mst: Enable link training fallback | expand

Commit Message

Imre Deak June 10, 2024, 4:49 p.m. UTC
Send a modeset-retry uevent to all connectors in the same MST topology
after a link training failure and reduction of the link parameters. This
matches the way the same uevent is sent after a DP tunnel BW allocation
failure.

v2: Add NOTE that the atomic state may not be valid for SST links and
    assert that it's valid for MST links. (Ville)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c          |  7 ++++++-
 drivers/gpu/drm/i915/display/intel_dp.h          |  1 -
 .../drm/i915/display/intel_dp_link_training.c    | 16 ++++++++++++----
 3 files changed, 18 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 4438ec2989249..8259d91d2d041 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2793,7 +2793,7 @@  intel_dp_audio_compute_config(struct intel_encoder *encoder,
 					intel_dp_is_uhbr(pipe_config);
 }
 
-void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
+static void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
 {
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 
@@ -2802,6 +2802,7 @@  void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
 		drm_connector_put(&connector->base);
 }
 
+/* NOTE: @state is only valid for MST links and can be %NULL for SST. */
 void
 intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
 				      struct intel_encoder *encoder,
@@ -2810,6 +2811,7 @@  intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
 	struct intel_connector *connector;
 	struct intel_digital_connector_state *conn_state;
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int i;
 
 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
@@ -2818,6 +2820,9 @@  intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
 		return;
 	}
 
+	if (drm_WARN_ON(&i915->drm, !state))
+		return;
+
 	for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
 		if (!conn_state->base.crtc)
 			continue;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 279cca23b95fa..ec4131db07439 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -44,7 +44,6 @@  bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state);
 int intel_dp_min_bpp(enum intel_output_format output_format);
 void intel_dp_init_modeset_retry_work(struct intel_connector *connector);
-void intel_dp_queue_modeset_retry_work(struct intel_connector *connector);
 void
 intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
 				      struct intel_encoder *encoder,
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 04629a4341eef..bb8680ac7f4da 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -1187,10 +1187,13 @@  static int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 	return 0;
 }
 
-static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
+/* NOTE: @state is only valid for MST links and can be %NULL for SST. */
+static void intel_dp_schedule_fallback_link_training(struct intel_atomic_state *state,
+						     struct intel_dp *intel_dp,
 						     const struct intel_crtc_state *crtc_state)
 {
-	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 
 	if (!intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base)) {
 		lt_dbg(intel_dp, DP_PHY_DPRX, "Link Training failed on disconnected sink.\n");
@@ -1205,8 +1208,13 @@  static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
 		return;
 	}
 
+	if (drm_WARN_ON(&i915->drm,
+			intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+			!state))
+		return;
+
 	/* Schedule a Hotplug Uevent to userspace to start modeset */
-	intel_dp_queue_modeset_retry_work(intel_connector);
+	intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state);
 }
 
 /* Perform the link training on all LTTPRs and the DPRX on a link. */
@@ -1525,7 +1533,7 @@  void intel_dp_start_link_train(struct intel_atomic_state *state,
 		return;
 	}
 
-	intel_dp_schedule_fallback_link_training(intel_dp, crtc_state);
+	intel_dp_schedule_fallback_link_training(state, intel_dp, crtc_state);
 }
 
 void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,