Bladeren bron

Merge "disp: msm: dp: account for fec overhead during bpp determination"

qctecmdr 4 jaren geleden
bovenliggende
commit
48e71a3272
2 gewijzigde bestanden met toevoegingen van 58 en 39 verwijderingen
  1. 42 26
      msm/dp/dp_ctrl.c
  2. 16 13
      msm/dp/dp_panel.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;
 }

+ 16 - 13
msm/dp/dp_panel.c

@@ -1795,7 +1795,8 @@ static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,
 	struct dp_panel_private *panel;
 	const u32 max_supported_bpp = 30;
 	u32 min_supported_bpp = 18;
-	u32 bpp = 0, data_rate_khz = 0;
+	u32 bpp = 0, link_bitrate = 0, mode_bitrate;
+	s64 rate_fp = 0;
 
 	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
 
@@ -1806,25 +1807,27 @@ static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,
 
 	link_params = &panel->link->link_params;
 
-	data_rate_khz = link_params->lane_count *
-		drm_dp_bw_code_to_link_rate(link_params->bw_code) * 8;
+	rate_fp = drm_int2fixp(drm_dp_bw_code_to_link_rate(link_params->bw_code) *
+			link_params->lane_count *  8);
+
+	if (dp_panel->fec_en)
+		rate_fp = drm_fixp_div(rate_fp, dp_panel->fec_overhead_fp);
+
+	link_bitrate = drm_fixp2int(rate_fp);
 
 	for (; bpp > min_supported_bpp; bpp -= 6) {
 		if (dp_panel->dsc_en) {
-			if (bpp == 36 && !(dp_panel->sink_dsc_caps.color_depth
-					& DP_DSC_12_BPC))
+			if (bpp == 30 && !(dp_panel->sink_dsc_caps.color_depth & DP_DSC_10_BPC))
 				continue;
-			else if (bpp == 30 &&
-					!(dp_panel->sink_dsc_caps.color_depth &
-					DP_DSC_10_BPC))
-				continue;
-			else if (bpp == 24 &&
-					!(dp_panel->sink_dsc_caps.color_depth &
-					DP_DSC_8_BPC))
+			else if (bpp == 24 && !(dp_panel->sink_dsc_caps.color_depth & DP_DSC_8_BPC))
 				continue;
+
+			mode_bitrate = mult_frac(mode_pclk_khz, bpp, 3);
+		} else {
+			mode_bitrate = mode_pclk_khz * bpp;
 		}
 
-		if (mode_pclk_khz * bpp <= data_rate_khz)
+		if (mode_bitrate <= link_bitrate)
 			break;
 	}