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.

Cc: Harry Wentland <harry.wentl...@amd.com>
Cc: Alex Deucher <alexander.deuc...@amd.com>

Signed-off-by: Shashank Sharma <shashank.sha...@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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to