浏览代码

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 年之前
父节点
当前提交
078b0f0793
共有 1 个文件被更改,包括 48 次插入10 次删除
  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);