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);