diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/video/samsung/fimc/fimc_dev.c | 54 | ||||
-rw-r--r-- | drivers/media/video/samsung/fimc/fimc_dev_u1.c | 54 | ||||
-rw-r--r-- | drivers/media/video/samsung/jpeg/jpeg_dev.c | 7 | ||||
-rw-r--r-- | drivers/media/video/samsung/mali/arch-orion-m400/config.h | 2 | ||||
-rw-r--r-- | drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c | 59 | ||||
-rw-r--r-- | drivers/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 12 |
8 files changed, 167 insertions, 23 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 94f9ec1..d11f4f3 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -40,7 +40,6 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ obj-$(CONFIG_DRM_VIA) +=via/ obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ ifeq ($(CONFIG_NAPLES_COMMON),y) -obj-$(CONFIG_DRM_EXYNOS) +=exynos_tmp/ else obj-$(CONFIG_DRM_EXYNOS) +=exynos/ endif diff --git a/drivers/media/video/samsung/fimc/fimc_dev.c b/drivers/media/video/samsung/fimc/fimc_dev.c index 1ed79dd..4822587 100644 --- a/drivers/media/video/samsung/fimc/fimc_dev.c +++ b/drivers/media/video/samsung/fimc/fimc_dev.c @@ -898,6 +898,50 @@ static struct vm_operations_struct fimc_mmap_ops = { }; static inline +int fimc_mmap_own_mem(struct file *filp, struct vm_area_struct *vma) +{ + struct fimc_prv_data *prv_data = + (struct fimc_prv_data *)filp->private_data; + struct fimc_control *ctrl = prv_data->ctrl; + u32 start_phy_addr = 0; + u32 size = vma->vm_end - vma->vm_start; + u32 pfn, idx = vma->vm_pgoff; + u32 buf_length = 0; + + buf_length = ctrl->mem.size; + if (size > PAGE_ALIGN(buf_length)) { + fimc_err("Requested mmap size is too big\n"); + return -EINVAL; + } + + start_phy_addr = ctrl->mem.base + (vma->vm_pgoff << PAGE_SHIFT); + + if (!cma_is_registered_region(start_phy_addr, size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, buf_length, start_phy_addr); + return -EINVAL; + } + + /* only supports non-cached mmap */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_RESERVED; + + if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) { + fimc_err("writable mapping must be shared\n"); + return -EINVAL; + } + + pfn = __phys_to_pfn(start_phy_addr); + + if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) { + fimc_err("mmap fail\n"); + return -EINVAL; + } + + return 0; +} + +static inline int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma) { struct fimc_prv_data *prv_data = @@ -981,10 +1025,14 @@ static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma) int idx = ctrl->out->ctx[ctx_id].overlay.req_idx; int ret = -1; +#if 0 if (idx >= 0) ret = fimc_mmap_out_dst(filp, vma, idx); else if (idx == FIMC_MMAP_IDX) ret = fimc_mmap_out_src(filp, vma); +#else + ret = fimc_mmap_own_mem(filp, vma); +#endif return ret; } @@ -1002,6 +1050,12 @@ static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; + if (!cma_is_registered_region(ctrl->cap->bufs[idx].base[0], size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, size, ctrl->cap->bufs[idx].base[0]); + return -EINVAL; + } + /* * page frame number of the address for a source frame * to be stored at. diff --git a/drivers/media/video/samsung/fimc/fimc_dev_u1.c b/drivers/media/video/samsung/fimc/fimc_dev_u1.c index 811ac96..52246a1 100644 --- a/drivers/media/video/samsung/fimc/fimc_dev_u1.c +++ b/drivers/media/video/samsung/fimc/fimc_dev_u1.c @@ -745,6 +745,50 @@ static struct vm_operations_struct fimc_mmap_ops = { }; static inline +int fimc_mmap_own_mem(struct file *filp, struct vm_area_struct *vma) +{ + struct fimc_prv_data *prv_data = + (struct fimc_prv_data *)filp->private_data; + struct fimc_control *ctrl = prv_data->ctrl; + u32 start_phy_addr = 0; + u32 size = vma->vm_end - vma->vm_start; + u32 pfn, idx = vma->vm_pgoff; + u32 buf_length = 0; + + buf_length = ctrl->mem.size; + if (size > PAGE_ALIGN(buf_length)) { + fimc_err("Requested mmap size is too big\n"); + return -EINVAL; + } + + start_phy_addr = ctrl->mem.base + (vma->vm_pgoff << PAGE_SHIFT); + + if (!cma_is_registered_region(start_phy_addr, size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, buf_length, start_phy_addr); + return -EINVAL; + } + + /* only supports non-cached mmap */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_RESERVED; + + if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) { + fimc_err("writable mapping must be shared\n"); + return -EINVAL; + } + + pfn = __phys_to_pfn(start_phy_addr); + + if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) { + fimc_err("mmap fail\n"); + return -EINVAL; + } + + return 0; +} + +static inline int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma) { struct fimc_prv_data *prv_data = @@ -829,10 +873,14 @@ static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma) int idx = ctrl->out->ctx[ctx_id].overlay.req_idx; int ret = -1; +#if 0 if (idx >= 0) ret = fimc_mmap_out_dst(filp, vma, idx); else if (idx == FIMC_MMAP_IDX) ret = fimc_mmap_out_src(filp, vma); +#else + ret = fimc_mmap_own_mem(filp, vma); +#endif return ret; } @@ -849,6 +897,12 @@ static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_flags |= VM_RESERVED; + if (!cma_is_registered_region(ctrl->cap->bufs[idx].base[0], size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, size, ctrl->cap->bufs[idx].base[0]); + return -EINVAL; + } + /* * page frame number of the address for a source frame * to be stored at. diff --git a/drivers/media/video/samsung/jpeg/jpeg_dev.c b/drivers/media/video/samsung/jpeg/jpeg_dev.c index 4038fd2..6ebcfb6 100644 --- a/drivers/media/video/samsung/jpeg/jpeg_dev.c +++ b/drivers/media/video/samsung/jpeg/jpeg_dev.c @@ -31,6 +31,7 @@ #include <linux/clk.h> #include <linux/semaphore.h> #include <linux/vmalloc.h> +#include <linux/cma.h> #include <asm/page.h> #include <linux/sched.h> @@ -247,6 +248,12 @@ int jpeg_mmap(struct file *filp, struct vm_area_struct *vma) size = vma->vm_end - vma->vm_start; + if (!cma_is_registered_region(jpeg_ctrl->mem.base, size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, (unsigned int)size, jpeg_ctrl->mem.base); + return -EINVAL; + } + vma->vm_flags |= VM_RESERVED | VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h index 5c4d79d..73502a2 100644 --- a/drivers/media/video/samsung/mali/arch-orion-m400/config.h +++ b/drivers/media/video/samsung/mali/arch-orion-m400/config.h @@ -130,7 +130,7 @@ static _mali_osk_resource_t arch_configuration [] = #endif/* if USING_OS_MEMORY*/ { .type = MEM_VALIDATION, - .description = "memory validation", + .description = "Framebuffer Memory", .base = MEM_BASE_ADDR, .size = MEM_TOTAL_SIZE, .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c index 3fa6e55..228be02 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c +++ b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c @@ -27,6 +27,8 @@ #include <plat/sysmmu.h> #endif +#include <linux/cma.h> + #ifdef CONFIG_UMP_VCM_ALLOC #include "ump_kernel_interface.h" #endif @@ -881,13 +883,24 @@ long s5p_tvout_tvif_ioctl( goto end_tvif_ioctl; } for (i = 0; i < S5PTV_VP_BUFF_CNT; i++) { - s5ptv_vp_buff.vp_buffs[i].phy_base = buffs[i].phy_base; - s5ptv_vp_buff.vp_buffs[i].vir_base = - (unsigned int)phys_to_virt(buffs[i].phy_base); - s5ptv_vp_buff.vp_buffs[i].size = buffs[i].size; - tvout_dbg("s5ptv_vp_buff phy_base = 0x%x, vir_base = 0x%8x\n", - s5ptv_vp_buff.vp_buffs[i].phy_base, - s5ptv_vp_buff.vp_buffs[i].vir_base); + if (cma_is_registered_region(buffs[i].phy_base, + buffs[i].size)) { + s5ptv_vp_buff.vp_buffs[i].phy_base = + buffs[i].phy_base; + s5ptv_vp_buff.vp_buffs[i].vir_base = + (unsigned int)phys_to_virt(buffs[i].phy_base); + s5ptv_vp_buff.vp_buffs[i].size = buffs[i].size; + tvout_dbg("s5ptv_vp_buff phy_base = 0x%x, " + "vir_base = 0x%8x\n", + s5ptv_vp_buff.vp_buffs[i].phy_base, + s5ptv_vp_buff.vp_buffs[i].vir_base); + } else { + s5ptv_vp_buff.vp_buffs[i].phy_base = 0; + s5ptv_vp_buff.vp_buffs[i].vir_base = 0; + printk(KERN_ERR "Buffer for VP is not CMA region\n"); + ret = -EINVAL; + goto end_tvif_ioctl; + } } goto end_tvif_ioctl; } @@ -1134,6 +1147,25 @@ static int s5p_tvout_vo_s_fmt_type_private( pix_fmt->height, color, field); #else if (pix_fmt->priv) { + if (pix_fmt->pixelformat == V4L2_PIX_FMT_NV12T + || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) { + y_size = ALIGN(ALIGN(pix_fmt->width, 128) * + ALIGN(pix_fmt->height, 32), SZ_8K); + cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) * + ALIGN(pix_fmt->height >> 1, 32), SZ_8K); + } else { + y_size = pix_fmt->width * pix_fmt->height; + cbcr_size = pix_fmt->width * (pix_fmt->height >> 1); + } + if (!cma_is_registered_region((unsigned int)vparam.base_y, + y_size) || + !cma_is_registered_region((unsigned int)vparam.base_c, + cbcr_size)) { + printk(KERN_ERR "Source image for VP is not" + "CMA region\n"); + goto error_on_s_fmt_type_private; + } + copy_buff_idx = s5ptv_vp_buff. copy_buff_idxs[s5ptv_vp_buff.curr_copy_idx]; @@ -1144,19 +1176,6 @@ static int s5p_tvout_vo_s_fmt_type_private( (u32) vparam.base_y, (u32) vparam.base_c, pix_fmt->width, pix_fmt->height, color, field); } else { - if (pix_fmt->pixelformat == - V4L2_PIX_FMT_NV12T - || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) { - y_size = ALIGN(ALIGN(pix_fmt->width, 128) * - ALIGN(pix_fmt->height, 32), SZ_8K); - cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) * - ALIGN(pix_fmt->height >> 1, 32), SZ_8K); - } else { - y_size = pix_fmt->width * pix_fmt->height; - cbcr_size = - pix_fmt->width * (pix_fmt->height >> 1); - } - src_vir_y_addr = (unsigned int)phys_to_virt( (unsigned long)vparam.base_y); src_vir_cb_addr = (unsigned int)phys_to_virt( diff --git a/drivers/video/Makefile b/drivers/video/Makefile index ff3c7b2..1261866 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -182,4 +182,3 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o #video output switch sysfs driver obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o - diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index b585a38..1ca9b20 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -34,6 +34,7 @@ #include <linux/fb.h> #include <asm/fb.h> +#include <linux/cma.h> /* @@ -1380,6 +1381,17 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) /* frame buffer memory */ start = info->fix.smem_start; len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); + +#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) + if (!cma_is_registered_region(start, len)) { + pr_err("%s: %x@%x is allowed to map\n", + __func__, (unsigned int)start, + (unsigned int)len); + mutex_unlock(&info->mm_lock); + return -EINVAL; + } +#endif + if (off >= len) { /* memory mapped io */ off -= len; |