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

Commit 7e713131 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran
Browse files

msm: mdss: fix smmu buffer mapping in recovery mode



When booting up in recovery mode, mmap is called without iommu attach.
This would result in device panic as iommu fails when buffer mapping is
done without attaching the respective iommu domain. Fix the issue by
delaying the mapping to a later point, during the commit.

Change-Id: Idbe4f6ca5557774b5add56c064ea6b05a67d530f
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent c72397bc
Loading
Loading
Loading
Loading
+2 −16
Original line number Diff line number Diff line
@@ -1667,9 +1667,6 @@ void mdss_fb_free_fb_ion_memory(struct msm_fb_data_type *mfd)
	ion_unmap_kernel(mfd->fb_ion_client, mfd->fb_ion_handle);

	if (mfd->mdp.fb_mem_get_iommu_domain) {
		mdss_smmu_unmap_dma_buf(mfd->fb_table,
				mfd->mdp.fb_mem_get_iommu_domain(),
				DMA_BIDIRECTIONAL, mfd->fbmem_buf);
		dma_buf_unmap_attachment(mfd->fb_attachment, mfd->fb_table,
				DMA_BIDIRECTIONAL);
		dma_buf_detach(mfd->fbmem_buf, mfd->fb_attachment);
@@ -1682,7 +1679,6 @@ void mdss_fb_free_fb_ion_memory(struct msm_fb_data_type *mfd)

int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size)
{
	unsigned long buf_size;
	int rc;
	void *vaddr;
	int domain;
@@ -1732,14 +1728,6 @@ int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size)
			rc = PTR_ERR(mfd->fb_table);
			goto err_detach;
		}

		rc = mdss_smmu_map_dma_buf(mfd->fbmem_buf, mfd->fb_table,
				domain, &mfd->iova, &buf_size,
				DMA_BIDIRECTIONAL);
		if (rc) {
			pr_err("Cannot map fb_mem to IOMMU. rc=%d\n", rc);
			goto err_unmap;
		}
	} else {
		pr_err("No IOMMU Domain\n");
		rc = -EINVAL;
@@ -1752,12 +1740,10 @@ int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size)
		rc = PTR_ERR(vaddr);
		goto err_unmap;
	}

	pr_debug("alloc 0x%zuB vaddr = %p (%pa iova) for fb%d\n", fb_size,
			vaddr, &mfd->iova, mfd->index);
	pr_debug("alloc 0x%zuB vaddr = %p for fb%d\n", fb_size,
			vaddr, mfd->index);

	mfd->fbi->screen_base = (char *) vaddr;
	mfd->fbi->fix.smem_start = (unsigned int) mfd->iova;
	mfd->fbi->fix.smem_len = fb_size;

	return rc;
+1 −0
Original line number Diff line number Diff line
@@ -382,6 +382,7 @@ struct mdss_mdp_img_data {
	u32 offset;
	u32 flags;
	bool mapped;
	bool skip_detach;
	struct fd srcp_f;
	struct dma_buf *srcp_dma_buf;
	struct dma_buf_attachment *srcp_attachment;
+8 −14
Original line number Diff line number Diff line
@@ -2329,7 +2329,7 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
	if (!mdp5_data || !mdp5_data->ctl)
		return;

	if (!fbi->fix.smem_start || fbi->fix.smem_len == 0 ||
	if (fbi->fix.smem_len == 0 ||
			mdp5_data->borderfill_enable) {
		mfd->mdp.kickoff_fnc(mfd, NULL);
		return;
@@ -2388,19 +2388,13 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
		goto pan_display_error;
	}

	if (mdata->mdss_util->iommu_attached()) {
		if (!mfd->iova) {
			pr_err("mfd iova is zero\n");
			mdss_mdp_pipe_unmap(pipe);
			goto pan_display_error;
		}
		buf_l->p[0].addr = mfd->iova;
	} else {
		buf_l->p[0].addr = fbi->fix.smem_start;
	}

	buf_l->p[0].addr += offset;
	buf_l->p[0].len = fbi->fix.smem_len - offset;
	buf_l->p[0].srcp_table = mfd->fb_table;
	buf_l->p[0].srcp_dma_buf = mfd->fbmem_buf;
	buf_l->p[0].len = 0;
	buf_l->p[0].addr = 0;
	buf_l->p[0].offset = offset;
	buf_l->p[0].skip_detach = true;
	buf_l->p[0].mapped = false;
	buf_l->num_planes = 1;

	mdss_mdp_pipe_unmap(pipe);
+8 −6
Original line number Diff line number Diff line
@@ -836,6 +836,7 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data, bool rotator,
							data->srcp_dma_buf);
				data->mapped = false;
			}
			if (!data->skip_detach) {
				dma_buf_unmap_attachment(data->srcp_attachment,
					data->srcp_table, dir);
				dma_buf_detach(data->srcp_dma_buf,
@@ -843,6 +844,7 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data, bool rotator,
				dma_buf_put(data->srcp_dma_buf);
				data->srcp_dma_buf = NULL;
			}
		}

	} else {
		return -ENOMEM;