[PATCH v2] drm/amdgpu/display: DP MST hot-unplug cleanup

Shashank Sharma shashank.sharma at amd.com
Fri Apr 30 14:32:10 UTC 2021


The current DP MST hotplug handling sequence adds new remote
sinks during the MST plug-in, but it doesn't removes it during
the unplug, which results into saturation of sink count after
2 contineous hotplugs (dual monitor scenario).

This patch adds a clean-up sequence during the hot-unplug situation.

V2: Removed one extra line added in V1

Cc: Harry Wentland <harry.wentland at amd.com>
Cc: Alex Deucher <alexander.deucher at amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma at amd.com>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 30 ++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 8dc5005bec0a..8b87dd0a3d50 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -220,6 +220,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
 		struct dc_sink_init_data init_params = {
 				.link = aconnector->dc_link,
 				.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
+
 		dc_sink = dc_link_add_remote_sink(
 			aconnector->dc_link,
 			(uint8_t *)aconnector->edid,
@@ -266,15 +267,42 @@ dm_mst_atomic_best_encoder(struct drm_connector *connector,
 	return &adev->dm.mst_encoders[acrtc->crtc_id].base;
 }
 
+static void
+dm_dp_mst_sink_cleanup(struct drm_connector *connector)
+{
+        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+
+        if (aconnector->dc_sink)
+                dc_link_remove_remote_sink(aconnector->dc_link,
+                                           aconnector->dc_sink);
+
+        if (aconnector->edid) {
+                kfree(aconnector->edid);
+                aconnector->edid = NULL;
+        }
+}
+
 static int
 dm_dp_mst_detect(struct drm_connector *connector,
 		 struct drm_modeset_acquire_ctx *ctx, bool force)
 {
 	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 	struct amdgpu_dm_connector *master = aconnector->mst_port;
+        enum drm_connector_status status;
 
-	return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr,
+	status = drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr,
 				      aconnector->port);
+
+        if ((status == connector_status_disconnected) &&
+            (connector->status == connector_status_connected)) {
+
+                /* Fresh hot-unplug scenario, sink cleaup required */
+                DRM_DEBUG_DRIVER("[CONNECTOR:%d:%s] MST hot-unplug, doing sink cleanup\n",
+                connector->base.id, connector->name);
+                dm_dp_mst_sink_cleanup(connector);
+        }
+
+        return status;
 }
 
 static int dm_dp_mst_atomic_check(struct drm_connector *connector,
-- 
2.25.1



More information about the amd-gfx mailing list