Browse Source

disp: msm: dp: use 3dmux when dsc is not available

The mode validation logic in DP checks for 3dmux only if DSC is
not supported by the sink. It does not cover the case where the
sink supports DSC but there are not enough DSC blocks available.
In this case, it filters out all the modes even though some of
the modes can be realized with 3dmux or without 3dmux or DSC.

This change updates the logic to check for DSC first and if
that fails, disable DSC for the panel and look for other modes
that can be supported with or without 3dmux alone.

Change-Id: Ie0497333c77d8de30d126e701b5458f354897b8c
Signed-off-by: Rajkumar Subbiah <[email protected]>
Rajkumar Subbiah 4 years ago
parent
commit
fd42eaf7ce
1 changed files with 23 additions and 12 deletions
  1. 23 12
      msm/dp/dp_display.c

+ 23 - 12
msm/dp/dp_display.c

@@ -2778,21 +2778,28 @@ static int dp_display_validate_topology(struct dp_display_private *dp,
 			return rc;
 			return rc;
 		}
 		}
 
 
-		/* Only DSCMERGE is supported on DP */
-		num_lm  = max(num_lm, num_dsc);
 		num_dsc = max(num_lm, num_dsc);
 		num_dsc = max(num_lm, num_dsc);
-	} else {
-		num_3dmux = avail_res->num_3dmux;
+		if ((num_dsc > avail_res->num_lm) ||  (num_dsc > avail_res->num_dsc)) {
+			DP_DEBUG("mode %sx%d: not enough resources for dsc %d dsc_a:%d lm_a:%d\n",
+					mode->name, fps, num_dsc, avail_res->num_dsc,
+					avail_res->num_lm);
+			/* Clear DSC caps and retry */
+			dp_mode->capabilities &= ~DP_PANEL_CAPS_DSC;
+			return -EAGAIN;
+		} else {
+			/* Only DSCMERGE is supported on DP */
+			num_lm = num_dsc;
+		}
+	}
+
+	if (!num_dsc && (num_lm == 2) && avail_res->num_3dmux) {
+		num_3dmux = 1;
 	}
 	}
 
 
 	if (num_lm > avail_res->num_lm) {
 	if (num_lm > avail_res->num_lm) {
 		DP_DEBUG("mode %sx%d is invalid, not enough lm %d %d\n",
 		DP_DEBUG("mode %sx%d is invalid, not enough lm %d %d\n",
 				mode->name, fps, num_lm, num_lm, avail_res->num_lm);
 				mode->name, fps, num_lm, num_lm, avail_res->num_lm);
 		return -EPERM;
 		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)) {
 	} else if (!num_dsc && (num_lm == dual && !num_3dmux)) {
 		DP_DEBUG("mode %sx%d is invalid, not enough 3dmux %d %d\n",
 		DP_DEBUG("mode %sx%d is invalid, not enough 3dmux %d %d\n",
 				mode->name, fps, num_3dmux, avail_res->num_3dmux);
 				mode->name, fps, num_3dmux, avail_res->num_3dmux);
@@ -2843,16 +2850,20 @@ static enum drm_mode_status dp_display_validate_mode(
 
 
 	dp_display->convert_to_dp_mode(dp_display, panel, mode, &dp_mode);
 	dp_display->convert_to_dp_mode(dp_display, panel, mode, &dp_mode);
 
 
-	rc = dp_display_validate_link_clock(dp, mode, dp_mode);
+	rc = dp_display_validate_topology(dp, dp_panel, mode, &dp_mode, avail_res);
+	if (rc == -EAGAIN) {
+		dp_panel->convert_to_dp_mode(dp_panel, mode, &dp_mode);
+		rc = dp_display_validate_topology(dp, dp_panel, mode, &dp_mode, avail_res);
+	}
+
 	if (rc)
 	if (rc)
 		goto end;
 		goto end;
 
 
-	rc = dp_display_validate_pixel_clock(dp_mode, dp_display->max_pclk_khz);
+	rc = dp_display_validate_link_clock(dp, mode, dp_mode);
 	if (rc)
 	if (rc)
 		goto end;
 		goto end;
 
 
-	rc = dp_display_validate_topology(dp, dp_panel, mode,
-			&dp_mode, avail_res);
+	rc = dp_display_validate_pixel_clock(dp_mode, dp_display->max_pclk_khz);
 	if (rc)
 	if (rc)
 		goto end;
 		goto end;