Browse Source

disp: msm: sde: assign a non-pairable DSC to a topology that requires single DSC

During suspend-resume in a dual-display scenario with primary
display topology <2 2 1> and secondary display topology <1 1 1>
with 3 DSC instances, allocating DSC block 1 to the secondary
display results in DSC blocks 2 and 3 being assigned to the
primary display. However, as DSC block 2 is not a peer of DSC
block 3, it triggers an atomic check failure as a part of the RM
reservation failure. While reserving the DSC resources, prefer non
pairable DSC if the topology requests for single DSC instance. If
there are no non pairable DSCs available, then select one of the
available DSC.

Change-Id: I3e3f7ec343b5bc99aa23786a3cb65cf7bbbd7275
Signed-off-by: Akash Gajjar <[email protected]>
Akash Gajjar 1 year ago
parent
commit
4676e59d3d
1 changed files with 45 additions and 5 deletions
  1. 45 5
      msm/sde/sde_rm.c

+ 45 - 5
msm/sde/sde_rm.c

@@ -1525,7 +1525,9 @@ static bool _sde_rm_check_dsc(struct sde_rm *rm,
 		struct sde_rm_rsvp *rsvp,
 		struct sde_rm_hw_blk *dsc,
 		struct sde_rm_hw_blk *paired_dsc,
-		struct sde_rm_hw_blk *pp_blk)
+		struct sde_rm_hw_blk *pp_blk,
+		int num_dsc_enc,
+		uint32_t un_paired_dsc_id)
 {
 	const struct sde_dsc_cfg *dsc_cfg = to_sde_hw_dsc(dsc->hw)->caps;
 
@@ -1555,6 +1557,19 @@ static bool _sde_rm_check_dsc(struct sde_rm *rm,
 					paired_dsc_cfg->id);
 			return false;
 		}
+	} else {
+		/**
+		 * For topologies, where there is a single DSC requirement,
+		 * Try to allocate unpaired DSCs first such that, pairable
+		 * DSCs are available for other displays.
+		 */
+		if (num_dsc_enc == 1 && un_paired_dsc_id > 0 && un_paired_dsc_id != dsc->id &&
+				IS_COMPATIBLE_PP_DSC(pp_blk->id, un_paired_dsc_id)) {
+			SDE_DEBUG("number of dsc %d, dsc %d can't match of pp %d\n",
+					num_dsc_enc, un_paired_dsc_id,
+					pp_blk ? pp_blk->id : -1);
+			return false;
+		}
 	}
 
 	return true;
@@ -1600,6 +1615,30 @@ static void sde_rm_get_rsvp_nxt_hw_blks(
 	}
 }
 
+static uint32_t _sde_rm_reserve_un_paired_dsc(
+		struct sde_rm_rsvp *rsvp,
+		struct sde_rm_requirements *reqs,
+		struct sde_rm *rm)
+{
+	const struct sde_dsc_cfg *dsc_cfg;
+	struct sde_rm_hw_iter iter_i;
+
+	if (reqs->topology->num_comp_enc != 1)
+		return 0;
+
+	sde_rm_init_hw_iter(&iter_i, 0, SDE_HW_BLK_DSC);
+
+	while (_sde_rm_get_hw_locked(rm, &iter_i, true)) {
+		dsc_cfg = to_sde_hw_dsc(iter_i.blk->hw)->caps;
+		if (RESERVED_BY_OTHER(iter_i.blk, rsvp))
+			continue;
+		if (!dsc_cfg->dsc_pair_mask[0])
+			return iter_i.blk->id;
+	}
+
+	return 0;
+}
+
 static int _sde_rm_reserve_dsc(
 		struct sde_rm *rm,
 		struct sde_rm_rsvp *rsvp,
@@ -1608,7 +1647,7 @@ static int _sde_rm_reserve_dsc(
 {
 	struct sde_rm_hw_iter iter_i, iter_j;
 	struct sde_rm_hw_blk *dsc[MAX_BLOCKS];
-	u32 reserve_mask = 0;
+	u32 reserve_mask = 0, un_paired_dsc_id;
 	struct sde_rm_hw_blk *pp[MAX_BLOCKS];
 	int alloc_count = 0;
 	int num_dsc_enc;
@@ -1639,6 +1678,7 @@ static int _sde_rm_reserve_dsc(
 			list_forward = sde_encoder_is_dsi_display(encoder);
 	}
 
+	un_paired_dsc_id = _sde_rm_reserve_un_paired_dsc(rsvp, reqs, rm);
 	sde_rm_get_rsvp_nxt_hw_blks(rm, rsvp, SDE_HW_BLK_PINGPONG, pp, list_forward);
 
 	/* Find a first DSC */
@@ -1661,7 +1701,7 @@ static int _sde_rm_reserve_dsc(
 			continue;
 
 		if (!_sde_rm_check_dsc(rm, rsvp, iter_i.blk, NULL,
-					 pp[alloc_count]))
+					 pp[alloc_count], num_dsc_enc, un_paired_dsc_id))
 			continue;
 
 		SDE_DEBUG("blk id = %d, _dsc_ids[%d] = %d\n",
@@ -1694,8 +1734,8 @@ static int _sde_rm_reserve_dsc(
 					_dsc_ids[req_index]))
 				continue;
 
-			if (!_sde_rm_check_dsc(rm, rsvp, iter_j.blk,
-					 iter_i.blk, pp[alloc_count]))
+			if (!_sde_rm_check_dsc(rm, rsvp, iter_j.blk, iter_i.blk,
+					 pp[alloc_count], num_dsc_enc, 0))
 				continue;
 
 			SDE_DEBUG("blk id = %d, _dsc_ids[%d] = %d\n",