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

disp: msm: sde: fix rm/kms for handling all cont-splash cases

Fix resource and splash buffer handling in resource manager
and sde_kms to support continuous splash to be enabled/disabled
independently in multiple built-in display usecase.

Change-Id: I446ea9b08a794e2b053c37f55b31e51404bbcf71
Signed-off-by: Veera Sundaram Sankaran <[email protected]>
Veera Sundaram Sankaran 6 жил өмнө
parent
commit
8b8fbfbeef

+ 0 - 3
msm/sde/sde_encoder.c

@@ -3294,7 +3294,6 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
 	for (i = 0; i < sde_enc->num_phys_encs; i++) {
 		if (sde_enc->phys_encs[i]) {
 			sde_enc->phys_encs[i]->cont_splash_enabled = false;
-			sde_enc->phys_encs[i]->cont_splash_single_flush = 0;
 			sde_enc->phys_encs[i]->connector = NULL;
 		}
 	}
@@ -5854,8 +5853,6 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder,
 		/* update connector for master and slave phys encoders */
 		phys->connector = conn;
 		phys->cont_splash_enabled = true;
-		phys->cont_splash_single_flush =
-			splash_display->single_flush_en;
 
 		phys->hw_pp = sde_enc->hw_pp[i];
 		if (phys->ops.cont_splash_mode_set)

+ 0 - 2
msm/sde/sde_encoder_phys.h

@@ -281,7 +281,6 @@ struct sde_encoder_irq {
  * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
  * @irq:			IRQ tracking structures
  * @has_intf_te:		Interface TE configuration support
- * @cont_splash_single_flush	Variable to check if single flush is enabled.
  * @cont_splash_enabled:	Variable to store continuous splash settings.
  * @in_clone_mode		Indicates if encoder is in clone mode ref@CWB
  * @vfp_cached:			cached vertical front porch to be used for
@@ -324,7 +323,6 @@ struct sde_encoder_phys {
 	wait_queue_head_t pending_kickoff_wq;
 	struct sde_encoder_irq irq[INTR_IDX_MAX];
 	bool has_intf_te;
-	u32 cont_splash_single_flush;
 	bool cont_splash_enabled;
 	bool in_clone_mode;
 	int vfp_cached;

+ 0 - 2
msm/sde/sde_hw_mdss.h

@@ -591,7 +591,6 @@ struct sde_sspp_index_info {
  * struct sde_splash_data - Struct contains details of resources and hw blocks
  * used in continuous splash on a specific display.
  * @cont_splash_enabled:  Stores the cont_splash status (enabled/disabled)
- * @single_flush_en: Stores if the single flush is enabled
  * @encoder:	Pointer to the drm encoder object used for this display
  * @splash:     Pointer to struct sde_splash_mem used for this display
  * @ctl_ids:	Stores the valid MDSS ctl block ids for the current mode
@@ -605,7 +604,6 @@ struct sde_sspp_index_info {
  */
 struct sde_splash_display {
 	bool cont_splash_enabled;
-	bool single_flush_en;
 	struct drm_encoder *encoder;
 	struct sde_splash_mem *splash;
 	u8 ctl_ids[MAX_DATA_PATH_PER_DSIPLAY];

+ 39 - 32
msm/sde/sde_kms.c

@@ -735,21 +735,15 @@ static int _sde_kms_splash_mem_put(struct sde_kms *sde_kms,
 	struct msm_mmu *mmu = NULL;
 	int rc = 0;
 
-	if (!sde_kms)
-		return -EINVAL;
-
-	if (!sde_kms->aspace[0]) {
-		SDE_ERROR("aspace not found for sde kms node\n");
+	if (!sde_kms || !sde_kms->aspace[0] || !sde_kms->aspace[0]->mmu) {
+		SDE_ERROR("invalid params\n");
 		return -EINVAL;
 	}
 
 	mmu = sde_kms->aspace[0]->mmu;
-	if (!mmu) {
-		SDE_ERROR("mmu not found for aspace\n");
-		return -EINVAL;
-	}
 
-	if (!splash || !mmu->funcs || !mmu->funcs->one_to_one_unmap)
+	if (!splash || !splash->ref_cnt ||
+			!mmu || !mmu->funcs || !mmu->funcs->one_to_one_unmap)
 		return -EINVAL;
 
 	splash->ref_cnt--;
@@ -869,6 +863,20 @@ static void sde_kms_commit(struct msm_kms *kms,
 	SDE_ATRACE_END("sde_kms_commit");
 }
 
+static void _sde_kms_free_splash_region(struct sde_kms *sde_kms,
+		struct sde_splash_display *splash_display)
+{
+	if (!sde_kms || !splash_display ||
+			!sde_kms->splash_data.num_splash_displays)
+		return;
+
+	_sde_kms_splash_mem_put(sde_kms, splash_display->splash);
+	sde_kms->splash_data.num_splash_displays--;
+	SDE_DEBUG("cont_splash handoff done, remaining:%d\n",
+				sde_kms->splash_data.num_splash_displays);
+	memset(splash_display, 0x0, sizeof(struct sde_splash_display));
+}
+
 static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms,
 		struct drm_crtc *crtc)
 {
@@ -897,16 +905,10 @@ static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms,
 	if (i >= MAX_DSI_DISPLAYS)
 		return;
 
-	_sde_kms_splash_mem_put(sde_kms, splash_display->splash);
-
 	if (splash_display->cont_splash_enabled) {
 		sde_encoder_update_caps_for_cont_splash(splash_display->encoder,
 				splash_display, false);
-		splash_display->cont_splash_enabled = false;
-		sde_kms->splash_data.num_splash_displays--;
-		SDE_DEBUG("cont_splash handoff done for dpy:%d remaining:%d\n",
-				i, sde_kms->splash_data.num_splash_displays);
-		memset(splash_display, 0x0, sizeof(struct sde_splash_display));
+		_sde_kms_free_splash_region(sde_kms, splash_display);
 	}
 
 	/* remove the votes if all displays are done with splash */
@@ -2314,13 +2316,9 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms)
 		return rc;
 	}
 
-	if (sde_kms->dsi_display_count !=
-			sde_kms->splash_data.num_splash_displays) {
-		SDE_ERROR("mismatch - displays:%d vs splash-displays:%d\n",
-				sde_kms->dsi_display_count,
-				sde_kms->splash_data.num_splash_displays);
-		return rc;
-	}
+	DRM_INFO("cont_splash enabled in %d of %d display(s)\n",
+				sde_kms->splash_data.num_splash_displays,
+				sde_kms->dsi_display_count);
 
 	/* dsi */
 	for (i = 0; i < sde_kms->dsi_display_count; ++i) {
@@ -3205,14 +3203,23 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms,
 	 * splash memory is found & release resources on any error
 	 * in finding display hw config in splash
 	 */
-	if (sde_kms->splash_data.num_splash_regions &&
-			sde_rm_cont_splash_res_init(priv, &sde_kms->rm,
-					&sde_kms->splash_data,
-					sde_kms->catalog)) {
-		SDE_DEBUG("freeing continuous splash resources\n");
-		_sde_kms_unmap_all_splash_regions(sde_kms);
-		memset(&sde_kms->splash_data, 0x0,
-				sizeof(struct sde_splash_data));
+	if (sde_kms->splash_data.num_splash_regions) {
+		struct sde_splash_display *display;
+		int ret, display_count =
+			sde_kms->splash_data.num_splash_displays;
+
+		ret = sde_rm_cont_splash_res_init(priv, &sde_kms->rm,
+				&sde_kms->splash_data, sde_kms->catalog);
+
+		for (i = 0; i < display_count; i++) {
+			display = &sde_kms->splash_data.splash_display[i];
+			/*
+			 * free splash region on resource init failure and
+			 * cont-splash disabled case
+			 */
+			if (!display->cont_splash_enabled || ret)
+				_sde_kms_free_splash_region(sde_kms, display);
+		}
 	}
 
 	sde_kms->hw_mdp = sde_rm_get_mdp(&sde_kms->rm);

+ 3 - 20
msm/sde/sde_rm.c

@@ -1467,7 +1467,8 @@ int sde_rm_cont_splash_res_init(struct msm_drm_private *priv,
 	hw_mdp = sde_rm_get_mdp(rm);
 
 	sde_rm_init_hw_iter(&iter_c, 0, SDE_HW_BLK_CTL);
-	while (_sde_rm_get_hw_locked(rm, &iter_c)) {
+	while (_sde_rm_get_hw_locked(rm, &iter_c)
+			&& (index < splash_data->num_splash_displays)) {
 		struct sde_hw_ctl *ctl = to_sde_hw_ctl(iter_c.blk->hw);
 
 		if (!ctl->ops.get_ctl_intf) {
@@ -1486,26 +1487,8 @@ int sde_rm_cont_splash_res_init(struct msm_drm_private *priv,
 			splash_display->cont_splash_enabled = true;
 			splash_display->ctl_ids[splash_display->ctl_cnt++] =
 				iter_c.blk->id;
-
-			if (hw_mdp && hw_mdp->ops.get_split_flush_status) {
-				splash_display->single_flush_en =
-					hw_mdp->ops.get_split_flush_status(
-							hw_mdp);
-			}
-
-			if (!splash_display->single_flush_en ||
-					(iter_c.blk->id != CTL_0))
-				index++;
-
-			if (index >= ARRAY_SIZE(splash_data->splash_display))
-				break;
 		}
-	}
-
-	if (index != splash_data->num_splash_displays) {
-		SDE_DEBUG("mismatch active displays vs actually enabled :%d/%d",
-				splash_data->num_splash_displays, index);
-		return -EINVAL;
+		index++;
 	}
 
 	return 0;