Browse Source

drm: msm: dp: turn off audio before dp lane status toggling

There is an audio turn off timeout error whenever DP handles
the link state toggling requests from sink during audio
playback session. The audio hw is waiting for DMA write done
interrupts before issuing a audio session tear down. As the
DP controller is put into reset before link training, the
DMA write done is not sent by the DP controller hence causing
audio timeout errors. These changes turn off audio before the
DP controller is put into reset so that the audio session
tear down takes place within the stipulated time.

Change-Id: I7b88d0385a84f308d8537c2766e6fbc25a2ddc3b
Signed-off-by: RAJAT GUPTA <[email protected]>
RAJAT GUPTA 5 years ago
parent
commit
078b0f0793
1 changed files with 48 additions and 10 deletions
  1. 48 10
      msm/dp/dp_display.c

+ 48 - 10
msm/dp/dp_display.c

@@ -991,6 +991,30 @@ 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;
@@ -1178,19 +1202,33 @@ static void dp_display_attention_work(struct work_struct *work)
 		goto mst_attention;
 	}
 
-	if (dp->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
-		dp->ctrl->process_phy_test_request(dp->ctrl);
-		goto mst_attention;
-	}
+	if (dp->link->sink_request & (DP_TEST_LINK_PHY_TEST_PATTERN |
+		DP_TEST_LINK_TRAINING | DP_LINK_STATUS_UPDATED)) {
 
-	if (dp->link->sink_request & DP_TEST_LINK_TRAINING) {
-		dp->link->send_test_response(dp->link);
-		dp->ctrl->link_maintenance(dp->ctrl);
-		goto mst_attention;
+		mutex_lock(&dp->session_lock);
+		dp_audio_enable(dp, false);
+		mutex_unlock(&dp->session_lock);
+
+		if (dp->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
+			dp->ctrl->process_phy_test_request(dp->ctrl);
+
+		if (dp->link->sink_request & DP_TEST_LINK_TRAINING) {
+			dp->link->send_test_response(dp->link);
+			dp->ctrl->link_maintenance(dp->ctrl);
+		}
+
+		if (dp->link->sink_request & DP_LINK_STATUS_UPDATED)
+			dp->ctrl->link_maintenance(dp->ctrl);
+
+		mutex_lock(&dp->session_lock);
+		dp_audio_enable(dp, true);
+		mutex_unlock(&dp->session_lock);
+
+		if (dp->link->sink_request & (DP_TEST_LINK_PHY_TEST_PATTERN |
+			DP_TEST_LINK_TRAINING))
+			goto mst_attention;
 	}
 
-	if (dp->link->sink_request & DP_LINK_STATUS_UPDATED)
-		dp->ctrl->link_maintenance(dp->ctrl);
 cp_irq:
 	if (dp_display_is_hdcp_enabled(dp) && dp->hdcp.ops->cp_irq)
 		dp->hdcp.ops->cp_irq(dp->hdcp.data);