From 5ba40d2997b828fb5ef2b44f52e055afb4e1ac4f Mon Sep 17 00:00:00 2001 From: Deva Ramasubramanian Date: Tue, 31 Jul 2012 11:11:46 -0700 Subject: [PATCH] msm: video: wfd: Move domain specific mappings into subdevices Move the domain specific mappings into subdevices to abstract away iommu from wfd-ioctl.c. This is especially needed as the encoder subdevices for MSM8x60 and MSM8x74 differ in the iommu domain to which they map the buffer to. This target specific handling needs to taken care of by the respective subdevices rather than by wfd-ioctl which should be target agnostic. Signed-off-by: Deva Ramasubramanian Conflicts: drivers/media/video/msm_wfd/mdp-4-subdev.c Change-Id: I83b2cbcff2b86b0f9cce9844b1e3b1607f5881ca Signed-off-by: Neha Pandey --- drivers/media/video/msm_wfd/enc-mfc-subdev.c | 73 ++++++++++++ drivers/media/video/msm_wfd/enc-subdev.h | 10 ++ .../media/video/msm_wfd/enc-venus-subdev.c | 101 +++++++++++++++-- drivers/media/video/msm_wfd/mdp-4-subdev.c | 90 ++++++++++++++- drivers/media/video/msm_wfd/mdp-5-subdev.c | 57 ++++++++++ .../media/video/msm_wfd/mdp-dummy-subdev.c | 25 +++++ drivers/media/video/msm_wfd/mdp-subdev.h | 4 + drivers/media/video/msm_wfd/wfd-ioctl.c | 106 ++++++------------ 8 files changed, 384 insertions(+), 82 deletions(-) diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c index 820d21e586e..59973454316 100644 --- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c +++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c @@ -2311,6 +2311,73 @@ static long venc_get_property(struct v4l2_subdev *sd, void *arg) return rc; } +long venc_mmap(struct v4l2_subdev *sd, void *arg) +{ + struct venc_inst *inst = sd->dev_priv; + struct mem_region_map *mmap = arg; + struct mem_region *mregion = NULL; + unsigned long rc = 0, size = 0; + void *paddr = NULL; + + if (!sd) { + WFD_MSG_ERR("Subdevice required for %s\n", __func__); + return -EINVAL; + } else if (!mmap || !mmap->mregion) { + WFD_MSG_ERR("Memregion required for %s\n", __func__); + return -EINVAL; + } + + mregion = mmap->mregion; + if (mregion->size % SZ_4K != 0) { + WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K); + return -EINVAL; + } + + if (inst->secure) { + rc = ion_phys(mmap->ion_client, mregion->ion_handle, + (unsigned long *)&paddr, + (size_t *)&size); + } else { + rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle, + VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K, + 0, (unsigned long *)&paddr, + &size, 0, 0); + } + + if (rc) { + WFD_MSG_ERR("Failed to get physical addr\n"); + paddr = NULL; + } else if (size < mregion->size) { + WFD_MSG_ERR("Failed to map enough memory\n"); + rc = -ENOMEM; + } + + mregion->paddr = paddr; + return rc; +} + +long venc_munmap(struct v4l2_subdev *sd, void *arg) +{ + struct venc_inst *inst = sd->dev_priv; + struct mem_region_map *mmap = arg; + struct mem_region *mregion = NULL; + if (!sd) { + WFD_MSG_ERR("Subdevice required for %s\n", __func__); + return -EINVAL; + } else if (!mregion) { + WFD_MSG_ERR("Memregion required for %s\n", __func__); + return -EINVAL; + } + + mregion = mmap->mregion; + if (!inst->secure) { + ion_unmap_iommu(mmap->ion_client, mregion->ion_handle, + VIDEO_DOMAIN, VIDEO_MAIN_POOL); + } + + return 0; +} + long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { long rc = 0; @@ -2374,6 +2441,12 @@ long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case ENCODE_FLUSH: rc = venc_flush_buffers(sd, arg); break; + case ENC_MMAP: + rc = venc_mmap(sd, arg); + break; + case ENC_MUNMAP: + rc = venc_munmap(sd, arg); + break; default: rc = -1; break; diff --git a/drivers/media/video/msm_wfd/enc-subdev.h b/drivers/media/video/msm_wfd/enc-subdev.h index 6418af6da8f..c6c854ece9f 100644 --- a/drivers/media/video/msm_wfd/enc-subdev.h +++ b/drivers/media/video/msm_wfd/enc-subdev.h @@ -31,6 +31,14 @@ struct mem_region { struct ion_handle *ion_handle; }; +/* FIXME: need to come with a less stupid name */ +struct mem_region_map { + struct mem_region *mregion; + struct ion_client *ion_client; + uint32_t flags; + void *cookie; +}; + struct bufreq { u32 count; u32 height; @@ -91,6 +99,8 @@ static inline bool mem_region_equals(struct mem_region *a, #define FREE_INPUT_BUFFER _IOWR('V', 22, struct mem_region *) #define FREE_RECON_BUFFERS _IO('V', 23) #define ENCODE_FLUSH _IO('V', 24) +#define ENC_MMAP _IOWR('V', 25, struct mem_region_map *) +#define ENC_MUNMAP _IOWR('V', 26, struct mem_region_map *) extern int venc_init(struct v4l2_subdev *sd, u32 val); extern int venc_load_fw(struct v4l2_subdev *sd); diff --git a/drivers/media/video/msm_wfd/enc-venus-subdev.c b/drivers/media/video/msm_wfd/enc-venus-subdev.c index 47f4b1358a8..04e42f57ab7 100644 --- a/drivers/media/video/msm_wfd/enc-venus-subdev.c +++ b/drivers/media/video/msm_wfd/enc-venus-subdev.c @@ -245,6 +245,7 @@ static long venc_open(struct v4l2_subdev *sd, void *arg) struct venc_inst *inst = NULL; struct venc_msg_ops *vmops = arg; struct v4l2_event_subscription event = {0}; + struct msm_vidc_iommu_info maps[MAX_MAP]; int rc = 0; if (!vmops) { @@ -264,6 +265,7 @@ static long venc_open(struct v4l2_subdev *sd, void *arg) goto venc_open_fail; } + inst->secure = false; inst->vmops = *vmops; INIT_LIST_HEAD(&inst->registered_output_bufs.list); INIT_LIST_HEAD(&inst->registered_input_bufs.list); @@ -291,6 +293,15 @@ static long venc_open(struct v4l2_subdev *sd, void *arg) goto vidc_subscribe_fail; } + rc = msm_vidc_get_iommu_maps(inst->vidc_context, maps); + if (rc) { + WFD_MSG_ERR("Failed to retreive domain mappings\n"); + rc = -ENODATA; + goto vidc_subscribe_fail; + } + + inst->domain = maps[inst->secure ? CP_MAP : NS_MAP].domain; + inst->callback_thread = kthread_run(venc_vidc_callback_thread, inst, "venc_vidc_callback_thread"); if (IS_ERR(inst->callback_thread)) { @@ -580,7 +591,8 @@ set_input_buffer_fail: return rc; } -static int venc_map_user_to_kernel(struct mem_region *mregion) +static int venc_map_user_to_kernel(struct venc_inst *inst, + struct mem_region *mregion) { int rc = 0; unsigned long flags = 0, size = 0; @@ -589,7 +601,6 @@ static int venc_map_user_to_kernel(struct mem_region *mregion) goto venc_map_fail; } - mregion->ion_handle = ion_import_dma_buf(venc_ion_client, mregion->fd); if (IS_ERR_OR_NULL(mregion->ion_handle)) { rc = PTR_ERR(mregion->ion_handle); @@ -604,7 +615,7 @@ static int venc_map_user_to_kernel(struct mem_region *mregion) WFD_MSG_ERR("Failed to get ion flags %d\n", rc); goto venc_map_fail; } - /* TODO: skip for secure */ + mregion->kvaddr = ion_map_kernel(venc_ion_client, mregion->ion_handle, flags); @@ -616,8 +627,8 @@ static int venc_map_user_to_kernel(struct mem_region *mregion) } rc = ion_map_iommu(venc_ion_client, mregion->ion_handle, - VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K, - 0, (unsigned long *)&mregion->paddr, &size, flags, 0); + inst->domain, 0, SZ_4K, 0, + (unsigned long *)&mregion->paddr, &size, flags, 0); if (rc) { WFD_MSG_ERR("Failed to map into iommu\n"); @@ -630,21 +641,22 @@ static int venc_map_user_to_kernel(struct mem_region *mregion) return 0; venc_map_iommu_size_fail: ion_unmap_iommu(venc_ion_client, mregion->ion_handle, - VIDEO_DOMAIN, VIDEO_MAIN_POOL); + inst->domain, 0); venc_map_iommu_map_fail: ion_unmap_kernel(venc_ion_client, mregion->ion_handle); venc_map_fail: return rc; } -static int venc_unmap_user_to_kernel(struct mem_region *mregion) +static int venc_unmap_user_to_kernel(struct venc_inst *inst, + struct mem_region *mregion) { if (!mregion || !mregion->ion_handle) return 0; if (mregion->paddr) { ion_unmap_iommu(venc_ion_client, mregion->ion_handle, - VIDEO_DOMAIN, VIDEO_MAIN_POOL); + inst->domain, 0); mregion->paddr = NULL; } @@ -694,7 +706,7 @@ static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg) *mregion = *(struct mem_region *)arg; INIT_LIST_HEAD(&mregion->list); - rc = venc_map_user_to_kernel(mregion); + rc = venc_map_user_to_kernel(inst, mregion); if (rc) { WFD_MSG_ERR("Failed to map output buffer\n"); goto venc_set_output_buffer_map_fail; @@ -725,7 +737,7 @@ static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg) list_add_tail(&mregion->list, &inst->registered_output_bufs.list); return rc; venc_set_output_buffer_prepare_fail: - venc_unmap_user_to_kernel(mregion); + venc_unmap_user_to_kernel(inst, mregion); venc_set_output_buffer_map_fail: kfree(mregion); venc_set_output_buffer_fail: @@ -953,7 +965,7 @@ static long venc_free_buffer(struct venc_inst *inst, int type, } if (unmap_user_buffer) { - int rc = venc_unmap_user_to_kernel(mregion); + int rc = venc_unmap_user_to_kernel(inst, mregion); if (rc) WFD_MSG_WARN("Unable to unmap user buffer\n"); } @@ -1067,6 +1079,67 @@ static long venc_get_property(struct v4l2_subdev *sd, void *arg) return msm_vidc_g_ctrl(inst->vidc_context, (struct v4l2_control *)arg); } +long venc_mmap(struct v4l2_subdev *sd, void *arg) +{ + struct mem_region_map *mmap = arg; + struct mem_region *mregion = NULL; + unsigned long rc = 0, size = 0; + void *paddr = NULL; + struct venc_inst *inst = NULL; + + if (!sd) { + WFD_MSG_ERR("Subdevice required for %s\n", __func__); + return -EINVAL; + } else if (!mmap || !mmap->mregion) { + WFD_MSG_ERR("Memregion required for %s\n", __func__); + return -EINVAL; + } + + inst = (struct venc_inst *)sd->dev_priv; + mregion = mmap->mregion; + if (mregion->size % SZ_4K != 0) { + WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K); + return -EINVAL; + } + + rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle, + inst->domain, 0, SZ_4K, 0, (unsigned long *)&paddr, + &size, 0, 0); + + if (rc) { + WFD_MSG_ERR("Failed to get physical addr\n"); + paddr = NULL; + } else if (size < mregion->size) { + WFD_MSG_ERR("Failed to map enough memory\n"); + rc = -ENOMEM; + } + + mregion->paddr = paddr; + return rc; +} + +long venc_munmap(struct v4l2_subdev *sd, void *arg) +{ + struct mem_region_map *mmap = arg; + struct mem_region *mregion = NULL; + struct venc_inst *inst = NULL; + + if (!sd) { + WFD_MSG_ERR("Subdevice required for %s\n", __func__); + return -EINVAL; + } else if (!mmap || !mmap->mregion) { + WFD_MSG_ERR("Memregion required for %s\n", __func__); + return -EINVAL; + } + + inst = (struct venc_inst *)sd->dev_priv; + mregion = mmap->mregion; + + ion_unmap_iommu(mmap->ion_client, mregion->ion_handle, + inst->domain, 0); + return 0; +} + long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { long rc = 0; @@ -1130,6 +1203,12 @@ long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case ENCODE_FLUSH: rc = venc_flush_buffers(sd, arg); break; + case ENC_MMAP: + rc = venc_mmap(sd, arg); + break; + case ENC_MUNMAP: + rc = venc_munmap(sd, arg); + break; default: WFD_MSG_ERR("Unknown ioctl %d to enc-subdev\n", cmd); rc = -ENOTSUPP; diff --git a/drivers/media/video/msm_wfd/mdp-4-subdev.c b/drivers/media/video/msm_wfd/mdp-4-subdev.c index fb0c99993bf..dc052dec634 100644 --- a/drivers/media/video/msm_wfd/mdp-4-subdev.c +++ b/drivers/media/video/msm_wfd/mdp-4-subdev.c @@ -10,10 +10,12 @@ * GNU General Public License for more details. * */ +#include +#include +#include +#include "enc-subdev.h" #include "mdp-subdev.h" #include "wfd-util.h" -#include -#include #include struct mdp_instance { @@ -29,6 +31,7 @@ int mdp_init(struct v4l2_subdev *sd, u32 val) { return 0; } + int mdp_open(struct v4l2_subdev *sd, void *arg) { struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance), @@ -189,6 +192,83 @@ int mdp_set_prop(struct v4l2_subdev *sd, void *arg) return 0; } +int mdp_mmap(struct v4l2_subdev *sd, void *arg) +{ + int rc = 0, domain = -1; + struct mem_region_map *mmap = arg; + struct mem_region *mregion; + bool use_iommu = true; + struct mdp_instance *inst = NULL; + + if (!mmap || !mmap->mregion || !mmap->cookie) { + WFD_MSG_ERR("Invalid argument\n"); + return -EINVAL; + } + + inst = mmap->cookie; + mregion = mmap->mregion; + if (mregion->size % SZ_4K != 0) { + WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K); + return -EINVAL; + } + + if (inst->uses_iommu_split_domain) { + if (inst->secure) + use_iommu = false; + else + domain = DISPLAY_WRITE_DOMAIN; + } else { + domain = DISPLAY_READ_DOMAIN; + } + + if (use_iommu) { + rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle, + domain, GEN_POOL, SZ_4K, 0, + (unsigned long *)&mregion->paddr, + (unsigned long *)&mregion->size, + 0, 0); + } else { + rc = ion_phys(mmap->ion_client, mregion->ion_handle, + (unsigned long *)&mregion->paddr, + (size_t *)&mregion->size); + } + + return rc; +} + +int mdp_munmap(struct v4l2_subdev *sd, void *arg) +{ + struct mem_region_map *mmap = arg; + struct mem_region *mregion; + bool use_iommu = false; + int domain = -1; + struct mdp_instance *inst = NULL; + + if (!mmap || !mmap->mregion || !mmap->cookie) { + WFD_MSG_ERR("Invalid argument\n"); + return -EINVAL; + } + + inst = mmap->cookie; + mregion = mmap->mregion; + + if (inst->uses_iommu_split_domain) { + if (inst->secure) + use_iommu = false; + else + domain = DISPLAY_WRITE_DOMAIN; + } else { + domain = DISPLAY_READ_DOMAIN; + } + + if (use_iommu) + ion_unmap_iommu(mmap->ion_client, + mregion->ion_handle, + domain, GEN_POOL); + + return 0; +} + long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { int rc = 0; @@ -218,6 +298,12 @@ long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case MDP_CLOSE: rc = mdp_close(sd, arg); break; + case MDP_MMAP: + rc = mdp_mmap(sd, arg); + break; + case MDP_MUNMAP: + rc = mdp_munmap(sd, arg); + break; default: WFD_MSG_ERR("IOCTL: %u not supported\n", cmd); rc = -EINVAL; diff --git a/drivers/media/video/msm_wfd/mdp-5-subdev.c b/drivers/media/video/msm_wfd/mdp-5-subdev.c index e80efde7939..40837eb5472 100644 --- a/drivers/media/video/msm_wfd/mdp-5-subdev.c +++ b/drivers/media/video/msm_wfd/mdp-5-subdev.c @@ -191,6 +191,57 @@ int mdp_set_prop(struct v4l2_subdev *sd, void *arg) return 0; } +int mdp_mmap(struct v4l2_subdev *sd, void *arg) +{ + int rc = 0; + struct mem_region_map *mmap = arg; + struct mem_region *mregion; + bool domain = -1; + struct mdp_instance *inst = NULL; + + if (!mmap || !mmap->mregion || !mmap->cookie) { + WFD_MSG_ERR("Invalid argument\n"); + return -EINVAL; + } + + inst = mmap->cookie; + mregion = mmap->mregion; + if (mregion->size % SZ_4K != 0) { + WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K); + return -EINVAL; + } + + domain = msm_fb_get_iommu_domain(); + rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle, + domain, 0, SZ_4K, 0, + (unsigned long *)&mregion->paddr, + (unsigned long *)&mregion->size, + 0, 0); + return rc; +} + +int mdp_munmap(struct v4l2_subdev *sd, void *arg) +{ + struct mem_region_map *mmap = arg; + struct mem_region *mregion; + bool domain = -1; + struct mdp_instance *inst = NULL; + + if (!mmap || !mmap->mregion || !mmap->cookie) { + WFD_MSG_ERR("Invalid argument\n"); + return -EINVAL; + } + + inst = mmap->cookie; + mregion = mmap->mregion; + + domain = msm_fb_get_iommu_domain(); + ion_unmap_iommu(mmap->ion_client, + mregion->ion_handle, + domain, 0); + return 0; +} + long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { int rc = 0; @@ -220,6 +271,12 @@ long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case MDP_CLOSE: rc = mdp_close(sd, arg); break; + case MDP_MMAP: + rc = mdp_mmap(sd, arg); + break; + case MDP_MUNMAP: + rc = mdp_munmap(sd, arg); + break; default: WFD_MSG_ERR("IOCTL: %u not supported\n", cmd); rc = -EINVAL; diff --git a/drivers/media/video/msm_wfd/mdp-dummy-subdev.c b/drivers/media/video/msm_wfd/mdp-dummy-subdev.c index 7ccbd729707..b2db2084afd 100644 --- a/drivers/media/video/msm_wfd/mdp-dummy-subdev.c +++ b/drivers/media/video/msm_wfd/mdp-dummy-subdev.c @@ -14,6 +14,7 @@ #include #include +#include "enc-subdev.h" #include "mdp-subdev.h" #include "wfd-util.h" @@ -124,6 +125,24 @@ int mdp_set_prop(struct v4l2_subdev *sd, void *arg) { return 0; } + +int mdp_mmap(struct v4l2_subdev *sd, void *arg) +{ + int rc = 0; + struct mem_region_map *mmap = arg; + struct mem_region *mregion; + + mregion = mmap->mregion; + mregion->paddr = mregion->kvaddr; + return rc; +} + +int mdp_munmap(struct v4l2_subdev *sd, void *arg) +{ + /* Whatever */ + return 0; +} + long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { int rc = 0; @@ -153,6 +172,12 @@ long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case MDP_CLOSE: rc = mdp_close(sd, arg); break; + case MDP_MMAP: + rc = mdp_mmap(sd, arg); + break; + case MDP_MUNMAP: + rc = mdp_munmap(sd, arg); + break; default: WFD_MSG_ERR("IOCTL: %u not supported\n", cmd); rc = -EINVAL; diff --git a/drivers/media/video/msm_wfd/mdp-subdev.h b/drivers/media/video/msm_wfd/mdp-subdev.h index 4e8da3f0180..5e81e3cbfac 100644 --- a/drivers/media/video/msm_wfd/mdp-subdev.h +++ b/drivers/media/video/msm_wfd/mdp-subdev.h @@ -57,6 +57,10 @@ static inline bool mdp_buf_info_equals(struct mdp_buf_info *a, #define MDP_CLOSE _IOR(MDP_MAGIC_IOCTL, 5, void *) #define MDP_START _IOR(MDP_MAGIC_IOCTL, 6, void *) #define MDP_STOP _IOR(MDP_MAGIC_IOCTL, 7, void *) +#define MDP_MMAP _IOR(MDP_MAGIC_IOCTL, 8, struct mem_region_map *) +#define MDP_MUNMAP _IOR(MDP_MAGIC_IOCTL, 9, struct mem_region_map *) + + extern int mdp_init(struct v4l2_subdev *sd, u32 val); extern long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg); diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c index d72dd08e5c3..23af7e94987 100644 --- a/drivers/media/video/msm_wfd/wfd-ioctl.c +++ b/drivers/media/video/msm_wfd/wfd-ioctl.c @@ -151,11 +151,10 @@ static unsigned long wfd_enc_addr_to_mdp_addr(struct wfd_inst *inst, static int wfd_allocate_ion_buffer(struct ion_client *client, bool secure, struct mem_region *mregion) { - struct ion_handle *handle; - void *kvaddr = NULL, *phys_addr = NULL; - unsigned long size; + struct ion_handle *handle = NULL; + void *kvaddr = NULL; unsigned int alloc_regions = 0; - int rc; + int rc = 0; alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID); alloc_regions |= secure ? ION_SECURE : @@ -177,32 +176,7 @@ static int wfd_allocate_ion_buffer(struct ion_client *client, goto alloc_fail; } - if (secure) { - WFD_MSG_INFO("%s: calling ion_phys", __func__); - rc = ion_phys(client, - handle, - (unsigned long *)&phys_addr, (size_t *)&size); - } else { - WFD_MSG_INFO("%s: calling ion_map_iommu", __func__); - rc = ion_map_iommu(client, handle, - VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K, - 0, (unsigned long *)&phys_addr, - &size, 0, 0); - } - - if (rc || !phys_addr) { - WFD_MSG_ERR( - "Failed to get physical addr, rc = %d, phys_addr = 0x%p\n", - rc, phys_addr); - goto alloc_fail; - } else if (size < mregion->size) { - WFD_MSG_ERR("Failed to map enough memory\n"); - rc = -ENOMEM; - goto alloc_fail; - } - mregion->kvaddr = kvaddr; - mregion->paddr = phys_addr; mregion->ion_handle = handle; return rc; @@ -272,6 +246,7 @@ int wfd_allocate_input_buffers(struct wfd_device *wfd_dev, spin_unlock_irqrestore(&inst->inst_lock, flags); for (i = 0; i < VENC_INPUT_BUFFERS; ++i) { + struct mem_region_map mmap_context = {0}; mpair = kzalloc(sizeof(*mpair), GFP_KERNEL); enc_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL); mdp_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL); @@ -280,12 +255,20 @@ int wfd_allocate_input_buffers(struct wfd_device *wfd_dev, rc = wfd_allocate_ion_buffer(wfd_dev->ion_client, wfd_dev->secure_device, enc_mregion); if (rc) { - WFD_MSG_ERR("Failed to allocate input memory." - " This error causes memory leak!!!\n"); + WFD_MSG_ERR("Failed to allocate input memory\n"); goto alloc_fail; } - WFD_MSG_DBG("NOTE: enc paddr = %p, kvaddr = %p\n", + mmap_context.mregion = enc_mregion; + mmap_context.ion_client = wfd_dev->ion_client; + rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, + ENC_MMAP, &mmap_context); + if (rc || !enc_mregion->paddr) { + WFD_MSG_ERR("Failed to map input memory\n"); + goto alloc_fail; + } + + WFD_MSG_ERR("NOTE: enc paddr = %p, kvaddr = %p\n", enc_mregion->paddr, enc_mregion->kvaddr); @@ -300,27 +283,12 @@ int wfd_allocate_input_buffers(struct wfd_device *wfd_dev, mdp_mregion->cookie = 0; mdp_mregion->ion_handle = enc_mregion->ion_handle; - if (wfd_dev->mdp_iommu_split_domain) { - if (wfd_dev->secure_device) { - rc = ion_phys(wfd_dev->ion_client, - mdp_mregion->ion_handle, - (unsigned long *)&mdp_mregion->paddr, - (size_t *)&mdp_mregion->size); - } else { - rc = ion_map_iommu(wfd_dev->ion_client, - mdp_mregion->ion_handle, - DISPLAY_WRITE_DOMAIN, GEN_POOL, SZ_4K, - 0, (unsigned long *)&mdp_mregion->paddr, - (unsigned long *)&mdp_mregion->size, - 0, 0); - } - } else { - rc = ion_map_iommu(wfd_dev->ion_client, - mdp_mregion->ion_handle, - DISPLAY_READ_DOMAIN, GEN_POOL, SZ_4K, - 0, (unsigned long *)&mdp_mregion->paddr, - (unsigned long *)&mdp_mregion->size, 0, 0); - } + memset(&mmap_context, 0, sizeof(mmap_context)); + mmap_context.mregion = mdp_mregion; + mmap_context.ion_client = wfd_dev->ion_client; + mmap_context.cookie = inst->mdp_inst; + rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, + MDP_MMAP, (void *)&mmap_context); if (rc || !mdp_mregion->paddr) { WFD_MSG_ERR( @@ -400,24 +368,24 @@ void wfd_free_input_buffers(struct wfd_device *wfd_dev, "from encoder\n"); if (mpair->mdp->paddr) { - if (wfd_dev->mdp_iommu_split_domain) { - if (!wfd_dev->secure_device) - ion_unmap_iommu(wfd_dev-> - ion_client, - mpair->mdp->ion_handle, - DISPLAY_WRITE_DOMAIN, - GEN_POOL); - } else { - ion_unmap_iommu(wfd_dev->ion_client, - mpair->mdp->ion_handle, - DISPLAY_READ_DOMAIN, GEN_POOL); - } + struct mem_region_map temp = {0}; + + temp.ion_client = wfd_dev->ion_client; + temp.mregion = mpair->mdp; + temp.cookie = inst->mdp_inst; + + v4l2_subdev_call(&wfd_dev->mdp_sdev, core, + ioctl, MDP_MUNMAP, + (void *)&temp); } - if (mpair->enc->paddr && !wfd_dev->secure_device) - ion_unmap_iommu(wfd_dev->ion_client, - mpair->enc->ion_handle, - VIDEO_DOMAIN, VIDEO_MAIN_POOL); + if (mpair->enc->paddr) { + struct mem_region_map temp = {0}; + temp.ion_client = wfd_dev->ion_client; + temp.mregion = mpair->enc; + v4l2_subdev_call(&wfd_dev->enc_sdev, + core, ioctl, ENC_MUNMAP, &temp); + } wfd_free_ion_buffer(wfd_dev->ion_client, mpair->enc); list_del(&mpair->list);