int res_trk_get_mem_type(void) { int mem_type = -1; switch (resource_context.res_mem_type) { case DDL_FW_MEM: if (res_trk_get_enable_ion()) mem_type = ION_HEAP(ION_MM_FIRMWARE_HEAP_ID); else mem_type = MEMTYPE_SMI_KERNEL; break; case DDL_MM_MEM: if (res_trk_get_enable_ion()) mem_type = ION_HEAP(ION_CP_MM_HEAP_ID); else mem_type = MEMTYPE_SMI_KERNEL; break; case DDL_CMD_MEM: if (res_trk_get_enable_ion()) mem_type = ION_HEAP(ION_CP_MFC_HEAP_ID); else mem_type = MEMTYPE_SMI_KERNEL; break; default: return mem_type; } return mem_type; }
static int res_trk_pmem_alloc (struct ddl_buf_addr *addr, size_t sz, u32 alignment) { u32 alloc_size; struct ddl_context *ddl_context; 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__); rc = -EINVAL; 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 (!res_trk_is_cp_enabled() || !res_trk_check_for_sec_session()) { 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__); rc = -ENOMEM; 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__); rc = -ENOMEM; goto bail_out; } } else { addr->alloc_handle = NULL; addr->alloced_phys_addr = PIL_FW_BASE_ADDR; addr->buffer_size = sz; } } 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); rc = -ENOMEM; goto bail_out; } addr->buffer_size = sz; return rc; } bail_out: return rc; }
static void *res_trk_pmem_alloc (struct ddl_buf_addr *addr, size_t sz, u32 alignment) { u32 alloc_size; struct ddl_context *ddl_context; 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 free_acm_ion_alloc; } return (void *) addr->alloc_handle; } 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; } addr->buffer_size = sz; return (void *)addr->alloced_phys_addr; } 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; } } bail_out: return NULL; }
u32 res_trk_get_mem_type(void) { u32 mem_type; if (res_trk_get_enable_ion()) mem_type = ION_HEAP(resource_context.memtype); else mem_type = resource_context.vidc_platform_data->memtype_pmem; return mem_type; }
void res_trk_init(struct device *device, u32 irq) { if (resource_context.device || resource_context.irq_num || !device) { VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n", __func__); } else { memset(&resource_context, 0, sizeof(resource_context)); mutex_init(&resource_context.lock); mutex_init(&resource_context.secure_lock); resource_context.device = device; resource_context.irq_num = irq; resource_context.vidc_platform_data = (struct msm_vidc_platform_data *) device->platform_data; if (resource_context.vidc_platform_data) { if (res_trk_get_enable_ion()) { resource_context.res_ion_client = res_trk_create_ion_client(); if (!(resource_context.res_ion_client)) { VCDRES_MSG_ERROR("%s()ION createfail\n", __func__); return; } } resource_context.disable_dmx = resource_context.vidc_platform_data->disable_dmx; resource_context.disable_fullhd = resource_context.vidc_platform_data->disable_fullhd; #ifdef CONFIG_MSM_BUS_SCALING resource_context.vidc_bus_client_pdata = resource_context.vidc_platform_data-> vidc_bus_client_pdata; #endif } else { resource_context.memtype = -1; resource_context.disable_dmx = 0; } resource_context.core_type = VCD_CORE_1080P; resource_context.firmware_addr.mem_type = DDL_FW_MEM; } }
void res_trk_init(struct device *device, u32 irq) { VCDRES_MSG_LOW("%s", __func__); if (resource_context.device || resource_context.irq_num || !device) { VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n", __func__); return; } memset(&resource_context, 0, sizeof(resource_context)); mutex_init(&resource_context.lock); resource_context.device = device; resource_context.irq_num = irq; resource_context.core_type = VCD_CORE_720P; resource_context.regulator = regulator_get(NULL, "fs_mfc"); resource_context.vidc_platform_data = (struct msm_vidc_platform_data *) device->platform_data; if (resource_context.vidc_platform_data) { resource_context.memtype = resource_context.vidc_platform_data->memtype; VCDRES_MSG_LOW("%s(): resource_context.memtype = 0x%x", __func__, (u32)resource_context.memtype); if (res_trk_get_enable_ion()) { resource_context.res_ion_client = res_trk_create_ion_client(); if (!(resource_context.res_ion_client)) { VCDRES_MSG_ERROR("%s()ION createfail\n", __func__); return; } VCDRES_MSG_LOW("%s(): ion_client = 0x%x", __func__, (u32)resource_context.res_ion_client); } } else { resource_context.memtype = -1; VCDRES_MSG_ERROR("%s(): vidc_platform_data is NULL", __func__); } }
u32 ddl_device_init(struct ddl_init_config *ddl_init_config, void *client_data) { struct ddl_context *ddl_context; u32 status = VCD_S_SUCCESS; void *ptr = NULL; DDL_MSG_HIGH("ddl_device_init"); if ((!ddl_init_config) || (!ddl_init_config->ddl_callback) || (!ddl_init_config->core_virtual_base_addr)) { DDL_MSG_ERROR("ddl_dev_init:Bad_argument"); return VCD_ERR_ILLEGAL_PARM; } ddl_context = ddl_get_context(); if (DDL_IS_INITIALIZED(ddl_context)) { DDL_MSG_ERROR("ddl_dev_init:Multiple_init"); return VCD_ERR_ILLEGAL_OP; } if (!DDL_IS_IDLE(ddl_context)) { DDL_MSG_ERROR("ddl_dev_init:Ddl_busy"); return VCD_ERR_BUSY; } memset(ddl_context, 0, sizeof(struct ddl_context)); DDL_BUSY(ddl_context); if (res_trk_get_enable_ion()) { DDL_MSG_LOW("ddl_dev_init:ION framework enabled"); ddl_context->video_ion_client = res_trk_get_ion_client(); if (!ddl_context->video_ion_client) { DDL_MSG_ERROR("ION client create failed"); return VCD_ERR_ILLEGAL_OP; } } ddl_context->ddl_callback = ddl_init_config->ddl_callback; if (ddl_init_config->interrupt_clr) ddl_context->interrupt_clr = ddl_init_config->interrupt_clr; ddl_context->core_virtual_base_addr = ddl_init_config->core_virtual_base_addr; ddl_context->client_data = client_data; ddl_context->ddl_hw_response.arg1 = DDL_INVALID_INTR_STATUS; ddl_context->frame_channel_depth = VCD_FRAME_COMMAND_DEPTH; DDL_MSG_LOW("%s() : virtual address of core(%x)\n", __func__, (u32) ddl_init_config->core_virtual_base_addr); vidc_1080p_set_device_base_addr( ddl_context->core_virtual_base_addr); ddl_context->cmd_state = DDL_CMD_INVALID; ddl_client_transact(DDL_INIT_CLIENTS, NULL); ddl_context->fw_memory_size = DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE; if (res_trk_get_firmware_addr(&ddl_context->dram_base_a)) { DDL_MSG_ERROR("firmware allocation failed"); ptr = NULL; } else { ptr = (void *)ddl_context->dram_base_a.virtual_base_addr; } if (!ptr) { DDL_MSG_ERROR("Memory Aocation Failed for FW Base"); status = VCD_ERR_ALLOC_FAIL; } else { DDL_MSG_LOW("%s() : physical address of base(%x)\n", __func__, (u32) ddl_context->dram_base_a.\ align_physical_addr); ddl_context->dram_base_b.align_physical_addr = ddl_context->dram_base_a.align_physical_addr; ddl_context->dram_base_b.align_virtual_addr = ddl_context->dram_base_a.align_virtual_addr; } if (!status) { if (res_trk_get_enable_sec_metadata()) { ddl_context->metadata_shared_input.mem_type = DDL_CMD_MEM; } else { ddl_context->metadata_shared_input.mem_type = DDL_FW_MEM; } ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input, DDL_METADATA_TOTAL_INPUTBUFSIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); if (!ptr) { DDL_MSG_ERROR("ddl_device_init: metadata alloc fail"); status = VCD_ERR_ALLOC_FAIL; } } if (!status && !ddl_fw_init(&ddl_context->dram_base_a)) { DDL_MSG_ERROR("ddl_dev_init:fw_init_failed"); status = VCD_ERR_ALLOC_FAIL; } if (!status) { ddl_context->cmd_state = DDL_CMD_DMA_INIT; ddl_vidc_core_init(ddl_context); } else { ddl_release_context_buffers(ddl_context); DDL_IDLE(ddl_context); } return status; }
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)); }
u32 vcd_get_ion_status(void) { return res_trk_get_enable_ion(); }
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; }
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; }
void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment) { u32 alloc_size, offset = 0 ; struct ddl_context *ddl_context; unsigned long iova = 0; unsigned long buffer_size = 0; unsigned long *kernel_vaddr = NULL; 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(), res_trk_get_ion_flags()); if (IS_ERR_OR_NULL(addr->alloc_handle)) { DDL_MSG_ERROR("%s() :DDL ION alloc failed\n", __func__); goto bail_out; } kernel_vaddr = (unsigned long *) ion_map_kernel( ddl_context->video_ion_client, addr->alloc_handle); 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, 0, 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 { pr_err("ION must be enabled."); goto bail_out; } return addr->virtual_base_addr; 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; }