From 33f6b8e11e82e366711043d65d9adfa57fecc94a Mon Sep 17 00:00:00 2001 From: Sankeerth Billakanti Date: Fri, 27 Dec 2019 11:17:46 +0530 Subject: [PATCH] disp: msm: dp: fix for screen freeze on dp disconnect The DP display driver issues an audio disconnect notification after the video disconnect notification. Sometimes audio driver is waiting for the video commit to complete before turning off the audio engine. In such cases, there is a brief screen freeze observed on the primary. In other cases, when the off call from audio driver gets delayed, a momentary screen freeze is seen. The audio notification happens as part of the display commit call. The order of notification is video and then audio while processing display connect and the same order is followed for disconnect also, which is causing this issue. These changes will modify the order of notification to send audio disconnect first and then video while processing DP cable disconnect. Change-Id: I8bece39c164620b319d971e5a2597d9dc187566e Signed-off-by: Sankeerth Billakanti Signed-off-by: Tatenda Chipeperekwa --- msm/dp/dp_audio.c | 8 +++++++- msm/dp/dp_display.c | 50 ++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/msm/dp/dp_audio.c b/msm/dp/dp_audio.c index 67f3741f9d..8284207408 100644 --- a/msm/dp/dp_audio.c +++ b/msm/dp/dp_audio.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -766,6 +766,12 @@ static int dp_audio_off(struct dp_audio *dp_audio) } audio = container_of(dp_audio, struct dp_audio_private, dp_audio); + + if (!atomic_read(&audio->session_on)) { + DP_DEBUG("audio already off\n"); + return rc; + } + ext = &audio->ext_audio_data; work_pending = cancel_delayed_work_sync(&audio->notify_delayed_work); diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 1866eeed54..ca4605f3fb 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -246,6 +246,30 @@ static bool dp_display_is_ready(struct dp_display_private *dp) dp->hpd->alt_mode_cfg_done; } +static void dp_audio_enable(struct dp_display_private *dp, bool enable) +{ + struct dp_panel *dp_panel; + int idx; + + for (idx = DP_STREAM_0; idx < DP_STREAM_MAX; idx++) { + if (!dp->active_panels[idx]) + continue; + dp_panel = dp->active_panels[idx]; + + if (dp_panel->audio_supported) { + if (enable) { + dp_panel->audio->bw_code = + dp->link->link_params.bw_code; + dp_panel->audio->lane_count = + dp->link->link_params.lane_count; + dp_panel->audio->on(dp_panel->audio); + } else { + dp_panel->audio->off(dp_panel->audio); + } + } + } +} + static void dp_display_update_hdcp_status(struct dp_display_private *dp, bool reset) { @@ -1065,7 +1089,7 @@ static int dp_display_process_hpd_low(struct dp_display_private *dp) dp_display_state_remove(DP_STATE_CONNECTED); dp->process_hpd_connect = false; - + dp_audio_enable(dp, false); dp_display_process_mst_hpd_low(dp); if ((dp_display_state_is(DP_STATE_CONNECT_NOTIFIED) || @@ -1150,30 +1174,6 @@ static void dp_display_stream_disable(struct dp_display_private *dp, dp->active_stream_cnt--; } -static void dp_audio_enable(struct dp_display_private *dp, bool enable) -{ - struct dp_panel *dp_panel; - int idx; - - for (idx = DP_STREAM_0; idx < DP_STREAM_MAX; idx++) { - if (!dp->active_panels[idx]) - continue; - dp_panel = dp->active_panels[idx]; - - if (dp_panel->audio_supported) { - if (enable) { - dp_panel->audio->bw_code = - dp->link->link_params.bw_code; - dp_panel->audio->lane_count = - dp->link->link_params.lane_count; - dp_panel->audio->on(dp_panel->audio); - } else { - dp_panel->audio->off(dp_panel->audio); - } - } - } -} - static void dp_display_clean(struct dp_display_private *dp) { int idx;