瀏覽代碼

disp: msm: dp: enable fec only for the first stream

FEC is a link specific configuration and should be configured before
the MST streams are enabled. Currently, the driver is configuring FEC
for each stream and in a case where the first stream is compressed and
the second stream is uncompressed, it enables FEC before the first
stream is enabled but ends up disabling FEC when the second stream is
enabled.

This change splits FEC/DSC configuration into separate functions and
skips FEC configuration for the second stream.

Change-Id: Ic1bab321dc77da7ec5c0253c93bb69735a217fd6
Signed-off-by: Rajkumar Subbiah <[email protected]>
Rajkumar Subbiah 4 年之前
父節點
當前提交
07b0a4d81a
共有 1 個文件被更改,包括 42 次插入26 次删除
  1. 42 26
      msm/dp/dp_ctrl.c

+ 42 - 26
msm/dp/dp_ctrl.c

@@ -563,6 +563,9 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl)
 		goto end;
 	}
 
+	/* disable FEC before link training */
+	ctrl->catalog->fec_config(ctrl->catalog, false);
+
 	ret = dp_ctrl_link_training_1(ctrl);
 	if (ret) {
 		DP_ERR("link training #1 failed\n");
@@ -895,6 +898,41 @@ static void dp_ctrl_send_video(struct dp_ctrl_private *ctrl)
 	ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO);
 }
 
+static void dp_ctrl_fec_setup(struct dp_ctrl_private *ctrl)
+{
+	u8 fec_sts = 0;
+	int i, max_retries = 3;
+	bool fec_en_detected = false;
+
+	if (!ctrl->fec_mode)
+		return;
+
+	/* FEC should be set only for the first stream */
+	if (ctrl->stream_count > 1)
+		return;
+
+	/* Need to try to enable multiple times due to BS symbols collisions */
+	for (i = 0; i < max_retries; i++) {
+		ctrl->catalog->fec_config(ctrl->catalog, ctrl->fec_mode);
+
+		/* wait for controller to start fec sequence */
+		usleep_range(900, 1000);
+
+		/* read back FEC status and check if it is enabled */
+		drm_dp_dpcd_readb(ctrl->aux->drm_aux, DP_FEC_STATUS, &fec_sts);
+		if (fec_sts & DP_FEC_DECODE_EN_DETECTED) {
+			fec_en_detected = true;
+			break;
+		}
+	}
+
+	SDE_EVT32_EXTERNAL(i, fec_en_detected);
+	DP_DEBUG("retries %d, fec_en_detected %d\n", i, fec_en_detected);
+
+	if (!fec_en_detected)
+		DP_WARN("failed to enable sink fec\n");
+}
+
 static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl)
 {
 	int ret = 0;
@@ -933,6 +971,7 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl)
 	if (ctrl->stream_count) {
 		dp_ctrl_send_video(ctrl);
 		dp_ctrl_wait4video_ready(ctrl);
+		dp_ctrl_fec_setup(ctrl);
 	}
 end:
 	return ret;
@@ -1173,38 +1212,14 @@ static void dp_ctrl_mst_stream_setup(struct dp_ctrl_private *ctrl,
 			lanes, bw_code, x_int, y_frac_enum);
 }
 
-static void dp_ctrl_fec_dsc_setup(struct dp_ctrl_private *ctrl)
+static void dp_ctrl_dsc_setup(struct dp_ctrl_private *ctrl)
 {
-	u8 fec_sts = 0;
 	int rlen;
 	u32 dsc_enable;
-	int i, max_retries = 3;
-	bool fec_en_detected = false;
 
 	if (!ctrl->fec_mode)
 		return;
 
-	/* Need to try to enable multiple times due to BS symbols collisions */
-	for (i = 0; i < max_retries; i++) {
-		ctrl->catalog->fec_config(ctrl->catalog, ctrl->fec_mode);
-
-		/* wait for controller to start fec sequence */
-		usleep_range(900, 1000);
-
-		/* read back FEC status and check if it is enabled */
-		drm_dp_dpcd_readb(ctrl->aux->drm_aux, DP_FEC_STATUS, &fec_sts);
-		if (fec_sts & DP_FEC_DECODE_EN_DETECTED) {
-			fec_en_detected = true;
-			break;
-		}
-	}
-
-	SDE_EVT32_EXTERNAL(i, fec_en_detected);
-	DP_DEBUG("retries %d, fec_en_detected %d\n", i, fec_en_detected);
-
-	if (!fec_en_detected)
-		DP_WARN("failed to enable sink fec\n");
-
 	dsc_enable = ctrl->dsc_mode ? 1 : 0;
 	rlen = drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_DSC_ENABLE,
 			dsc_enable);
@@ -1257,7 +1272,8 @@ static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel)
 	DP_DEBUG("mainlink %s\n", link_ready ? "READY" : "NOT READY");
 
 	/* wait for link training completion before fec config as per spec */
-	dp_ctrl_fec_dsc_setup(ctrl);
+	dp_ctrl_fec_setup(ctrl);
+	dp_ctrl_dsc_setup(ctrl);
 
 	return rc;
 }