diff options
| author | Huaibin Yang <huaibiny@codeaurora.org> | 2013-04-29 16:56:24 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:16:54 -0700 |
| commit | 7be668f2c0131c827ee07dcf9b950d40e58a1aff (patch) | |
| tree | a5a2239587e0b8058764040ac9c78def9ae0da24 | |
| parent | 53846e5c6a941317442802e68550ef892454a28c (diff) | |
msm: mdss: allocate framebuffer memory in mdss_fb
Move fb memory allocation from mdp level up to mdss_fb based on the
device tree reserve size and then map the buffer depending on iommu,
so the code can be reused by multiple targets which have iommu mapping.
Change-Id: Ie57a097e047d26d69a92c05ddd0da22dfa6eca57
Signed-off-by: Huaibin Yang <huaibiny@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3.c | 48 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 63 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 41 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 1 |
5 files changed, 77 insertions, 77 deletions
diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c index 3d0d596185c3..902e5a6be0cb 100644 --- a/drivers/video/fbdev/msm/mdp3.c +++ b/drivers/video/fbdev/msm/mdp3.c @@ -708,45 +708,6 @@ u32 mdp3_fb_stride(u32 fb_index, u32 xres, int bpp) return xres * bpp; } -/* - * physical contiguous memory should be allocated in mdss_fb, and SMMU - * virtual address mapping can be done in the MDP h/w specific code. It - * should have a reference count, if none is current mapped, the SMMU context - * can bedetached, thus allowing power saving in SMMU. - */ -static int mdp3_fbmem_alloc(struct msm_fb_data_type *mfd) -{ - int 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) { - virt = allocate_contiguous_memory(size, MEMTYPE_EBI1, SZ_1M, 0); - if (!virt) { - pr_err("unable to alloc fbmem size=%u\n", size); - return -ENOMEM; - } - phys = memory_pool_node_paddr(virt); - dom = (mdp3_res->domains + MDP3_IOMMU_DOMAIN)->domain_idx; - msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0, - &mfd->iova); - - pr_debug("allocating %u bytes at %p (%lx phys) for fb %d\n", - size, virt, phys, mfd->index); - } else { - size = 0; - } - - mfd->fbi->screen_base = virt; - mfd->fbi->fix.smem_start = phys; - mfd->fbi->fix.smem_len = size; - return 0; -} - struct mdp3_dma *mdp3_get_dma_pipe(int capability) { int i; @@ -775,12 +736,19 @@ struct mdp3_intf *mdp3_get_display_intf(int type) return NULL; } +static int mdp3_fb_mem_get_iommu_domain(void) +{ + if (!mdp3_res) + return -ENODEV; + return mdp3_res->domains[MDP3_IOMMU_DOMAIN].domain_idx; +} + static int mdp3_probe(struct platform_device *pdev) { int rc; static struct msm_mdp_interface mdp3_interface = { .init_fnc = mdp3_init, - .fb_mem_alloc_fnc = mdp3_fbmem_alloc, + .fb_mem_get_iommu_domain = mdp3_fb_mem_get_iommu_domain, .fb_stride = mdp3_fb_stride, }; diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 920da0daaf61..1ad818239391 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -40,12 +40,16 @@ #include <linux/version.h> #include <linux/vmalloc.h> #include <linux/file.h> +#include <linux/memory_alloc.h> #include <sync.h> #include <sw_sync.h> #include <mach/board.h> #include <mach/memory.h> +#include <mach/iommu.h> +#include <mach/iommu_domains.h> +#include <mach/msm_memtypes.h> #include "mdss_fb.h" @@ -710,13 +714,68 @@ static struct fb_ops mdss_fb_ops = { .fb_mmap = mdss_fb_mmap, }; +static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom) +{ + void *virt = NULL; + unsigned long phys = 0; + size_t size = 0; + struct platform_device *pdev = mfd->pdev; + + if (!pdev || !pdev->dev.of_node) { + pr_err("Invalid device node\n"); + return -ENODEV; + } + + if (of_property_read_u32(pdev->dev.of_node, + "qcom,memory-reservation-size", + &size) || !size) { + mfd->fbi->screen_base = NULL; + mfd->fbi->fix.smem_start = 0; + mfd->fbi->fix.smem_len = 0; + return 0; + } + + pr_info("%s frame buffer reserve_size=0x%x\n", __func__, size); + + if (size < PAGE_ALIGN(mfd->fbi->fix.line_length * + mfd->fbi->var.yres_virtual)) + pr_warn("reserve size is smaller than framebuffer size\n"); + + virt = allocate_contiguous_memory(size, MEMTYPE_EBI1, SZ_1M, 0); + if (!virt) { + pr_err("unable to alloc fbmem size=%u\n", size); + return -ENOMEM; + } + + phys = memory_pool_node_paddr(virt); + + msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0, + &mfd->iova); + 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; +} + static int mdss_fb_alloc_fbmem(struct msm_fb_data_type *mfd) { - if (!mfd->mdp.fb_mem_alloc_fnc) { + + if (mfd->mdp.fb_mem_alloc_fnc) + return mfd->mdp.fb_mem_alloc_fnc(mfd); + else if (mfd->mdp.fb_mem_get_iommu_domain) { + int dom = mfd->mdp.fb_mem_get_iommu_domain(); + if (dom >= 0) + return mdss_fb_alloc_fbmem_iommu(mfd, dom); + else + return -ENOMEM; + } else { pr_err("no fb memory allocator function defined\n"); return -ENOMEM; } - return mfd->mdp.fb_mem_alloc_fnc(mfd); } static int mdss_fb_register(struct msm_fb_data_type *mfd) diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h index 6f6f49046661..5682f0bcad9f 100644 --- a/drivers/video/fbdev/msm/mdss_fb.h +++ b/drivers/video/fbdev/msm/mdss_fb.h @@ -56,6 +56,7 @@ struct msm_fb_data_type; struct msm_mdp_interface { int (*fb_mem_alloc_fnc)(struct msm_fb_data_type *mfd); + int (*fb_mem_get_iommu_domain)(void); int (*init_fnc)(struct msm_fb_data_type *mfd); int (*on_fnc)(struct msm_fb_data_type *mfd); int (*off_fnc)(struct msm_fb_data_type *mfd); diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index ce737997a5fe..d3c0361b22bb 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -55,9 +55,15 @@ #include "mdss_debug.h" struct mdss_data_type *mdss_res; + +static int mdss_fb_mem_get_iommu_domain(void) +{ + return mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE); +} + struct msm_mdp_interface mdp5 = { .init_fnc = mdss_mdp_overlay_init, - .fb_mem_alloc_fnc = mdss_mdp_alloc_fb_mem, + .fb_mem_get_iommu_domain = mdss_fb_mem_get_iommu_domain, .panel_register_done = mdss_panel_register_done, .fb_stride = mdss_mdp_fb_stride, }; @@ -136,39 +142,6 @@ static int mdss_mdp_parse_dt_smp(struct platform_device *pdev); static int mdss_mdp_parse_dt_misc(struct platform_device *pdev); static int mdss_mdp_parse_dt_ad_cfg(struct platform_device *pdev); -int mdss_mdp_alloc_fb_mem(struct msm_fb_data_type *mfd) -{ - int 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) { - virt = allocate_contiguous_memory(size, MEMTYPE_EBI1, SZ_1M, 0); - if (!virt) { - pr_err("unable to alloc fbmem size=%u\n", size); - return -ENOMEM; - } - phys = memory_pool_node_paddr(virt); - dom = mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE); - msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0, - &mfd->iova); - - pr_debug("allocating %u bytes at %p (%lx phys) for fb %d\n", - size, virt, phys, mfd->index); - } else - size = 0; - - mfd->fbi->screen_base = virt; - mfd->fbi->fix.smem_start = phys; - mfd->fbi->fix.smem_len = size; - - return 0; -} - u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp) { /* The adreno GPU hardware requires that the pitch be aligned to diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index e18722ca5fde..a65052201187 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -533,7 +533,6 @@ int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd); int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg); int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id); -int mdss_mdp_alloc_fb_mem(struct msm_fb_data_type *mfd); u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp); int mdss_panel_register_done(struct mdss_panel_data *pdata); |
