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

Commit c9d48a35 authored by Ujwal Patel's avatar Ujwal Patel Committed by Ian Maund
Browse files

msm: mdss: fix boot-up issues with splash thread enabled



Starting with commit f01f7cd13954e86172a5745f5838487b0d2400e5 (delay
iommu mapping of buffers until commit), if continuous splash and splash
thread both are enabled, iommu attach is skipped if handoff is pending.
But if iommu is not attached then iova is treated as physical address and
MDP hw fetches memory from incorrect buffer resulting in corruption on
screen. Fix this by attaching iommu based on its ref count and not by
handoff pending flag. Also if splash thread is disabled then do not allow
iommu attach if it is an empty commit.

Change-Id: I363b87256c8faa6a2ab51e25f3487bc04f91d0dc
Signed-off-by: default avatarUjwal Patel <ujwalp@codeaurora.org>
Signed-off-by: default avatarJayant Shekhar <jshekhar@codeaurora.org>
[imaund@codeaurora.org: Resolved trivial context conflicts]
Signed-off-by: default avatarIan Maund <imaund@codeaurora.org>
parent 1099778f
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -173,6 +173,9 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev);
static int mdss_mdp_parse_dt_ad_cfg(struct platform_device *pdev);
static int mdss_mdp_parse_dt_bus_scale(struct platform_device *pdev);
static int mdss_mdp_parse_dt_ppb_off(struct platform_device *pdev);
static int mdss_iommu_attach(struct mdss_data_type *mdata);
static int mdss_iommu_dettach(struct mdss_data_type *mdata);

/**
 * mdss_mdp_vbif_axi_halt() - Halt MDSS AXI ports
 * @mdata: pointer to the global mdss data structure.
@@ -669,11 +672,7 @@ int mdss_iommu_ctrl(int enable)
		__builtin_return_address(0), enable, mdata->iommu_ref_cnt);

	if (enable) {
		/*
		 * delay iommu attach until continous splash screen has
		 * finished handoff, as it may still be working with phys addr
		 */
		if (!mdata->iommu_attached && !mdata->handoff_pending)
		if (mdata->iommu_ref_cnt == 0)
			rc = mdss_iommu_attach(mdata);
		mdata->iommu_ref_cnt++;
	} else {
@@ -966,7 +965,7 @@ static int mdss_mdp_irq_clk_setup(struct mdss_data_type *mdata)
	return 0;
}

int mdss_iommu_attach(struct mdss_data_type *mdata)
static int mdss_iommu_attach(struct mdss_data_type *mdata)
{
	struct iommu_domain *domain;
	struct mdss_iommu_map_type *iomap;
@@ -1005,7 +1004,7 @@ end:
	return rc;
}

int mdss_iommu_dettach(struct mdss_data_type *mdata)
static int mdss_iommu_dettach(struct mdss_data_type *mdata)
{
	struct iommu_domain *domain;
	struct mdss_iommu_map_type *iomap;
@@ -1035,7 +1034,7 @@ int mdss_iommu_dettach(struct mdss_data_type *mdata)
	return 0;
}

int mdss_iommu_init(struct mdss_data_type *mdata)
static int mdss_iommu_init(struct mdss_data_type *mdata)
{
	struct msm_iova_layout layout;
	struct iommu_domain *domain;
+0 −2
Original line number Diff line number Diff line
@@ -818,8 +818,6 @@ static inline u32 left_lm_w_from_mfd(struct msm_fb_data_type *mfd)
}

irqreturn_t mdss_mdp_isr(int irq, void *ptr);
int mdss_iommu_attach(struct mdss_data_type *mdata);
int mdss_iommu_dettach(struct mdss_data_type *mdata);
void mdss_mdp_irq_clear(struct mdss_data_type *mdata,
		u32 intr_type, u32 intf_num);
int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num);
+14 −10
Original line number Diff line number Diff line
@@ -1297,10 +1297,12 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	struct mdss_mdp_ctl *ctl = mdp5_data->ctl;

	pr_debug("starting fb%d overlay called from %pS\n", mfd->index,
		__builtin_return_address(0));

	if (mdss_mdp_ctl_is_power_on(ctl)) {
		if (!mdp5_data->mdata->batfet)
			mdss_mdp_batfet_ctrl(mdp5_data->mdata, true);
		mdss_mdp_release_splash_pipe(mfd);
		return 0;
	} else if (mfd->panel_info->cont_splash_enabled) {
		mutex_lock(&mdp5_data->list_lock);
@@ -1671,19 +1673,18 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	ret = mdss_mdp_overlay_start(mfd);
	if (ret) {
		pr_err("unable to start overlay %d (%d)\n", mfd->index, ret);
		mutex_unlock(&mdp5_data->ov_lock);
		if (ctl->shared_lock)
			mutex_unlock(ctl->shared_lock);
		return ret;
		goto unlock_exit;
	}

	if (!mdss_mdp_ctl_is_power_on(ctl)) {
		pr_debug("ctl is not powerd on. skip kickoff\n");
		goto unlock_exit;
	}

	ret = mdss_iommu_ctrl(1);
	if (IS_ERR_VALUE(ret)) {
		pr_err("iommu attach failed rc=%d\n", ret);
		mutex_unlock(&mdp5_data->ov_lock);
		if (ctl->shared_lock)
			mutex_unlock(ctl->shared_lock);
		return ret;
		goto unlock_exit;
	}
	mutex_lock(&mdp5_data->list_lock);

@@ -1842,10 +1843,11 @@ commit_fail:
	if (!mdp5_data->kickoff_released)
		mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_CTX_DONE);

	mdss_iommu_ctrl(0);
unlock_exit:
	mutex_unlock(&mdp5_data->ov_lock);
	if (ctl->shared_lock)
		mutex_unlock(ctl->shared_lock);
	mdss_iommu_ctrl(0);
	ATRACE_END(__func__);

	return ret;
@@ -2083,6 +2085,8 @@ static int mdss_mdp_overlay_play(struct msm_fb_data_type *mfd,
		goto done;
	}

	mdss_mdp_release_splash_pipe(mfd);

	if (req->id & MDSS_MDP_ROT_SESSION_MASK) {
		ret = mdss_mdp_rotator_play(mfd, req);
	} else if (req->id == BORDERFILL_NDX) {