void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment) { u32 alloc_size, offset = 0, flags = 0; u32 index = 0; struct ddl_context *ddl_context; struct msm_mapped_buffer *mapped_buffer = NULL; 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(); alloc_size = (sz + alignment); 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_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_alloc: free_contiguous_memory_by_paddr( (unsigned long)addr->alloced_phys_addr); addr->alloced_phys_addr = (phys_addr_t)NULL; bail_out: return NULL; }
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)); }
static void res_trk_pmem_free(struct ddl_buf_addr *addr) { struct ddl_context *ddl_context; if (!addr) { DDL_MSG_ERROR("\n%s() NULL address", __func__); return; } ddl_context = ddl_get_context(); if (ddl_context->video_ion_client) { if (addr->alloc_handle) { ion_free(ddl_context->video_ion_client, addr->alloc_handle); addr->alloc_handle = NULL; } } 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 ddl_pmem_free(struct ddl_buf_addr *buff_addr) { struct ddl_context *ddl_context; ddl_context = ddl_get_context(); if (!buff_addr) { ERR("\n %s() invalid arguments %p", __func__, buff_addr); return; } DBG("ddl_pmem_free: phys(0x%x) align_phys(0x%x), "\ "virt(0x%x), align_virt(0x%x), size(%u)", (u32)buff_addr->physical_base_addr, (u32)buff_addr->align_physical_addr, (u32)buff_addr->virtual_base_addr, (u32)buff_addr->align_virtual_addr, buff_addr->buffer_size); if (ddl_context->video_ion_client) { if (buff_addr->alloc_handle) { ion_unmap_kernel(ddl_context->video_ion_client, buff_addr->alloc_handle); ion_free(ddl_context->video_ion_client, buff_addr->alloc_handle); } } else { if (buff_addr->mapped_buffer) msm_subsystem_unmap_buffer( buff_addr->mapped_buffer); if (buff_addr->physical_base_addr) free_contiguous_memory_by_paddr((unsigned long) buff_addr->physical_base_addr); } memset(buff_addr, 0, sizeof(struct ddl_buf_addr)); }
static void res_trk_pmem_unmap(struct ddl_buf_addr *addr) { if (!addr) { pr_err("%s() invalid args\n", __func__); return; } if (addr->mapped_buffer) msm_subsystem_unmap_buffer(addr->mapped_buffer); addr->mapped_buffer = NULL; }
static void msm_vb2_mem_ops_put(void *buf_priv) { struct videobuf2_contig_pmem *mem = buf_priv; if (!mem->is_userptr) { D("%s Freeing memory ", __func__); if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0) D("%s unmapped memory\n", __func__); msm_mem_free(mem); } kfree(mem); }
void msm_gemini_platform_p2v(struct file *file, struct msm_mapped_buffer **msm_buffer) { if (msm_subsystem_unmap_buffer( (struct msm_mapped_buffer *)*msm_buffer) < 0) pr_err("%s: umapped stat memory\n", __func__); *msm_buffer = NULL; #ifdef CONFIG_ANDROID_PMEM put_pmem_file(file); #endif }
void ddl_pmem_free(struct ddl_buf_addr *addr) { if (!addr) { pr_err("%s() invalid args\n", __func__); return; } if (addr->alloced_phys_addr) free_contiguous_memory_by_paddr( (unsigned long)addr->alloced_phys_addr); if (addr->mapped_buffer) msm_subsystem_unmap_buffer(addr->mapped_buffer); memset(addr, 0, sizeof(struct ddl_buf_addr)); }
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem, struct ion_client *client) { if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0) D("%s unmapped memory\n", __func__); if (mem->is_userptr) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION 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 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_free(ddl_context->video_ion_client, addr->alloc_handle); } } else { if (addr->alloced_phys_addr) free_contiguous_memory_by_paddr( (unsigned long)addr->alloced_phys_addr); } if (addr->mapped_buffer) msm_subsystem_unmap_buffer(addr->mapped_buffer); memset(addr, 0, sizeof(struct ddl_buf_addr)); }
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 }
void ddl_pmem_free(struct ddl_buf_addr *buff_addr) { if (!buff_addr) { ERR("\n %s() invalid arguments %p", __func__, buff_addr); return; } DBG_PMEM("\n%s() IN: phy_addr(%p) ker_addr(%p) size(%u)", __func__, buff_addr->physical_base_addr, buff_addr->virtual_base_addr, buff_addr->buffer_size); if (buff_addr->mapped_buffer) msm_subsystem_unmap_buffer(buff_addr->mapped_buffer); if (buff_addr->physical_base_addr) free_contiguous_memory_by_paddr( (unsigned long) buff_addr->physical_base_addr); DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__, buff_addr->physical_base_addr, buff_addr->virtual_base_addr, buff_addr->buffer_size); buff_addr->buffer_size = 0; buff_addr->physical_base_addr = NULL; buff_addr->virtual_base_addr = NULL; buff_addr->mapped_buffer = NULL; }
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; }
void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align) { u32 guard_bytes, align_mask; u32 physical_addr; u32 align_offset; u32 alloc_size, flags = 0; struct ddl_context *ddl_context; struct msm_mapped_buffer *mapped_buffer = NULL; unsigned long *kernel_vaddr = NULL; ion_phys_addr_t phyaddr = 0; size_t len = 0; int ret = -EINVAL; if (!buff_addr) { ERR("\n%s() Invalid Parameters\n", __func__); return; } if (align == DDL_LINEAR_BUFFER_ALIGN_BYTES) { guard_bytes = 31; align_mask = 0xFFFFFFE0U; } else { guard_bytes = DDL_TILE_BUF_ALIGN_GUARD_BYTES; align_mask = DDL_TILE_BUF_ALIGN_MASK; } ddl_context = ddl_get_context(); alloc_size = sz + guard_bytes; 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) { ERR("\n%s(): DDL ION Client Invalid handle\n", __func__); goto bailout; } buff_addr->mem_type = res_trk_get_mem_type(); buff_addr->alloc_handle = ion_alloc( ddl_context->video_ion_client, alloc_size, SZ_4K, buff_addr->mem_type); if (!buff_addr->alloc_handle) { ERR("\n%s(): DDL ION alloc failed\n", __func__); goto bailout; } ret = ion_phys(ddl_context->video_ion_client, buff_addr->alloc_handle, &phyaddr, &len); if (ret || !phyaddr) { ERR("\n%s(): DDL ION client physical failed\n", __func__); goto free_ion_buffer; } buff_addr->physical_base_addr = (u32 *)phyaddr; kernel_vaddr = (unsigned long *) ion_map_kernel( ddl_context->video_ion_client, buff_addr->alloc_handle, UNCACHED); if (IS_ERR_OR_NULL(kernel_vaddr)) { ERR("\n%s(): DDL ION map failed\n", __func__); goto unmap_ion_buffer; } buff_addr->virtual_base_addr = (u32 *)kernel_vaddr; DBG("ddl_ion_alloc: handle(0x%x), mem_type(0x%x), "\ "phys(0x%x), virt(0x%x), size(%u), align(%u), "\ "alloced_len(%u)", (u32)buff_addr->alloc_handle, (u32)buff_addr->mem_type, (u32)buff_addr->physical_base_addr, (u32)buff_addr->virtual_base_addr, alloc_size, align, len); } else { physical_addr = (u32) allocate_contiguous_memory_nomap(alloc_size, ddl_context->memtype, SZ_4K); if (!physical_addr) { ERR("\n%s(): DDL pmem allocate failed\n", __func__); goto bailout; } buff_addr->physical_base_addr = (u32 *) physical_addr; flags = MSM_SUBSYSTEM_MAP_KADDR; buff_addr->mapped_buffer = msm_subsystem_map_buffer((unsigned long)physical_addr, alloc_size, flags, NULL, 0); if (IS_ERR(buff_addr->mapped_buffer)) { ERR("\n%s() buffer map failed\n", __func__); goto free_pmem_buffer; } mapped_buffer = buff_addr->mapped_buffer; if (!mapped_buffer->vaddr) { ERR("\n%s() mapped virtual address is NULL\n", __func__); goto unmap_pmem_buffer; } buff_addr->virtual_base_addr = mapped_buffer->vaddr; DBG("ddl_pmem_alloc: mem_type(0x%x), phys(0x%x),"\ " virt(0x%x), sz(%u), align(%u)", (u32)buff_addr->mem_type, (u32)buff_addr->physical_base_addr, (u32)buff_addr->virtual_base_addr, alloc_size, SZ_4K); } memset(buff_addr->virtual_base_addr, 0 , sz + guard_bytes); buff_addr->buffer_size = sz; buff_addr->align_physical_addr = (u32 *) (((u32)buff_addr->physical_base_addr + guard_bytes) & align_mask); align_offset = (u32) (buff_addr->align_physical_addr) - (u32)buff_addr->physical_base_addr; buff_addr->align_virtual_addr = (u32 *) ((u32) (buff_addr->virtual_base_addr) + align_offset); DBG("%s(): phys(0x%x) align_phys(0x%x), virt(0x%x),"\ " align_virt(0x%x)", __func__, (u32)buff_addr->physical_base_addr, (u32)buff_addr->align_physical_addr, (u32)buff_addr->virtual_base_addr, (u32)buff_addr->align_virtual_addr); return; unmap_pmem_buffer: if (buff_addr->mapped_buffer) msm_subsystem_unmap_buffer(buff_addr->mapped_buffer); free_pmem_buffer: if (buff_addr->physical_base_addr) free_contiguous_memory_by_paddr((unsigned long) buff_addr->physical_base_addr); memset(buff_addr, 0, sizeof(struct ddl_buf_addr)); return; unmap_ion_buffer: if (ddl_context->video_ion_client) { if (buff_addr->alloc_handle) ion_unmap_kernel(ddl_context->video_ion_client, buff_addr->alloc_handle); } free_ion_buffer: if (ddl_context->video_ion_client) { if (buff_addr->alloc_handle) ion_free(ddl_context->video_ion_client, buff_addr->alloc_handle); } bailout: memset(buff_addr, 0, sizeof(struct ddl_buf_addr)); }
void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment) { u32 alloc_size, offset = 0, flags = 0; u32 index = 0; struct ddl_context *ddl_context; struct msm_mapped_buffer *mapped_buffer = NULL; int rc = -EINVAL; ion_phys_addr_t phyaddr = 0; size_t len = 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(); alloc_size = (sz + alignment); 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, (1<<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; } rc = ion_phys(ddl_context->video_ion_client, addr->alloc_handle, &phyaddr, &len); if (rc || !phyaddr) { DDL_MSG_ERROR("%s():DDL ION client physical failed\n", __func__); goto free_acm_ion_alloc; } addr->alloced_phys_addr = phyaddr; } 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) { 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; }
void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align) { u32 guard_bytes, align_mask; u32 physical_addr; u32 align_offset; u32 alloc_size, flags = 0; struct ddl_context *ddl_context; struct msm_mapped_buffer *mapped_buffer = NULL; if (!buff_addr) { ERR("\n%s() Invalid Parameters", __func__); return; } DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); if (align == DDL_LINEAR_BUFFER_ALIGN_BYTES) { guard_bytes = 31; align_mask = 0xFFFFFFE0U; } else { guard_bytes = DDL_TILE_BUF_ALIGN_GUARD_BYTES; align_mask = DDL_TILE_BUF_ALIGN_MASK; } ddl_context = ddl_get_context(); alloc_size = sz + guard_bytes; physical_addr = (u32) allocate_contiguous_memory_nomap(alloc_size, ddl_context->memtype, SZ_4K); if (!physical_addr) { pr_err("%s(): could not allocate kernel pmem buffers\n", __func__); goto bailout; } buff_addr->physical_base_addr = (u32 *) physical_addr; flags = MSM_SUBSYSTEM_MAP_KADDR; buff_addr->mapped_buffer = msm_subsystem_map_buffer((unsigned long)physical_addr, alloc_size, flags, NULL, 0); if (IS_ERR(buff_addr->mapped_buffer)) { pr_err(" %s() buffer map failed", __func__); goto free_acm_alloc; } mapped_buffer = buff_addr->mapped_buffer; if (!mapped_buffer->vaddr) { pr_err("%s() mapped virtual address is NULL", __func__); goto free_map_buffers; } buff_addr->virtual_base_addr = mapped_buffer->vaddr; memset(buff_addr->virtual_base_addr, 0 , sz + guard_bytes); buff_addr->buffer_size = sz; buff_addr->align_physical_addr = (u32 *) ((physical_addr + guard_bytes) & align_mask); align_offset = (u32) (buff_addr->align_physical_addr) - physical_addr; buff_addr->align_virtual_addr = (u32 *) ((u32) (buff_addr->virtual_base_addr) + align_offset); DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__, buff_addr->physical_base_addr, buff_addr->virtual_base_addr, buff_addr->buffer_size); return; free_map_buffers: msm_subsystem_unmap_buffer(buff_addr->mapped_buffer); free_acm_alloc: free_contiguous_memory_by_paddr( (unsigned long) physical_addr); bailout: buff_addr->physical_base_addr = NULL; buff_addr->virtual_base_addr = NULL; buff_addr->buffer_size = 0; buff_addr->mapped_buffer = NULL; }
static void *res_trk_pmem_map (struct ddl_buf_addr *addr, size_t sz, u32 alignment) { u32 offset = 0, flags = 0; u32 index = 0; struct ddl_context *ddl_context; struct msm_mapped_buffer *mapped_buffer = NULL; int ret = 0; unsigned long iova = 0; unsigned long buffer_size = 0; unsigned long *kernel_vaddr = NULL; ddl_context = ddl_get_context(); if (res_trk_get_enable_ion() && addr->alloc_handle) { kernel_vaddr = (unsigned long *) ion_map_kernel( ddl_context->video_ion_client, addr->alloc_handle, UNCACHED); if (IS_ERR_OR_NULL(kernel_vaddr)) { DDL_MSG_ERROR("%s():DDL ION client map failed\n", __func__); goto ion_bail_out; } addr->virtual_base_addr = (u8 *) kernel_vaddr; ret = ion_map_iommu(ddl_context->video_ion_client, addr->alloc_handle, VIDEO_DOMAIN, VIDEO_FIRMWARE_POOL, SZ_4K, 0, &iova, &buffer_size, UNCACHED, 0); if (ret || !iova) { DDL_MSG_ERROR( "%s():DDL ION client iommu map failed, ret = %d iova = 0x%lx\n", __func__, ret, iova); goto ion_unmap_bail_out; } addr->mapped_buffer = NULL; 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 = buffer_size; } else { if (!res_trk_check_for_sec_session()) { if (!addr->alloced_phys_addr) { pr_err(" %s() alloced addres NULL", __func__); 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, sz, flags, &restrk_mmu_subsystem[index], sizeof(restrk_mmu_subsystem[index])/ sizeof(unsigned int)); if (IS_ERR(addr->mapped_buffer)) { pr_err(" %s() buffer map failed", __func__); goto bail_out; } mapped_buffer = addr->mapped_buffer; if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { pr_err("%s() map buffers failed\n", __func__); goto bail_out; } addr->physical_base_addr = (u8 *)mapped_buffer->iova[0]; addr->virtual_base_addr = mapped_buffer->vaddr; } else { addr->physical_base_addr = (u8 *) addr->alloced_phys_addr; addr->virtual_base_addr = (u8 *)addr->alloced_phys_addr; } 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; bail_out: if (IS_ERR(addr->mapped_buffer)) msm_subsystem_unmap_buffer(addr->mapped_buffer); return NULL; ion_unmap_bail_out: if (!IS_ERR_OR_NULL(addr->alloc_handle)) { ion_unmap_kernel(resource_context. res_ion_client, addr->alloc_handle); } ion_bail_out: return NULL; }
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; ion_phys_addr_t phyaddr = 0; size_t len = 0; int rc = 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(); res_trk_set_mem_type(addr->mem_type); alloc_size = (sz + alignment); 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; } alloc_size = (alloc_size+4095) & ~4095; 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 (IS_ERR_OR_NULL(kernel_vaddr)) { DDL_MSG_ERROR("%s() :DDL ION map failed\n", __func__); goto free_ion_alloc; } addr->virtual_base_addr = (u8 *) kernel_vaddr; if (res_trk_check_for_sec_session()) { rc = ion_phys(ddl_context->video_ion_client, addr->alloc_handle, &phyaddr, &len); if (rc || !phyaddr) { DDL_MSG_ERROR( "%s():DDL ION client physical failed\n", __func__); goto unmap_ion_alloc; } addr->alloced_phys_addr = phyaddr; } else { 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 || !iova) { DDL_MSG_ERROR( "%s():DDL ION ion map iommu failed, ret = %d iova = 0x%lx\n", __func__, ret, iova); goto unmap_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 unmap_ion_alloc; } addr->mapped_buffer = NULL; addr->physical_base_addr = (u8 *) addr->alloced_phys_addr; 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_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_alloc: free_contiguous_memory_by_paddr( (unsigned long)addr->alloced_phys_addr); addr->alloced_phys_addr = (phys_addr_t)NULL; return NULL; unmap_ion_alloc: ion_unmap_kernel(ddl_context->video_ion_client, addr->alloc_handle); addr->virtual_base_addr = NULL; addr->alloced_phys_addr = (phys_addr_t)NULL; free_ion_alloc: ion_free(ddl_context->video_ion_client, addr->alloc_handle); addr->alloc_handle = NULL; bail_out: return NULL; }