ソースを参照

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 年 前
コミット
fd42eaf7ce
1 ファイル変更23 行追加12 行削除
  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;
 		}
 
-		/* 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;
+		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) {
 		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);
@@ -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);
 
-	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)
 		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)
 		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)
 		goto end;