diff options
| author | Xiaoming Zhou <zhoux@codeaurora.org> | 2013-06-27 18:02:18 -0400 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:18:47 -0700 |
| commit | 0002d8177d65cff53e3ae95b8d51ef11a6cef8dc (patch) | |
| tree | 46cd4e1726c9860eef0757f9a354c38ba1ca234e /drivers/video/fbdev | |
| parent | d34fdd343d1c13bc4f13758cda17857f424c17d1 (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.c | 87 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3.h | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3_ctrl.c | 10 |
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); |
