Explorar o código

disp: msm: dp: fix mode filtering for 4K120

Currently, 4K120 mode is being filtered by DP driver
due to invalid topology assignation. When 4 LMs are
needed, the number of DSCs must match the number of
LMs since only DSCMERGE based topologies are supported
for driving DSC capable panels.

This change fixes the topology validation logic and
aggregates LM and DSC validation functions in the topology
one since the number of LMs and DSCs must now be considered
in calculating the topology requirement.

Change-Id: I95577eabb34068cd490d23e70ffbb899d1c2d03a
Signed-off-by: Amine Najahi <[email protected]>
Amine Najahi %!s(int64=4) %!d(string=hai) anos
pai
achega
2c98ff7194
Modificáronse 1 ficheiros con 27 adicións e 66 borrados
  1. 27 66
      msm/dp/dp_display.c

+ 27 - 66
msm/dp/dp_display.c

@@ -2740,55 +2740,6 @@ static int dp_display_validate_pixel_clock(struct dp_display_mode dp_mode,
 	return 0;
 }
 
-static int dp_display_validate_mixers(struct msm_drm_private *priv,
-		struct drm_display_mode *mode,
-		const struct msm_resource_caps_info *avail_res)
-{
-	int rc;
-	u32 num_lm = 0;
-
-	rc = msm_get_mixer_count(priv, mode, avail_res, &num_lm);
-	if (rc) {
-		DP_ERR("error getting mixer count. rc:%d\n", rc);
-		return rc;
-	}
-
-	if (num_lm > avail_res->num_lm) {
-		DP_DEBUG("num lm:%d > available lm:%d\n", num_lm,
-				avail_res->num_lm);
-		return -EPERM;
-	}
-
-	return 0;
-}
-
-static int dp_display_validate_dscs(struct msm_drm_private *priv,
-		struct dp_panel *dp_panel, struct drm_display_mode *mode,
-		struct dp_display_mode *dp_mode,
-		const struct msm_resource_caps_info *avail_res)
-{
-	int rc;
-	u32 num_dsc = 0;
-	bool dsc_capable = dp_mode->capabilities & DP_PANEL_CAPS_DSC;
-
-	if (!dp_panel->dsc_en || !dsc_capable)
-		return 0;
-
-	rc = msm_get_dsc_count(priv, mode->hdisplay, &num_dsc);
-	if (rc) {
-		DP_ERR("error getting dsc count. rc:%d\n", rc);
-		return rc;
-	}
-
-	if (num_dsc > avail_res->num_dsc) {
-		DP_DEBUG("num dsc:%d > available dsc:%d\n", num_dsc,
-				avail_res->num_dsc);
-		return -EPERM;
-	}
-
-	return 0;
-}
-
 static int dp_display_validate_topology(struct dp_display_private *dp,
 		struct dp_panel *dp_panel, struct drm_display_mode *mode,
 		struct dp_display_mode *dp_mode,
@@ -2796,9 +2747,10 @@ static int dp_display_validate_topology(struct dp_display_private *dp,
 {
 	int rc;
 	struct msm_drm_private *priv = dp->priv;
-	const u32 dual_lm = 2, quad_lm = 4;
+	const u32 dual = 2, quad = 4;
 	u32 num_lm = 0, num_dsc = 0, num_3dmux = 0;
 	bool dsc_capable = dp_mode->capabilities & DP_PANEL_CAPS_DSC;
+	u32 fps = dp_mode->timing.refresh_rate;
 
 	rc = msm_get_mixer_count(priv, mode, avail_res, &num_lm);
 	if (rc) {
@@ -2806,24 +2758,42 @@ static int dp_display_validate_topology(struct dp_display_private *dp,
 		return rc;
 	}
 
-	num_3dmux = avail_res->num_3dmux;
-
+	/* Merge using DSC, if enabled */
 	if (dp_panel->dsc_en && dsc_capable) {
 		rc = msm_get_dsc_count(priv, mode->hdisplay, &num_dsc);
 		if (rc) {
 			DP_ERR("error getting dsc count. rc:%d\n", rc);
 			return rc;
 		}
+
+		/* Only DSCMERGE is supported on DP */
+		num_lm  = max(num_lm, num_dsc);
+		num_dsc = max(num_lm, num_dsc);
+	} else {
+		num_3dmux = avail_res->num_3dmux;
 	}
 
-	/* filter out unsupported DP topologies */
-	if ((num_lm == dual_lm && (!num_3dmux && !num_dsc)) ||
-			(num_lm == quad_lm && (num_dsc != 4))) {
-		DP_DEBUG("invalid topology lm:%d dsc:%d 3dmux:%d intf:1\n",
-				num_lm, num_dsc, num_3dmux);
+	if (num_lm > avail_res->num_lm) {
+		DP_DEBUG("mode %sx%d is invalid, not enough lm %d %d\n",
+				mode->name, fps, num_lm, num_lm, avail_res->num_lm);
+		return -EPERM;
+	} else if (num_dsc > avail_res->num_dsc) {
+		DP_DEBUG("mode %sx%d is invalid, not enough dsc %d %d\n",
+				mode->name, fps, num_dsc, avail_res->num_dsc);
+		return -EPERM;
+	} else if (!num_dsc && (num_lm == dual && !num_3dmux)) {
+		DP_DEBUG("mode %sx%d is invalid, not enough 3dmux %d %d\n",
+				mode->name, fps, num_3dmux, avail_res->num_3dmux);
+		return -EPERM;
+	} else if (num_lm == quad && num_dsc != quad)  {
+		DP_DEBUG("mode %sx%d is invalid, unsupported DP topology lm:%d dsc:%d\n",
+				mode->name, fps, num_lm, num_dsc);
 		return -EPERM;
 	}
 
+	DP_DEBUG("mode %sx%d is valid, supported DP topology lm:%d dsc:%d 3dmux:%d\n",
+				mode->name, fps, num_lm, num_dsc, num_3dmux);
+
 	return 0;
 }
 
@@ -2869,15 +2839,6 @@ static enum drm_mode_status dp_display_validate_mode(
 	if (rc)
 		goto end;
 
-	rc = dp_display_validate_mixers(dp->priv, mode, avail_res);
-	if (rc)
-		goto end;
-
-	rc = dp_display_validate_dscs(dp->priv, panel, mode, &dp_mode,
-			avail_res);
-	if (rc)
-		goto end;
-
 	rc = dp_display_validate_topology(dp, dp_panel, mode,
 			&dp_mode, avail_res);
 	if (rc)