Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b8fbfbe authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran
Browse files

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: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 5af1fe18
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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;
	}

	return 0;