Merge "msm: mdss: support frame buffer allocation on 8x10"
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 4abd0f7..0cf1093 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -1667,69 +1667,79 @@
 		return xres * bpp;
 }
 
-static int mdp3_alloc(size_t size, void **virt, unsigned long *phys)
+static int mdp3_alloc(struct msm_fb_data_type *mfd)
 {
-	int ret = 0;
+	int ret;
+	int dom;
+	void *virt;
+	unsigned long phys;
+	u32 offsets[2];
+	size_t size;
+	struct platform_device *pdev = mfd->pdev;
 
-	if (mdp3_res->ion_handle) {
-		pr_debug("memory already alloc\n");
-		*virt = mdp3_res->virt;
-		*phys = mdp3_res->phys;
-		return 0;
+	mfd->fbi->screen_base = NULL;
+	mfd->fbi->fix.smem_start = 0;
+	mfd->fbi->fix.smem_len = 0;
+
+	ret = of_property_read_u32_array(pdev->dev.of_node,
+				"qcom,memblock-reserve", offsets, 2);
+
+	if (ret) {
+		pr_err("fail to parse splash memory address\n");
+		return ret;
 	}
 
-	mdp3_res->ion_handle = ion_alloc(mdp3_res->ion_client, size,
-					SZ_1M,
-					ION_HEAP(ION_QSECOM_HEAP_ID), 0);
+	phys = offsets[0];
+	size = PAGE_ALIGN(mfd->fbi->fix.line_length *
+		mfd->fbi->var.yres_virtual);
 
-	if (!IS_ERR_OR_NULL(mdp3_res->ion_handle)) {
-		*virt = ion_map_kernel(mdp3_res->ion_client,
-					mdp3_res->ion_handle);
-		if (IS_ERR(*virt)) {
-			pr_err("map kernel error\n");
-			goto ion_map_kernel_err;
-		}
+	if (size > offsets[1]) {
+		pr_err("reserved splash memory size too small\n");
+		return -EINVAL;
+	}
 
-		ret = ion_phys(mdp3_res->ion_client, mdp3_res->ion_handle,
-				phys, &size);
-		if (ret) {
-			pr_err("%s ion_phys error\n", __func__);
-			goto ion_map_phys_err;
-		}
-
-		mdp3_res->virt = *virt;
-		mdp3_res->phys = *phys;
-		mdp3_res->size = size;
-	} else {
-		pr_err("%s ion alloc fail\n", __func__);
-		mdp3_res->ion_handle = NULL;
+	virt = phys_to_virt(phys);
+	if (unlikely(!virt)) {
+		pr_err("unable to map in splash memory\n");
 		return -ENOMEM;
 	}
 
-	return 0;
+	dom = mdp3_res->domains[MDP3_DMA_IOMMU_DOMAIN].domain_idx;
+	ret = msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0,
+					&mfd->iova);
 
-ion_map_phys_err:
-	ion_unmap_kernel(mdp3_res->ion_client, mdp3_res->ion_handle);
-ion_map_kernel_err:
-	ion_free(mdp3_res->ion_client, mdp3_res->ion_handle);
-	mdp3_res->ion_handle = NULL;
-	mdp3_res->virt = NULL;
-	mdp3_res->phys = 0;
-	mdp3_res->size = 0;
-	return -ENOMEM;
+	if (ret) {
+		pr_err("fail to map to IOMMU %d\n", ret);
+		return ret;
+	}
+	pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n",
+		size, virt, phys, mfd->index);
+
+	mfd->fbi->screen_base = virt;
+	mfd->fbi->fix.smem_start = phys;
+	mfd->fbi->fix.smem_len = size;
+
+	return 0;
 }
 
-void mdp3_free(void)
+void mdp3_free(struct msm_fb_data_type *mfd)
 {
-	pr_debug("mdp3_fbmem_free\n");
-	if (mdp3_res->ion_handle) {
-		ion_unmap_kernel(mdp3_res->ion_client, mdp3_res->ion_handle);
-		ion_free(mdp3_res->ion_client, mdp3_res->ion_handle);
-		mdp3_res->ion_handle = NULL;
-		mdp3_res->virt = NULL;
-		mdp3_res->phys = 0;
-		mdp3_res->size = 0;
+	size_t size = 0;
+	int dom;
+
+	if (!mfd->iova || !mfd->fbi->screen_base) {
+		pr_info("no fbmem allocated\n");
+		return;
 	}
+
+	size = mfd->fbi->fix.smem_len;
+	dom = mdp3_res->domains[MDP3_DMA_IOMMU_DOMAIN].domain_idx;
+	msm_iommu_unmap_contig_buffer(mfd->iova, dom, 0, size);
+
+	mfd->fbi->screen_base = NULL;
+	mfd->fbi->fix.smem_start = 0;
+	mfd->fbi->fix.smem_len = 0;
+	mfd->iova = 0;
 }
 
 int mdp3_parse_dt_splash(struct msm_fb_data_type *mfd)
@@ -1752,16 +1762,17 @@
 	mdp3_res->splash_mem_addr = offsets[0];
 	mdp3_res->splash_mem_size = offsets[1];
 
-	pr_debug("memaddr=%x size=%x\n", mdp3_res->splash_mem_addr,
+	pr_debug("memaddr=%lx size=%x\n", mdp3_res->splash_mem_addr,
 		mdp3_res->splash_mem_size);
 
 	return rc;
 }
 
-void mdp3_release_splash_memory(void)
+void mdp3_release_splash_memory(struct msm_fb_data_type *mfd)
 {
 	/* Give back the reserved memory to the system */
 	if (mdp3_res->splash_mem_addr) {
+		mdp3_free(mfd);
 		pr_debug("mdp3_release_splash_memory\n");
 		memblock_free(mdp3_res->splash_mem_addr,
 				mdp3_res->splash_mem_size);
@@ -1811,44 +1822,6 @@
 	return mdp3_res->cont_splash_en;
 }
 
-int mdp3_continuous_splash_copy(struct mdss_panel_data *pdata)
-{
-	unsigned long splash_phys, phys;
-	void *splash_virt, *virt;
-	u32 height, width, rgb_size, stride;
-	size_t size;
-	int rc;
-
-	if (pdata->panel_info.type != MIPI_VIDEO_PANEL) {
-		pr_debug("cmd mode panel, no need to copy splash image\n");
-		return 0;
-	}
-
-	rgb_size = MDP3_REG_READ(MDP3_REG_DMA_P_SIZE);
-	stride = MDP3_REG_READ(MDP3_REG_DMA_P_IBUF_Y_STRIDE);
-	stride = stride & 0x3FFF;
-	splash_phys = MDP3_REG_READ(MDP3_REG_DMA_P_IBUF_ADDR);
-
-	height = (rgb_size >> 16) & 0xffff;
-	width  = rgb_size & 0xffff;
-	size = PAGE_ALIGN(height * stride);
-	pr_debug("splash_height=%d splash_width=%d Buffer size=%d\n",
-		height, width, size);
-
-	rc = mdp3_alloc(size, &virt, &phys);
-	if (rc) {
-		pr_err("fail to allocate memory for continuous splash image\n");
-		return rc;
-	}
-
-	splash_virt = ioremap(splash_phys, stride * height);
-	memcpy(virt, splash_virt, stride * height);
-	iounmap(splash_virt);
-	MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, phys);
-
-	return 0;
-}
-
 static int mdp3_is_display_on(struct mdss_panel_data *pdata)
 {
 	int rc = 0;
@@ -2174,6 +2147,7 @@
 	.fb_mem_get_iommu_domain = mdp3_fb_mem_get_iommu_domain,
 	.panel_register_done = mdp3_panel_register_done,
 	.fb_stride = mdp3_fb_stride,
+	.fb_mem_alloc_fnc = mdp3_alloc,
 	};
 
 	struct mdp3_intr_cb underrun_cb = {
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index bd0dc65..a253d8f 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -137,9 +137,6 @@
 	struct ion_handle *ion_handle;
 	struct mutex iommu_lock;
 	struct rb_root iommu_root;
-	void *virt;
-	unsigned long phys;
-	size_t size;
 
 	struct mdp3_dma dma[MDP3_DMA_MAX];
 	struct mdp3_intf intf[MDP3_DMA_OUTPUT_SEL_MAX];
@@ -154,7 +151,7 @@
 
 	struct early_suspend suspend_handler;
 	struct mdss_panel_cfg pan_cfg;
-	u32 splash_mem_addr;
+	unsigned long splash_mem_addr;
 	u32 splash_mem_size;
 
 	int clk_prepare_count;
@@ -195,9 +192,9 @@
 int mdp3_iommu_enable(int client);
 int mdp3_iommu_disable(int client);
 int mdp3_iommu_is_attached(int client);
-void mdp3_free(void);
+void mdp3_free(struct msm_fb_data_type *mfd);
 int mdp3_parse_dt_splash(struct msm_fb_data_type *mfd);
-void mdp3_release_splash_memory(void);
+void mdp3_release_splash_memory(struct msm_fb_data_type *mfd);
 int mdp3_create_sysfs_link(struct device *dev);
 int mdp3_get_cont_spash_en(void);
 int mdp3_get_mdp_dsi_clk(void);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index dafaae3..44a7e51 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -627,17 +627,8 @@
 	}
 
 	mdp3_session->clk_on = 1;
-	pr_debug("mdp3_ctrl_on dma start\n");
-	if (mfd->fbi->screen_base) {
-		rc = mdp3_session->dma->start(mdp3_session->dma,
-						mdp3_session->intf);
-		if (rc) {
-			pr_err("fail to start the MDP display interface\n");
-			goto on_error;
-		}
-	} else {
-		mdp3_session->first_commit = true;
-	}
+
+	mdp3_session->first_commit = true;
 
 on_error:
 	if (!rc)
@@ -763,10 +754,7 @@
 	if (vsync_client.handler)
 		mdp3_dma->vsync_enable(mdp3_dma, &vsync_client);
 
-	if (mfd->fbi->screen_base)
-		rc = mdp3_dma->start(mdp3_dma, mdp3_session->intf);
-	else
-		mdp3_session->first_commit = true;
+	mdp3_session->first_commit = true;
 
 reset_error:
 	mutex_unlock(&mdp3_session->lock);
@@ -854,10 +842,7 @@
 	if (vsync_client.handler)
 		mdp3_dma->vsync_enable(mdp3_dma, &vsync_client);
 
-	if (mfd->fbi->screen_base)
-		rc = mdp3_dma->start(mdp3_dma, mdp3_session->intf);
-	else
-		mdp3_session->first_commit = true;
+	mdp3_session->first_commit = true;
 
 reset_error:
 	mutex_unlock(&mdp3_session->lock);
@@ -1030,7 +1015,6 @@
 		mdp3_ctrl_reset(mfd);
 		reset_done = true;
 	}
-	mdp3_release_splash_memory();
 
 	mutex_lock(&mdp3_session->lock);
 
@@ -1065,6 +1049,7 @@
 	}
 
 	if (mdp3_bufq_count(&mdp3_session->bufq_out) > 1) {
+		mdp3_release_splash_memory(mfd);
 		data = mdp3_bufq_pop(&mdp3_session->bufq_out);
 		mdp3_put_img(data, MDP3_CLIENT_DMA_P);
 	}
@@ -1110,7 +1095,6 @@
 		pr_debug("continuous splash screen, IOMMU not attached\n");
 		mdp3_ctrl_reset(mfd);
 	}
-	mdp3_release_splash_memory();
 
 	mutex_lock(&mdp3_session->lock);