void ddl_pmem_free(struct ddl_buf_addr *addr) { struct ddl_context *ddl_context; ddl_context = ddl_get_context(); if (!addr) { pr_err("%s() invalid args\n", __func__); return; } if (ddl_context->video_ion_client) { if (!IS_ERR_OR_NULL(addr->alloc_handle)) { ion_unmap_kernel(ddl_context->video_ion_client, addr->alloc_handle); if (!res_trk_check_for_sec_session()) { ion_unmap_iommu(ddl_context->video_ion_client, addr->alloc_handle, VIDEO_DOMAIN, VIDEO_MAIN_POOL); } ion_free(ddl_context->video_ion_client, addr->alloc_handle); } } else { if (addr->mapped_buffer) msm_subsystem_unmap_buffer(addr->mapped_buffer); if (addr->alloced_phys_addr) free_contiguous_memory_by_paddr( (unsigned long)addr->alloced_phys_addr); } memset(addr, 0, sizeof(struct ddl_buf_addr)); }
void camera_free_ion_handle(struct ion_client *ion_client, buffer_arr_t *pbuf) { int i = 0; print_info("enter %s.", __func__); if((NULL == ion_client) || (NULL == pbuf)){ print_error("%s:ion_client=%p,pbuf=%p.", __func__,ion_client,pbuf); return; } /* release ion handle */ for (i = 0; i < pbuf->buf_count; i++) { if(pbuf->buffers[i].viraddr != NULL){ ion_unmap_kernel(ion_client, pbuf->buffers[i].ion_handle); print_info("unmap kernel handle=%p success",pbuf->buffers[i].ion_handle); pbuf->buffers[i].viraddr = NULL; } ion_unmap_iommu(ion_client, pbuf->buffers[i].ion_handle); print_info("unmap iommu handle=%p success",pbuf->buffers[i].ion_handle); if(pbuf->buffers[i].ion_handle != NULL){ print_info("%s:ion_client=%p,i=%d,handle=%p.", __func__,ion_client,i,pbuf->buffers[i].ion_handle); ion_free(ion_client, pbuf->buffers[i].ion_handle); print_info("ion free handle=%p success",pbuf->buffers[i].ion_handle); pbuf->buffers[i].ion_handle = NULL; } } }
static void put_device_address(struct smem_client *smem_client, struct ion_handle *hndl, int domain_num, int partition_num, u32 flags) { struct ion_client *clnt = NULL; if (!hndl || !smem_client) { dprintk(VIDC_WARN, "Invalid params: %p, %p\n", smem_client, hndl); return; } clnt = smem_client->clnt; if (!clnt) { dprintk(VIDC_WARN, "Invalid client"); return; } if (is_iommu_present(smem_client->res)) { dprintk(VIDC_DBG, "Calling ion_unmap_iommu - domain: %d, parition: %d", domain_num, partition_num); ion_unmap_iommu(clnt, hndl, domain_num, partition_num); } if (flags & SMEM_SECURE) { if (msm_ion_unsecure_buffer(clnt, hndl)) dprintk(VIDC_ERR, "Failed to unsecure memory\n"); } }
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; }
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem, struct ion_client *client, int domain_num) { if (mem->is_userptr) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION if (IS_ERR_OR_NULL(mem->ion_handle)) { pr_err("%s ION import failed\n", __func__); return; } #if !defined(CONFIG_MSM_IOMMU) #if defined(CACHABLE_MEMORY) ion_unmap_kernel(client, mem->ion_handle); #endif #else ion_unmap_iommu(client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL); #endif ion_free(client, mem->ion_handle); #elif CONFIG_ANDROID_PMEM put_pmem_file(mem->file); #endif } mem->is_userptr = 0; mem->phyaddr = 0; mem->size = 0; mem->mapped_phyaddr = 0; }
static int mdp_munmap(struct v4l2_subdev *sd, void *arg) { struct mem_region_map *mmap = arg; struct mem_region *mregion; 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; msm_fb_writeback_iommu_ref(inst->mdp, true); domain = msm_fb_get_iommu_domain(inst->mdp, inst->secure ? MDP_IOMMU_DOMAIN_CP : MDP_IOMMU_DOMAIN_NS); ion_unmap_iommu(mmap->ion_client, mregion->ion_handle, domain, 0); if (inst->secure) msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle); msm_fb_writeback_iommu_ref(inst->mdp, false); return 0; }
void msm_gemini_platform_p2v(struct file *file, struct ion_handle **ionhandle) { ion_unmap_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL); ion_free(gemini_client, *ionhandle); *ionhandle = NULL; }
void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file, struct ion_handle **ionhandle, int domain_num) { ion_unmap_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0); ion_free(pgmn_dev->jpeg_client, *ionhandle); *ionhandle = NULL; }
static unsigned long msm_vpe_queue_buffer_info(struct vpe_device *vpe_dev, struct msm_vpe_buff_queue_info_t *buff_queue, struct msm_vpe_buffer_info_t *buffer_info) { struct list_head *buff_head; struct msm_vpe_buffer_map_list_t *buff, *save; int rc = 0; if (buffer_info->native_buff) buff_head = &buff_queue->native_buff_head; else buff_head = &buff_queue->vb2_buff_head; list_for_each_entry_safe(buff, save, buff_head, entry) { if (buff->map_info.buff_info.index == buffer_info->index) { pr_err("error buffer index already queued\n"); return -EINVAL; } } buff = kzalloc( sizeof(struct msm_vpe_buffer_map_list_t), GFP_KERNEL); if (!buff) { pr_err("error allocating memory\n"); return -EINVAL; } buff->map_info.buff_info = *buffer_info; buff->map_info.ion_handle = ion_import_dma_buf(vpe_dev->client, buffer_info->fd); if (IS_ERR_OR_NULL(buff->map_info.ion_handle)) { pr_err("ION import failed\n"); goto queue_buff_error1; } rc = ion_map_iommu(vpe_dev->client, buff->map_info.ion_handle, vpe_dev->domain_num, 0, SZ_4K, 0, (unsigned long *)&buff->map_info.phy_addr, &buff->map_info.len, 0, 0); if (rc < 0) { pr_err("ION mmap failed\n"); goto queue_buff_error2; } INIT_LIST_HEAD(&buff->entry); list_add_tail(&buff->entry, buff_head); return buff->map_info.phy_addr; queue_buff_error2: ion_unmap_iommu(vpe_dev->client, buff->map_info.ion_handle, vpe_dev->domain_num, 0); queue_buff_error1: ion_free(vpe_dev->client, buff->map_info.ion_handle); buff->map_info.ion_handle = NULL; kzfree(buff); return 0; }
void msm_gemini_platform_p2v(struct file *file, struct ion_handle **ionhandle) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL); ion_free(gemini_client, *ionhandle); *ionhandle = NULL; #endif }
void msm_mercury_platform_p2v(struct file *file, struct ion_handle **ionhandle) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(mercury_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL); ion_free(mercury_client, *ionhandle); *ionhandle = NULL; #elif CONFIG_ANDROID_PMEM put_pmem_file(file); #endif }
static int32_t msm_mem_free(struct videobuf2_contig_pmem *mem) { int32_t rc = 0; #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(mem->client, mem->ion_handle, -1, 0); ion_free(mem->client, mem->ion_handle); ion_client_destroy(mem->client); #else free_contiguous_memory_by_paddr(mem->phyaddr); #endif return rc; }
static void msm_vpe_dequeue_buffer_info(struct vpe_device *vpe_dev, struct msm_vpe_buffer_map_list_t *buff) { ion_unmap_iommu(vpe_dev->client, buff->map_info.ion_handle, vpe_dev->domain_num, 0); ion_free(vpe_dev->client, buff->map_info.ion_handle); buff->map_info.ion_handle = NULL; list_del_init(&buff->entry); kzfree(buff); return; }
static int __msm_pmem_table_del(struct hlist_head *ptype, struct msm_pmem_info *pinfo, struct ion_client *client, int domain_num) { int rc = 0; struct msm_pmem_region *region; struct hlist_node *node, *n; switch (pinfo->type) { case MSM_PMEM_AF: case MSM_PMEM_AEC: case MSM_PMEM_AWB: case MSM_PMEM_RS: case MSM_PMEM_CS: case MSM_PMEM_IHIST: case MSM_PMEM_SKIN: case MSM_PMEM_AEC_AWB: case MSM_PMEM_BAYER_GRID: case MSM_PMEM_BAYER_FOCUS: case MSM_PMEM_BAYER_HIST: hlist_for_each_entry_safe(region, node, n, ptype, list) { if (pinfo->type == region->info.type && pinfo->vaddr == region->info.vaddr && pinfo->fd == region->info.fd) { hlist_del(node); #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(client, region->handle, domain_num, 0); // pr_err("%s: IOMMU unmapping address 0x%x\n", __func__, (unsigned int)region->paddr); // ion_free(client, region->handle); #endif kfree(region); } } break; default: rc = -EINVAL; break; } return rc; }
static int __msm_pmem_table_del(struct hlist_head *ptype, struct msm_pmem_info *pinfo, struct ion_client *client) { int rc = 0; struct msm_pmem_region *region; struct hlist_node *node, *n; switch (pinfo->type) { case MSM_PMEM_AF: case MSM_PMEM_AEC: case MSM_PMEM_AWB: case MSM_PMEM_RS: case MSM_PMEM_CS: case MSM_PMEM_IHIST: case MSM_PMEM_SKIN: case MSM_PMEM_AEC_AWB: //QCT - BAYER STATS - MB case MSM_PMEM_BAYER_GRID: case MSM_PMEM_BAYER_FOCUS: case MSM_PMEM_BAYER_HIST: //QCT - BAYER STATS - ME hlist_for_each_entry_safe(region, node, n, ptype, list) { if (pinfo->type == region->info.type && pinfo->vaddr == region->info.vaddr && pinfo->fd == region->info.fd) { hlist_del(node); #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL); ion_free(client, region->handle); #else put_pmem_file(region->file); #endif kfree(region); } } break; default: rc = -EINVAL; break; } return rc; }
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem, struct ion_client *client, int domain_num) { if (mem->is_userptr) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(client, mem->ion_handle, domain_num, 0); ion_free(client, mem->ion_handle); #elif CONFIG_ANDROID_PMEM put_pmem_file(mem->file); #endif } mem->is_userptr = 0; mem->phyaddr = 0; mem->size = 0; mem->mapped_phyaddr = 0; }
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem, struct ion_client *client) { if (mem->is_userptr) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_kernel(client, mem->ion_handle); ion_unmap_iommu(client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL); ion_free(client, mem->ion_handle); #elif CONFIG_ANDROID_PMEM put_pmem_file(mem->file); #endif } mem->is_userptr = 0; mem->phyaddr = 0; mem->size = 0; mem->mapped_phyaddr = 0; }
static int __msm_pmem_table_del(struct hlist_head *ptype, struct msm_pmem_info *pinfo, struct ion_client *client) { int rc = 0; struct msm_pmem_region *region; struct hlist_node *node, *n; switch (pinfo->type) { case MSM_PMEM_AF: case MSM_PMEM_AEC: case MSM_PMEM_AWB: case MSM_PMEM_RS: case MSM_PMEM_CS: case MSM_PMEM_IHIST: case MSM_PMEM_SKIN: case MSM_PMEM_AEC_AWB: hlist_for_each_entry_safe(region, node, n, ptype, list) { if (pinfo->type == region->info.type && pinfo->vaddr == region->info.vaddr && pinfo->fd == region->info.fd) { hlist_del(node); #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL); pr_err("%s: IOMMU unmapping address 0x%x\n", __func__, (unsigned int)region->paddr); //QCT patch, Fix_IOMMU_and_VFE_bus_overflow, 2012-10-31, freeso.kim ion_free(client, region->handle); #else put_pmem_file(region->file); #endif kfree(region); } } break; default: rc = -EINVAL; break; } return rc; }
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem, struct ion_client *client, int domain_num) { if (mem->is_userptr) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION if (IS_ERR_OR_NULL(mem->ion_handle)) { pr_err("%s ION import failed\n", __func__); return; } ion_unmap_iommu(client, mem->ion_handle, domain_num, 0); ion_free(client, mem->ion_handle); #elif CONFIG_ANDROID_PMEM put_pmem_file(mem->file); #endif } mem->is_userptr = 0; mem->phyaddr = 0; mem->size = 0; mem->mapped_phyaddr = 0; }
void msm_gemini_platform_p2v(struct file *file, #if !defined(CONFIG_MSM_IOMMU) struct msm_mapped_buffer **msm_buffer, #endif struct ion_handle **ionhandle) { #if !defined(CONFIG_MSM_IOMMU) if (msm_subsystem_unmap_buffer( (struct msm_mapped_buffer *)*msm_buffer) < 0) pr_err("%s: umapped stat memory\n", __func__); *msm_buffer = NULL; #endif #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION #if defined(CONFIG_MSM_IOMMU) ion_unmap_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL); #endif ion_free(gemini_client, *ionhandle); *ionhandle = NULL; #elif CONFIG_ANDROID_PMEM put_pmem_file(file); #endif }
static void res_trk_pmem_unmap(struct ddl_buf_addr *addr) { if (!addr) { pr_err("%s() invalid args\n", __func__); return; } if (!IS_ERR_OR_NULL(addr->alloc_handle)) { if (addr->physical_base_addr) { ion_unmap_kernel(resource_context.res_ion_client, addr->alloc_handle); if (!res_trk_check_for_sec_session()) { ion_unmap_iommu(resource_context.res_ion_client, addr->alloc_handle, VIDEO_DOMAIN, VIDEO_FIRMWARE_POOL); } addr->virtual_base_addr = NULL; addr->physical_base_addr = NULL; } } else if (addr->mapped_buffer) msm_subsystem_unmap_buffer(addr->mapped_buffer); addr->mapped_buffer = NULL; }
int mdss_mdp_put_img(struct mdss_mdp_img_data *data) { struct ion_client *iclient = mdss_get_ionclient(); if (data->flags & MDP_MEMORY_ID_TYPE_FB) { pr_debug("fb mem buf=0x%x\n", data->addr); fput_light(data->srcp_file, data->p_need); data->srcp_file = NULL; } else if (data->srcp_file) { pr_debug("pmem buf=0x%x\n", data->addr); data->srcp_file = NULL; } else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) { pr_debug("ion hdl=%p buf=0x%x\n", data->srcp_ihdl, data->addr); if (is_mdss_iommu_attached()) { int domain; if (data->flags & MDP_SECURE_OVERLAY_SESSION) domain = MDSS_IOMMU_DOMAIN_SECURE; else domain = MDSS_IOMMU_DOMAIN_UNSECURE; ion_unmap_iommu(iclient, data->srcp_ihdl, mdss_get_iommu_domain(domain), 0); if (domain == MDSS_IOMMU_DOMAIN_SECURE) { msm_ion_unsecure_buffer(iclient, data->srcp_ihdl); mdss_mdp_secure_vote(0); } } ion_free(iclient, data->srcp_ihdl); data->srcp_ihdl = NULL; } else { return -ENOMEM; } return 0; }
void ddl_pmem_free(struct ddl_buf_addr *addr) { struct ddl_context *ddl_context; ddl_context = ddl_get_context(); if (!addr) { pr_err("%s() invalid args\n", __func__); return; } if (ddl_context->video_ion_client) { if (!IS_ERR_OR_NULL(addr->alloc_handle)) { ion_unmap_kernel(ddl_context->video_ion_client, addr->alloc_handle); if (!res_trk_check_for_sec_session()) { ion_unmap_iommu(ddl_context->video_ion_client, addr->alloc_handle, VIDEO_DOMAIN, VIDEO_MAIN_POOL); } ion_free(ddl_context->video_ion_client, addr->alloc_handle); } } memset(addr, 0, sizeof(struct ddl_buf_addr)); }
static int msm_pmem_table_add(struct hlist_head *ptype, struct msm_pmem_info *info, struct ion_client *client, int domain_num) { unsigned long paddr; #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION unsigned long kvstart; struct file *file; #endif int rc = -ENOMEM; unsigned long len; struct msm_pmem_region *region; region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL); if (!region) goto out; #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION region->handle = ion_import_dma_buf(client, info->fd); if (IS_ERR_OR_NULL(region->handle)) goto out1; if (ion_map_iommu(client, region->handle, domain_num, 0, SZ_4K, 0, &paddr, &len, 0, 0) < 0) goto out2; // pr_err("%s: IOMMU mapped address is 0x%x\n", __func__, (unsigned int)paddr); // #else paddr = 0; file = NULL; kvstart = 0; #endif if (!info->len) info->len = len; paddr += info->offset; len = info->len; if (check_overlap(ptype, paddr, len) < 0) { rc = -EINVAL; goto out3; } CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n", __func__, info->type, info->active, paddr, (unsigned long)info->vaddr); INIT_HLIST_NODE(®ion->list); region->paddr = paddr; region->len = len; memcpy(®ion->info, info, sizeof(region->info)); D("%s Adding region to list with type %d\n", __func__, region->info.type); D("%s pmem_stats address is 0x%p\n", __func__, ptype); hlist_add_head(&(region->list), ptype); return 0; out3: #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(client, region->handle, domain_num, 0); #endif #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION out2: ion_free(client, region->handle); #endif out1: kfree(region); out: return rc; }
static void put_device_address(struct ion_client *clnt, struct ion_handle *hndl, int domain_num, int partition_num) { ion_unmap_iommu(clnt, hndl, domain_num, partition_num); }
static int msm_pmem_table_add(struct hlist_head *ptype, struct msm_pmem_info *info, struct ion_client *client) { unsigned long paddr; #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION unsigned long kvstart; struct file *file; #endif int rc = -ENOMEM; unsigned long len; struct msm_pmem_region *region; region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL); if (!region) goto out; #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION region->handle = ion_import_fd(client, info->fd); if (IS_ERR_OR_NULL(region->handle)) goto out1; if (ion_map_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL, SZ_4K, 0, &paddr, &len, UNCACHED, 0) < 0) goto out2; #elif CONFIG_ANDROID_PMEM rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file); if (rc < 0) { pr_err("%s: get_pmem_file fd %d error %d\n", __func__, info->fd, rc); goto out1; } region->file = file; #else paddr = 0; file = NULL; kvstart = 0; #endif if (!info->len) info->len = len; rc = check_pmem_info(info, len); if (rc < 0) goto out3; paddr += info->offset; len = info->len; if (check_overlap(ptype, paddr, len) < 0) { rc = -EINVAL; goto out3; } CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n", __func__, info->type, info->active, paddr, (unsigned long)info->vaddr); INIT_HLIST_NODE(®ion->list); region->paddr = paddr; region->len = len; memcpy(®ion->info, info, sizeof(region->info)); D("%s Adding region to list with type %d\n", __func__, region->info.type); D("%s pmem_stats address is 0x%p\n", __func__, ptype); hlist_add_head(&(region->list), ptype); return 0; out3: #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_unmap_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL); #endif #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION out2: ion_free(client, region->handle); #elif CONFIG_ANDROID_PMEM put_pmem_file(region->file); #endif out1: kfree(region); out: return rc; }
void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment) { u32 alloc_size, offset = 0 ; u32 index = 0; struct ddl_context *ddl_context; struct msm_mapped_buffer *mapped_buffer = NULL; unsigned long iova = 0; unsigned long buffer_size = 0; unsigned long *kernel_vaddr = NULL; unsigned long ionflag = 0; unsigned long flags = 0; int ret = 0; DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); if (!addr) { DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__); goto bail_out; } ddl_context = ddl_get_context(); #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION res_trk_set_mem_type(addr->mem_type); #endif alloc_size = (sz + alignment); alloc_size = (alloc_size+4095) & ~4095; if (res_trk_get_enable_ion()) { if (!ddl_context->video_ion_client) ddl_context->video_ion_client = res_trk_get_ion_client(); if (!ddl_context->video_ion_client) { DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n", __func__); goto bail_out; } addr->alloc_handle = ion_alloc( ddl_context->video_ion_client, alloc_size, SZ_4K, res_trk_get_mem_type()); if (IS_ERR_OR_NULL(addr->alloc_handle)) { DDL_MSG_ERROR("%s() :DDL ION alloc failed\n", __func__); goto bail_out; } if (res_trk_check_for_sec_session() || addr->mem_type == DDL_FW_MEM) ionflag = UNCACHED; else ionflag = CACHED; kernel_vaddr = (unsigned long *) ion_map_kernel( ddl_context->video_ion_client, addr->alloc_handle, ionflag); if (!kernel_vaddr) { DDL_MSG_ERROR("%s() :DDL ION map failed\n", __func__); goto free_acm_ion_alloc; } addr->virtual_base_addr = (u8 *) kernel_vaddr; if (ion_handle_get_flags(ddl_context->video_ion_client, addr->alloc_handle, &ionflag)) { DDL_MSG_ERROR("%s():DDL ION get flag failed\n", __func__); goto free_acm_ion_alloc; } ret = ion_map_iommu(ddl_context->video_ion_client, addr->alloc_handle, VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K, 0, &iova, &buffer_size, UNCACHED, 0); if (ret) { DDL_MSG_ERROR("%s():DDL ION ion map iommu failed\n", __func__); goto free_acm_ion_alloc; } addr->alloced_phys_addr = (phys_addr_t) iova; if (!addr->alloced_phys_addr) { DDL_MSG_ERROR("%s():DDL ION client physical failed\n", __func__); goto free_acm_ion_alloc; } addr->mapped_buffer = 0; addr->physical_base_addr = (u8 *) iova; addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) addr->physical_base_addr, alignment); offset = (u32)(addr->align_physical_addr - addr->physical_base_addr); addr->align_virtual_addr = addr->virtual_base_addr + offset; addr->buffer_size = alloc_size; } else { addr->alloced_phys_addr = (phys_addr_t) allocate_contiguous_memory_nomap(alloc_size, res_trk_get_mem_type(), SZ_4K); if (!addr->alloced_phys_addr) { DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n", __func__, alloc_size); goto bail_out; } flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR; if (alignment == DDL_KILO_BYTE(128)) index = 1; else if (alignment > SZ_4K) flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K; addr->mapped_buffer = msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr, alloc_size, flags, &vidc_mmu_subsystem[index], sizeof(vidc_mmu_subsystem[index])/sizeof(unsigned int)); if (IS_ERR(addr->mapped_buffer)) { pr_err(" %s() buffer map failed", __func__); goto free_acm_ion_alloc; } mapped_buffer = addr->mapped_buffer; if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { pr_err("%s() map buffers failed\n", __func__); goto free_map_buffers; } addr->physical_base_addr = (u8 *)mapped_buffer->iova[0]; addr->virtual_base_addr = mapped_buffer->vaddr; addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) addr->physical_base_addr, alignment); offset = (u32)(addr->align_physical_addr - addr->physical_base_addr); addr->align_virtual_addr = addr->virtual_base_addr + offset; addr->buffer_size = sz; } return addr->virtual_base_addr; free_map_buffers: msm_subsystem_unmap_buffer(addr->mapped_buffer); addr->mapped_buffer = NULL; free_acm_ion_alloc: if (ddl_context->video_ion_client) { if (addr->alloc_handle) { if (addr->virtual_base_addr) { ion_unmap_kernel(ddl_context->video_ion_client, addr->alloc_handle); addr->virtual_base_addr = 0; } if (addr->alloced_phys_addr) { ion_unmap_iommu(ddl_context->video_ion_client, addr->alloc_handle, VIDEO_DOMAIN, VIDEO_MAIN_POOL); addr->alloced_phys_addr = 0; } ion_free(ddl_context->video_ion_client, addr->alloc_handle); addr->alloc_handle = NULL; } } else { free_contiguous_memory_by_paddr( (unsigned long)addr->alloced_phys_addr); addr->alloced_phys_addr = (phys_addr_t)NULL; } bail_out: return NULL; }