summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorXiaoming Zhou <zhoux@codeaurora.org>2013-06-27 18:02:18 -0400
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:18:47 -0700
commit0002d8177d65cff53e3ae95b8d51ef11a6cef8dc (patch)
tree46cd4e1726c9860eef0757f9a354c38ba1ca234e /drivers/video/fbdev
parentd34fdd343d1c13bc4f13758cda17857f424c17d1 (diff)
msm: mdss: support recovery mode on 8x10
The recovery mode is using the frame buffer memory and pan display to render. To support this, we need to allocate frame buffer. Change-Id: I3c2d9b849abfa5420860f9d6ba89df355efb4061 Signed-off-by: Xiaoming Zhou <zhoux@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdp3.c87
-rw-r--r--drivers/video/fbdev/msm/mdp3.h2
-rw-r--r--drivers/video/fbdev/msm/mdp3_ctrl.c10
3 files changed, 99 insertions, 0 deletions
diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c
index a53d2da6b60f..7bf600e833c5 100644
--- a/drivers/video/fbdev/msm/mdp3.c
+++ b/drivers/video/fbdev/msm/mdp3.c
@@ -983,6 +983,92 @@ u32 mdp3_fb_stride(u32 fb_index, u32 xres, int bpp)
return xres * bpp;
}
+static int mdp3_fbmem_alloc(struct msm_fb_data_type *mfd)
+{
+ int ret = -ENOMEM, dom;
+ void *virt = NULL;
+ unsigned long phys = 0;
+ size_t size;
+ u32 yres = mfd->fbi->var.yres_virtual;
+
+ size = PAGE_ALIGN(mfd->fbi->fix.line_length * yres);
+
+ if (mfd->index != 0) {
+ mfd->fbi->screen_base = virt;
+ mfd->fbi->fix.smem_start = phys;
+ mfd->fbi->fix.smem_len = 0;
+ return 0;
+ }
+
+ mdp3_res->ion_handle = ion_alloc(mdp3_res->ion_client, size,
+ SZ_1M,
+ ION_HEAP(ION_QSECOM_HEAP_ID), 0);
+
+ 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("%s map kernel error\n", __func__);
+ goto ion_map_kernel_err;
+ }
+
+ 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;
+ }
+ } else {
+ pr_err("%s ion alloc fail\n", __func__);
+ mdp3_res->ion_handle = NULL;
+ return -ENOMEM;
+ }
+
+ dom = (mdp3_res->domains + MDP3_IOMMU_DOMAIN)->domain_idx;
+
+ ret = ion_map_iommu(mdp3_res->ion_client, mdp3_res->ion_handle,
+ dom, 0, SZ_4K, 0, &mfd->iova,
+ (unsigned long *)&size, 0, 0);
+
+ if (ret) {
+ pr_err("%s map IOMMU error\n", __func__);
+ goto ion_map_phys_err;
+ }
+
+ 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;
+
+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;
+ return -ENOMEM;
+}
+
+void mdp3_fbmem_free(struct msm_fb_data_type *mfd)
+{
+ pr_info("mdp3_fbmem_free\n");
+ if (mdp3_res->ion_handle) {
+ int dom = (mdp3_res->domains + MDP3_IOMMU_DOMAIN)->domain_idx;
+
+ ion_unmap_kernel(mdp3_res->ion_client, mdp3_res->ion_handle);
+ ion_unmap_iommu(mdp3_res->ion_client, mdp3_res->ion_handle,
+ dom, 0);
+ ion_free(mdp3_res->ion_client, mdp3_res->ion_handle);
+ mdp3_res->ion_handle = NULL;
+ mfd->fbi->screen_base = 0;
+ mfd->fbi->fix.smem_start = 0;
+ mfd->fbi->fix.smem_len = 0;
+ mfd->iova = 0;
+ }
+}
+
struct mdp3_dma *mdp3_get_dma_pipe(int capability)
{
int i;
@@ -1024,6 +1110,7 @@ static int mdp3_probe(struct platform_device *pdev)
static struct msm_mdp_interface mdp3_interface = {
.init_fnc = mdp3_init,
.fb_mem_get_iommu_domain = mdp3_fb_mem_get_iommu_domain,
+ .fb_mem_alloc_fnc = mdp3_fbmem_alloc,
.fb_stride = mdp3_fb_stride,
};
diff --git a/drivers/video/fbdev/msm/mdp3.h b/drivers/video/fbdev/msm/mdp3.h
index 850b8b529c43..18cd7eb33c66 100644
--- a/drivers/video/fbdev/msm/mdp3.h
+++ b/drivers/video/fbdev/msm/mdp3.h
@@ -109,6 +109,7 @@ struct mdp3_hw_resource {
struct ion_client *ion_client;
struct mdp3_iommu_domain_map *domains;
struct mdp3_iommu_ctx_map *iommu_contexts;
+ struct ion_handle *ion_handle;
struct mdp3_dma dma[MDP3_DMA_MAX];
struct mdp3_intf intf[MDP3_DMA_OUTPUT_SEL_MAX];
@@ -146,6 +147,7 @@ int mdp3_put_img(struct mdp3_img_data *data);
int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data);
int mdp3_iommu_enable(int client);
int mdp3_iommu_disable(int client);
+void mdp3_fbmem_free(struct msm_fb_data_type *mfd);
#define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr)
#define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr)
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index 008daddb8e54..04cd78c88dc3 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -461,6 +461,10 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd)
goto on_error;
}
+ if (panel->set_backlight)
+ panel->set_backlight(panel, panel->panel_info.bl_max);
+
+ pr_debug("mdp3_ctrl_on dma start\n");
if (mfd->fbi->screen_base) {
rc = mdp3_session->dma->start(mdp3_session->dma,
mdp3_session->intf);
@@ -503,6 +507,9 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd)
mdp3_histogram_stop(mdp3_session, MDP_BLOCK_DMA_P);
pr_debug("mdp3_ctrl_off turn panel off\n");
+ if (panel->set_backlight)
+ panel->set_backlight(panel, 0);
+
if (panel->event_handler)
rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
if (rc)
@@ -677,6 +684,9 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd)
if (mdp3_bufq_count(&mdp3_session->bufq_out) > 2) {
data = mdp3_bufq_pop(&mdp3_session->bufq_out);
mdp3_put_img(data);
+
+ if (mfd->fbi->screen_base)
+ mdp3_fbmem_free(mfd);
}
mutex_unlock(&mdp3_session->lock);