[Why&How] Set dpms off on the MST connector that was unplugged, for the side effect of releasing some references held through deallocation of mst payload. Signed-off-by: Aurabindo Pillai <aurabindo.pillai@xxxxxxx> Signed-off-by: Eryk Brol <eryk.brol@xxxxxxx> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e213246e3f04..fc984cf6e316 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1984,6 +1984,64 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, return; } +static void dm_set_dpms_off(struct dc_link *link) +{ + struct { + struct dc_surface_update surface_updates[MAX_SURFACES]; + struct dc_stream_update stream_update; + } * bundle; + struct dc_stream_state *stream_state; + struct dc_context *dc_ctx = link->ctx; + int i; + + bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); + + if (!bundle) { + dm_error("Failed to allocate update bundle\n"); + return; + } + + bundle->stream_update.dpms_off = kzalloc(sizeof(bool), GFP_KERNEL); + + if (!bundle->stream_update.dpms_off) { + dm_error("Failed to allocate update bundle\n"); + goto cleanup; + } + + *bundle->stream_update.dpms_off = true; + + for (i = 0; i< MAX_PIPES; i++) { + if (dc_ctx->dc->current_state->streams[i] == NULL) + continue; + + if (dc_ctx->dc->current_state->streams[i]->link == link) { + stream_state = dc_ctx->dc->current_state->streams[i]; + goto link_found; + } + } + + dm_error("Cannot find link associated with the stream to be disabled\n"); + return; + +link_found: + if (stream_state == NULL) { + dm_error("Stream state associated with the link is NULL\n"); + return; + } + + bundle->stream_update.stream = stream_state; + + dc_commit_updates_for_stream(stream_state->ctx->dc, bundle->surface_updates, 0, + stream_state, &bundle->stream_update, + stream_state->ctx->dc->current_state); + + kfree(bundle->stream_update.dpms_off); +cleanup: + kfree(bundle); + + return; +} + static int dm_resume(void *handle) { struct amdgpu_device *adev = handle; @@ -2434,8 +2492,11 @@ static void handle_hpd_irq(void *param) drm_kms_helper_hotplug_event(dev); } else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) { - amdgpu_dm_update_connector_after_detect(aconnector); + if (new_connection_type == dc_connection_none && + aconnector->dc_link->type == dc_connection_none) + dm_set_dpms_off(aconnector->dc_link); + amdgpu_dm_update_connector_after_detect(aconnector); drm_modeset_lock_all(dev); dm_restore_drm_connector_state(dev, connector); -- 2.25.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx