소스 검색

disp: msm: sde: fix 3dmux bookkeeping during resource info check

Currently, num of 3dmux used is incremented or decremented based
on LM allotment. This was leading to wrong bookkeeping in few
corner cases. This change maintains a 3d mux mask to track the
usage and update the count accordingly.

Change-Id: Idf25eff827462f3f0263d01a1aa733a1cbaf0a83
Signed-off-by: Sandeep Gangadharaiah <[email protected]>
Sandeep Gangadharaiah 2 년 전
부모
커밋
52a0b8ab86
4개의 변경된 파일28개의 추가작업 그리고 19개의 파일을 삭제
  1. 2 0
      msm/msm_drv.h
  2. 10 3
      msm/sde/sde_hw_catalog.c
  3. 2 0
      msm/sde/sde_hw_catalog.h
  4. 14 16
      msm/sde/sde_rm.c

+ 2 - 0
msm/msm_drv.h

@@ -849,6 +849,7 @@ struct msm_mode_info {
  * @num_ctl             number of ctl available
  * @num_3dmux           number of 3d mux available
  * @max_mixer_width:    max width supported by layer mixer
+ * @merge_3d_mask:      bitmap of available 3d mux resource
  */
 struct msm_resource_caps_info {
 	uint32_t num_lm_in_use;
@@ -858,6 +859,7 @@ struct msm_resource_caps_info {
 	uint32_t num_ctl;
 	uint32_t num_3dmux;
 	uint32_t max_mixer_width;
+	unsigned long merge_3d_mask;
 };
 
 /**

+ 10 - 3
msm/sde/sde_hw_catalog.c

@@ -2232,7 +2232,7 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c
 	struct sde_lm_cfg *mixer;
 	struct sde_lm_sub_blks *sblk;
 	int pp_count, dspp_count, ds_count, mixer_count;
-	u32 pp_idx, dspp_idx, ds_idx;
+	u32 pp_idx, dspp_idx, ds_idx, merge_3d_idx;
 	u32 mixer_base;
 	struct device_node *snp = NULL;
 	struct sde_dt_props *props, *blend_props, *blocks_props = NULL;
@@ -2273,8 +2273,8 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c
 		goto put_blocks;
 	}
 
-	for (i = 0, mixer_count = 0, pp_idx = 0, dspp_idx = 0,
-			ds_idx = 0; i < off_count; i++) {
+	for (i = 0, mixer_count = 0, pp_idx = 0, dspp_idx = 0, ds_idx = 0,
+			merge_3d_idx = 0; i < off_count; i++) {
 		const char *disp_pref = NULL;
 		const char *cwb_pref = NULL;
 		const char *dcwb_pref = NULL;
@@ -2348,6 +2348,7 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c
 		mixer->dspp = dspp_count > 0 ? dspp_idx + DSPP_0
 							: DSPP_MAX;
 		mixer->ds = ds_count > 0 ? ds_idx + DS_0 : DS_MAX;
+		mixer->merge_3d = merge_3d_idx + MERGE_3D_0;
 		pp_count--;
 		dspp_count--;
 		ds_count--;
@@ -2356,6 +2357,12 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c
 		ds_idx++;
 
 		mixer_count++;
+		/*
+		 * Since each 3dmux is assigned to a pair of LM,
+		 * increment this idx only at even LM counts
+		 */
+		if ((mixer_count & 1) == 0)
+			merge_3d_idx++;
 
 		sblk->gc.id = SDE_MIXER_GC;
 		if (blocks_props && blocks_props->exists[MIXER_GC_PROP]) {

+ 2 - 0
msm/sde/sde_hw_catalog.h

@@ -1348,6 +1348,7 @@ struct sde_sspp_cfg {
  * @dspp:              ID of connected DSPP, DSPP_MAX if unsupported
  * @pingpong:          ID of connected PingPong, PINGPONG_MAX if unsupported
  * @ds:                ID of connected DS, DS_MAX if unsupported
+ * @merge_3d:          ID of connected 3d MUX
  * @dummy_mixer:       identifies dcwb mixer is considered dummy
  * @lm_pair_mask:      Bitmask of LMs that can be controlled by same CTL
  */
@@ -1357,6 +1358,7 @@ struct sde_lm_cfg {
 	u32 dspp;
 	u32 pingpong;
 	u32 ds;
+	u32 merge_3d;
 	bool dummy_mixer;
 	unsigned long lm_pair_mask;
 };

+ 14 - 16
msm/sde/sde_rm.c

@@ -213,23 +213,23 @@ static void _sde_rm_inc_resource_info_lm(struct sde_rm *rm,
 	list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) {
 		lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap;
 		/*
-		 * If lm2 is free, or
-		 * lm1 & lm2 reserved by same enc, check mask
+		 * If the paired lm is free, or is reserved by the same encoder
+		 * set the bit for the 3d mux associated with the lm
+		 * counting these set bits will give an accurate count of available 3dmux
 		 */
-		if ((!blk2->rsvp || (blk->rsvp &&
-				blk2->rsvp->enc_id == blk->rsvp->enc_id
-				&& lm_cfg->id > lm_cfg2->id)) &&
+		if ((!blk2->rsvp || (blk->rsvp && blk2->rsvp->enc_id == blk->rsvp->enc_id)) &&
 				test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask))
-			avail_res->num_3dmux++;
+			set_bit(lm_cfg->merge_3d, &avail_res->merge_3d_mask);
 	}
+
+	avail_res->num_3dmux = hweight_long(avail_res->merge_3d_mask);
 }
 
 static void _sde_rm_dec_resource_info_lm(struct sde_rm *rm,
 	struct msm_resource_caps_info *avail_res,
 	struct sde_rm_hw_blk *blk)
 {
-	struct sde_rm_hw_blk *blk2;
-	const struct sde_lm_cfg *lm_cfg, *lm_cfg2;
+	const struct sde_lm_cfg *lm_cfg;
 
 	lm_cfg = to_sde_hw_mixer(blk->hw)->cap;
 
@@ -239,14 +239,12 @@ static void _sde_rm_dec_resource_info_lm(struct sde_rm *rm,
 
 	avail_res->num_lm--;
 
-	/* Check for 3d muxes by comparing paired lms */
-	list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) {
-		lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap;
-		/* If lm2 is free and lm1 is now being reserved */
-		if (!blk2->rsvp &&
-				test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask))
-			avail_res->num_3dmux--;
-	}
+	/*
+	 * Clear the bit for the 3d mux associated with the lm
+	 * counting these set bits will give an accurate count of available 3dmux
+	 */
+	clear_bit(lm_cfg->merge_3d, &avail_res->merge_3d_mask);
+	avail_res->num_3dmux = hweight_long(avail_res->merge_3d_mask);
 }
 
 static void _sde_rm_inc_resource_info(struct sde_rm *rm,