Эх сурвалжийг харах

disp: msm: sde: fix cont splash pipe identification

This change fixes the continuos splash logic that identifies the
pipes staged by bootloader. The same code flow is used in trusted ui
handover as well. Existing logic was counting the pipes twice if the pipe
is staged on both the layer mixers. This change simplifies the pipes
already staged before handover by using the pipe index to convey if
it is staged or not.

Change-Id: Idb255f2077161dc3553114ac5d04e0ef743bb5ea
Signed-off-by: Abhijit Kulkarni <[email protected]>
Abhijit Kulkarni 4 жил өмнө
parent
commit
944a0629f5

+ 10 - 8
msm/sde/sde_hw_ctl.c

@@ -919,7 +919,7 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
 }
 
 static u32 sde_hw_ctl_get_staged_sspp(struct sde_hw_ctl *ctx, enum sde_lm lm,
-		struct sde_sspp_index_info *info, u32 info_max_cnt)
+		struct sde_sspp_index_info *info)
 {
 	int i, j;
 	u32 count = 0;
@@ -929,8 +929,8 @@ static u32 sde_hw_ctl_get_staged_sspp(struct sde_hw_ctl *ctx, enum sde_lm lm,
 	struct sde_hw_blk_reg_map *c;
 	const struct ctl_sspp_stage_reg_map *sspp_cfg;
 
-	if (!ctx || (lm >= LM_MAX) || !info)
-		return count;
+	if (!ctx || (lm >= LM_DCWB_DUMMY_0) || !info)
+		return 0;
 
 	c = &ctx->hw;
 	mixercfg[0] = SDE_REG_READ(c, CTL_LAYER(lm));
@@ -938,10 +938,11 @@ static u32 sde_hw_ctl_get_staged_sspp(struct sde_hw_ctl *ctx, enum sde_lm lm,
 	mixercfg[2] = SDE_REG_READ(c, CTL_LAYER_EXT2(lm));
 	mixercfg[3] = SDE_REG_READ(c, CTL_LAYER_EXT3(lm));
 
+	if (mixercfg[0] & CTL_MIXER_BORDER_OUT)
+		info->bordercolor = true;
+
 	for (i = SSPP_VIG0; i < SSPP_MAX; i++) {
 		for (j = 0; j < CTL_SSPP_MAX_RECTS; j++) {
-			if (count >= info_max_cnt)
-				goto end;
 
 			sspp_cfg = &sspp_reg_cfg_tbl[i][j];
 			if (!sspp_cfg->bits || sspp_cfg->ext >= CTL_NUM_EXT)
@@ -953,14 +954,15 @@ static u32 sde_hw_ctl_get_staged_sspp(struct sde_hw_ctl *ctx, enum sde_lm lm,
 				staged = mixercfg[1] & sspp_cfg->sec_bit_mask;
 
 			if (staged) {
-				info[count].sspp = i;
-				info[count].is_virtual = j;
+				if (j)
+					set_bit(i, info->virt_pipes);
+				else
+					set_bit(i, info->pipes);
 				count++;
 			}
 		}
 	}
 
-end:
 	return count;
 }
 

+ 3 - 4
msm/sde/sde_hw_ctl.h

@@ -428,12 +428,11 @@ struct sde_hw_ctl_ops {
 	 * Get all the sspp staged on a layer mixer
 	 * @ctx       : ctl path ctx pointer
 	 * @lm        : layer mixer enumeration
-	 * @info      : array address to populate connected sspp index info
-	 * @info_max_cnt : maximum sspp info elements based on array size
-	 * @Return: count of sspps info  elements populated
+	 * @info      : structure to populate connected sspp index info
+	 * @Return: count of sspps info elements populated
 	 */
 	u32 (*get_staged_sspp)(struct sde_hw_ctl *ctx, enum sde_lm lm,
-		struct sde_sspp_index_info *info, u32 info_max_cnt);
+		struct sde_sspp_index_info *info);
 
 	/**
 	 * Flush the reg dma by sending last command.

+ 11 - 8
msm/sde/sde_hw_mdss.h

@@ -639,13 +639,18 @@ struct sde_splash_mem {
 };
 
 /**
- * struct sde_sspp_index_info - Struct containing sspp identifier info
- * @sspp:	Enum value indicates sspp id
- * @is_virtual: Boolean to identify if virtual or base
+ * struct sde_sspp_index_info - Struct informing which pipes are staged on
+ * particular display
+ * @pipes:      bitmap, bit index is true if rect_0 of that pipe is staged,
+ *              else is false
+ * @virt_pipes: bitmap, bit index is true if rect_1 of that pipe is staged,
+ *              else set to false
+ * @bordercolor: True if border color is enabled
  */
 struct sde_sspp_index_info {
-	enum sde_sspp sspp;
-	bool is_virtual;
+	DECLARE_BITMAP(pipes, SSPP_MAX);
+	DECLARE_BITMAP(virt_pipes, SSPP_MAX);
+	bool bordercolor;
 };
 
 /**
@@ -664,7 +669,6 @@ struct sde_sspp_index_info {
  * @lm_cnt:	Stores the active number of MDSS "LM" blks for the current mode
  * @dsc_cnt:	Stores the active number of MDSS "dsc" blks for the current mode
  * @vdc_cnt:	Stores the valid MDSS VDC block ids for the current mode
- * @pipe_cnt:	Stores the active number of "sspp" blks connected
  */
 struct sde_splash_display {
 	bool cont_splash_enabled;
@@ -675,12 +679,11 @@ struct sde_splash_display {
 	u8 lm_ids[MAX_DATA_PATH_PER_DSIPLAY];
 	u8 dsc_ids[MAX_DATA_PATH_PER_DSIPLAY];
 	u8 vdc_ids[MAX_DATA_PATH_PER_DSIPLAY];
-	struct sde_sspp_index_info pipes[SSPP_MAX];
+	struct sde_sspp_index_info pipe_info;
 	u8 ctl_cnt;
 	u8 lm_cnt;
 	u8 dsc_cnt;
 	u8 vdc_cnt;
-	u8 pipe_cnt;
 };
 
 enum sde_handoff_type {

+ 13 - 12
msm/sde/sde_kms.c

@@ -2954,9 +2954,10 @@ static int _sde_kms_update_planes_for_cont_splash(struct sde_kms *sde_kms,
 	struct sde_splash_mem *splash;
 	struct sde_splash_mem *demura;
 	struct sde_plane_state *pstate;
-	enum sde_sspp plane_id;
+	struct sde_sspp_index_info *pipe_info;
+	enum sde_sspp pipe_id;
 	bool is_virtual;
-	int i, j;
+	int i;
 
 	if (!sde_kms || !splash_display || !crtc) {
 		SDE_ERROR("invalid input args\n");
@@ -2964,18 +2965,17 @@ static int _sde_kms_update_planes_for_cont_splash(struct sde_kms *sde_kms,
 	}
 
 	priv = sde_kms->dev->dev_private;
+	pipe_info = &splash_display->pipe_info;
+	splash = splash_display->splash;
+	demura = splash_display->demura;
+
 	for (i = 0; i < priv->num_planes; i++) {
 		plane = priv->planes[i];
-		plane_id = sde_plane_pipe(plane);
+		pipe_id = sde_plane_pipe(plane);
 		is_virtual = is_sde_plane_virtual(plane);
-		splash = splash_display->splash;
-		demura = splash_display->demura;
 
-		for (j = 0; j < splash_display->pipe_cnt; j++) {
-			if ((plane_id != splash_display->pipes[j].sspp) ||
-					(splash_display->pipes[j].is_virtual
-					 != is_virtual))
-				continue;
+		if ((is_virtual && test_bit(pipe_id, pipe_info->virt_pipes)) ||
+				(!is_virtual && test_bit(pipe_id, pipe_info->pipes))) {
 
 			if (splash && sde_plane_validate_src_addr(plane,
 						splash->splash_buf_base,
@@ -2984,7 +2984,8 @@ static int _sde_kms_update_planes_for_cont_splash(struct sde_kms *sde_kms,
 						plane, demura->splash_buf_base,
 						demura->splash_buf_size)) {
 					SDE_ERROR("invalid adr on pipe:%d crtc:%d\n",
-							plane_id, DRMID(crtc));
+							pipe_id, DRMID(crtc));
+					continue;
 				}
 			}
 
@@ -2993,7 +2994,7 @@ static int _sde_kms_update_planes_for_cont_splash(struct sde_kms *sde_kms,
 			pstate = to_sde_plane_state(plane->state);
 			pstate->cont_splash_populated = true;
 			SDE_DEBUG("set crtc:%d for plane:%d rect:%d\n",
-					DRMID(crtc), plane_id, is_virtual);
+					DRMID(crtc), DRMID(plane), is_virtual);
 		}
 	}
 

+ 11 - 14
msm/sde/sde_plane.c

@@ -2537,7 +2537,7 @@ static int _sde_plane_validate_shared_crtc(struct sde_plane *psde,
 {
 	struct sde_kms *sde_kms;
 	struct sde_splash_display *splash_display;
-	int i, j;
+	int i;
 
 	sde_kms = _sde_plane_get_kms(&psde->base);
 
@@ -2548,19 +2548,16 @@ static int _sde_plane_validate_shared_crtc(struct sde_plane *psde,
 		splash_display = &sde_kms->splash_data.splash_display[i];
 
 		if (splash_display && splash_display->cont_splash_enabled &&
-			splash_display->encoder &&
-			state->crtc != splash_display->encoder->crtc) {
-
-			for (j = 0; j < MAX_DATA_PATH_PER_DSIPLAY; j++) {
-
-				if (splash_display->pipes[j].sspp ==
-						psde->pipe) {
-					SDE_ERROR_PLANE(psde,
-					"pipe:%d used in cont-splash on crtc:%d\n",
-					psde->pipe,
-					splash_display->encoder->crtc->base.id);
-					return -EINVAL;
-				}
+				splash_display->encoder &&
+				state->crtc != splash_display->encoder->crtc) {
+			struct sde_sspp_index_info *pipe_info = &splash_display->pipe_info;
+
+			if (test_bit(psde->pipe, pipe_info->pipes)  ||
+					test_bit(psde->pipe, pipe_info->virt_pipes)) {
+				SDE_ERROR_PLANE(psde, "pipe:%d used in cont-splash on crtc:%d\n",
+						psde->pipe,
+						splash_display->encoder->crtc->base.id);
+				return -EINVAL;
 			}
 		}
 	}

+ 27 - 68
msm/sde/sde_rm.c

@@ -1924,55 +1924,35 @@ static int _sde_rm_make_next_rsvp(struct sde_rm *rm, struct drm_encoder *enc,
 	return ret;
 }
 
-static int _sde_rm_update_pipe_cnt_from_active(
+static int _sde_rm_update_active_only_pipes(
 		struct sde_splash_display *splash_display,
 		u32 active_pipes_mask)
 {
+	struct sde_sspp_index_info *pipe_info;
 	int i;
-	u32 sspp_present = 0, space_remain = 0;
 
 	if (!active_pipes_mask) {
 		return 0;
 	} else if (!splash_display) {
 		SDE_ERROR("invalid splash display provided\n");
 		return -EINVAL;
-	} else if (splash_display->pipe_cnt >=
-			ARRAY_SIZE(splash_display->pipes)) {
-		SDE_ERROR("no room to add active pipes to pipe array\n");
-		return -EINVAL;
 	}
 
-	for (i = 0; i < splash_display->pipe_cnt; i++)
-		sspp_present |= BIT(splash_display->pipes[i].sspp);
-
-	space_remain = ARRAY_SIZE(splash_display->pipes)
-			- splash_display->pipe_cnt;
-
+	pipe_info = &splash_display->pipe_info;
 	for (i = SSPP_VIG0; i < SSPP_MAX; i++) {
-		/* Skip planes already present in the array */
-		if (!(active_pipes_mask & BIT(i)) ||
-				(sspp_present & BIT(i)))
+		if (!(active_pipes_mask & BIT(i)))
 			continue;
 
-		if (space_remain < R_MAX) {
-			SDE_ERROR("not enough room to add active pipe %d", i);
-			return -EINVAL;
-		}
+		if (test_bit(i, pipe_info->pipes) || test_bit(i, pipe_info->virt_pipes))
+			continue;
 
 		/*
-		 * A plane in active but not sspp_present indicates a non-pixel
+		 * A pipe is active but not staged indicates a non-pixel
 		 * plane. Register both rectangles as we can't differentiate
 		 */
-		splash_display->pipes[splash_display->pipe_cnt].sspp = i;
-		splash_display->pipes[splash_display->pipe_cnt].is_virtual =
-				false;
-		splash_display->pipe_cnt++;
-		space_remain--;
-		splash_display->pipes[splash_display->pipe_cnt].sspp = i;
-		splash_display->pipes[splash_display->pipe_cnt].is_virtual =
-				true;
-		splash_display->pipe_cnt++;
-		space_remain--;
+		set_bit(i, pipe_info->pipes);
+		set_bit(i, pipe_info->virt_pipes);
+		SDE_DEBUG("pipe %d is active:0x%x but not staged\n", i, active_pipes_mask);
 	}
 
 	return 0;
@@ -1990,10 +1970,10 @@ static int _sde_rm_get_hw_blk_for_cont_splash(struct sde_rm *rm,
 		struct sde_hw_ctl *ctl,
 		struct sde_splash_display *splash_display)
 {
-	u32 lm_reg, max_cnt, active_pipes_mask = 0;
+	u32 active_pipes_mask = 0;
 	struct sde_rm_hw_iter iter_lm, iter_dsc;
 	struct sde_kms *sde_kms;
-	size_t start_count;
+	size_t pipes_per_lm;
 
 	if (!rm || !ctl || !splash_display) {
 		SDE_ERROR("invalid input parameters\n");
@@ -2001,7 +1981,6 @@ static int _sde_rm_get_hw_blk_for_cont_splash(struct sde_rm *rm,
 	}
 
 	sde_kms = container_of(rm, struct sde_kms, rm);
-	max_cnt = ARRAY_SIZE(splash_display->pipes);
 
 	sde_rm_init_hw_iter(&iter_lm, 0, SDE_HW_BLK_LM);
 	sde_rm_init_hw_iter(&iter_dsc, 0, SDE_HW_BLK_DSC);
@@ -2009,48 +1988,28 @@ static int _sde_rm_get_hw_blk_for_cont_splash(struct sde_rm *rm,
 		if (splash_display->lm_cnt >= MAX_DATA_PATH_PER_DSIPLAY)
 			break;
 
-		lm_reg = ctl->ops.read_ctl_layers(ctl, iter_lm.blk->id);
-		if (!lm_reg)
-			continue;
-
-		splash_display->lm_ids[splash_display->lm_cnt++] =
-			iter_lm.blk->id;
-		SDE_DEBUG("lm_cnt=%d lm_reg[%d]=0x%x\n", splash_display->lm_cnt,
-				iter_lm.blk->id - LM_0, lm_reg);
-
-		start_count = splash_display->pipe_cnt;
 		if (ctl->ops.get_staged_sspp) {
-			struct sde_sspp_index_info *start =
-				&splash_display->pipes[
-					splash_display->pipe_cnt];
-
-			splash_display->pipe_cnt += ctl->ops.get_staged_sspp(
-					ctl, iter_lm.blk->id, start,
-					max_cnt - splash_display->pipe_cnt);
-		}
-
-		if (sde_kms->splash_data.type == SDE_VM_HANDOFF) {
-			/* Allow VM handoff without any pipes, as it is a
-			 * valid case to have NULL commit before the
-			 * transition.
-			 */
-			SDE_DEBUG("VM handoff with no pipes staged\n");
-		} else if (start_count == splash_display->pipe_cnt) {
-			SDE_ERROR("no pipes detected on LM-%d\n",
-					iter_lm.blk->id - LM_0);
-			return 0;
-		} else if (splash_display->pipe_cnt > max_cnt) {
-			SDE_ERROR("found %d pipes exceed max of %d\n",
-					splash_display->pipe_cnt, max_cnt);
-			return 0;
+			// reset bordercolor from previous LM
+			splash_display->pipe_info.bordercolor = false;
+			pipes_per_lm = ctl->ops.get_staged_sspp(
+					ctl, iter_lm.blk->id,
+					&splash_display->pipe_info);
+			if (pipes_per_lm ||
+					splash_display->pipe_info.bordercolor) {
+				splash_display->lm_ids[splash_display->lm_cnt++] =
+					iter_lm.blk->id;
+				SDE_DEBUG("lm_cnt=%d lm_id %d pipe_cnt%d\n",
+						splash_display->lm_cnt,
+						iter_lm.blk->id - LM_0,
+						pipes_per_lm);
+			}
 		}
 	}
 
 	if (ctl->ops.get_active_pipes)
 		active_pipes_mask = ctl->ops.get_active_pipes(ctl);
 
-	if (_sde_rm_update_pipe_cnt_from_active(splash_display,
-			active_pipes_mask))
+	if (_sde_rm_update_active_only_pipes(splash_display, active_pipes_mask))
 		return 0;
 
 	while (_sde_rm_get_hw_locked(rm, &iter_dsc)) {