Browse Source

Merge "disp: msm: dp: Implement dsc slice selection logic based on sink caps"

qctecmdr 6 years ago
parent
commit
fc92a6d9f6
1 changed files with 63 additions and 3 deletions
  1. 63 3
      msm/dp/dp_panel.c

+ 63 - 3
msm/dp/dp_panel.c

@@ -1527,7 +1527,12 @@ struct dp_dsc_peak_throughput {
 	u32 peak_throughput;
 };
 
-struct dp_dsc_slices_per_line slice_per_line_tbl[] = {
+struct dp_dsc_slice_caps_bit_map {
+	u32 num_slices;
+	u32 bit_index;
+};
+
+const struct dp_dsc_slices_per_line slice_per_line_tbl[] = {
 	{0,     340,    1   },
 	{340,   680,    2   },
 	{680,   1360,   4   },
@@ -1556,13 +1561,54 @@ const struct dp_dsc_peak_throughput peak_throughput_mode_0_tbl[] = {
 	{14, 1000},
 };
 
+const struct dp_dsc_slice_caps_bit_map slice_caps_bit_map_tbl[] = {
+	{1, 0},
+	{2, 1},
+	{4, 3},
+	{6, 4},
+	{8, 5},
+	{10, 6},
+	{12, 7},
+	{16, 0},
+	{20, 1},
+	{24, 2},
+};
+
+static bool dp_panel_check_slice_support(u32 num_slices, u32 raw_data_1,
+		u32 raw_data_2)
+{
+	const struct dp_dsc_slice_caps_bit_map *bcap;
+	u32 raw_data;
+	int i;
+
+	if (num_slices <= 12)
+		raw_data = raw_data_1;
+	else
+		raw_data = raw_data_2;
+
+	for (i = 0; i < ARRAY_SIZE(slice_caps_bit_map_tbl); i++) {
+		bcap = &slice_caps_bit_map_tbl[i];
+
+		if (bcap->num_slices == num_slices) {
+			raw_data &= (1 << bcap->bit_index);
+
+			if (raw_data)
+				return true;
+			else
+				return false;
+		}
+	}
+
+	return false;
+}
+
 static int dp_panel_dsc_prepare_basic_params(
 		struct msm_compression_info *comp_info,
 		const struct dp_display_mode *dp_mode,
 		struct dp_panel *dp_panel)
 {
 	int i;
-	struct dp_dsc_slices_per_line *rec;
+	const struct dp_dsc_slices_per_line *rec;
 	const struct dp_dsc_peak_throughput *tput;
 	u32 slice_width;
 	u32 ppr = dp_mode->timing.pixel_clk_khz/1000;
@@ -1570,6 +1616,8 @@ static int dp_panel_dsc_prepare_basic_params(
 	u32 ppr_max_index;
 	u32 peak_throughput;
 	u32 ppr_per_slice;
+	u32 slice_caps_1;
+	u32 slice_caps_2;
 
 	comp_info->dsc_info.slice_per_pkt = 0;
 	for (i = 0; i < ARRAY_SIZE(slice_per_line_tbl); i++) {
@@ -1599,8 +1647,20 @@ static int dp_panel_dsc_prepare_basic_params(
 
 	ppr_per_slice = ppr/comp_info->dsc_info.slice_per_pkt;
 
+	slice_caps_1 = dp_panel->dsc_dpcd[4];
+	slice_caps_2 = dp_panel->dsc_dpcd[13] & 0x7;
+
+	/*
+	 * There are 3 conditions to check for sink support:
+	 * 1. The slice width cannot exceed the maximum.
+	 * 2. The ppr per slice cannot exceed the maximum.
+	 * 3. The number of slices must be explicitly supported.
+	 */
 	while (slice_width >= max_slice_width ||
-			ppr_per_slice > peak_throughput) {
+			ppr_per_slice > peak_throughput ||
+			!dp_panel_check_slice_support(
+			comp_info->dsc_info.slice_per_pkt, slice_caps_1,
+			slice_caps_2)) {
 		if (i == ARRAY_SIZE(slice_per_line_tbl))
 			return -EINVAL;