From 83de56ec5e745d32cb42e20c2ed7b4b9db1aead2 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 --- msm/dp/dp_audio.c | 6 ++++++ msm/dp/dp_display.c | 50 ++++++++++++++++++++++----------------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/msm/dp/dp_audio.c b/msm/dp/dp_audio.c index 67f3741f9ddf..90c3ad16dba6 100644 --- a/msm/dp/dp_audio.c +++ b/msm/dp/dp_audio.c @@ -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 e51b63ac65f0..187ae528aad9 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -245,6 +245,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) { @@ -1022,7 +1046,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) || @@ -1107,30 +1131,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;