static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, u32 flags, int domain, int partition, struct msm_smem *mem) { struct ion_handle *hndl; unsigned long iova = 0; unsigned long buffer_size = 0; unsigned long ionflags = 0; unsigned long heap_mask = 0; int rc = 0; if (flags == SMEM_CACHED) ionflags = ION_SET_CACHED(ionflags); else ionflags = ION_SET_UNCACHED(ionflags); heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID); if (align < 4096) align = 4096; size = (size + 4095) & (~4095); pr_debug("\n in %s domain: %d, Partition: %d\n", __func__, domain, partition); hndl = ion_alloc(client->clnt, size, align, heap_mask, ionflags); if (IS_ERR_OR_NULL(hndl)) { pr_err("Failed to allocate shared memory = %p, %d, %d, 0x%x\n", client, size, align, ionflags); rc = -ENOMEM; goto fail_shared_mem_alloc; } mem->mem_type = client->mem_type; mem->smem_priv = hndl; mem->domain = domain; mem->partition_num = partition; mem->kvaddr = ion_map_kernel(client->clnt, hndl); if (!mem->kvaddr) { pr_err("Failed to map shared mem in kernel\n"); rc = -EIO; goto fail_map; } rc = get_device_address(client->clnt, hndl, mem->domain, mem->partition_num, align, &iova, &buffer_size); if (rc) { pr_err("Failed to get device address: %d\n", rc); goto fail_device_address; } mem->device_addr = iova; pr_debug("device_address = 0x%lx, kvaddr = 0x%p\n", mem->device_addr, mem->kvaddr); mem->size = size; return rc; fail_device_address: ion_unmap_kernel(client->clnt, hndl); fail_map: ion_free(client->clnt, hndl); fail_shared_mem_alloc: return rc; }
static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, struct msm_smem *mem, enum hal_buffer buffer_type) { struct ion_handle *hndl; dma_addr_t iova = 0; unsigned long buffer_size = 0; unsigned long ionflags = 0; int rc = 0; int align = SZ_4K; hndl = ion_import_dma_buf(client->clnt, fd); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, "Failed to get handle: %pK, %d, %d, %pK\n", client, fd, offset, hndl); rc = -ENOMEM; goto fail_import_fd; } mem->kvaddr = NULL; rc = ion_handle_get_flags(client->clnt, hndl, &ionflags); if (rc) { dprintk(VIDC_ERR, "Failed to get ion flags: %d\n", rc); goto fail_device_address; } mem->flags = ionflags; mem->buffer_type = buffer_type; if (mem->flags & SMEM_SECURE) align = ALIGN(align, SZ_1M); rc = get_device_address(client, hndl, align, &iova, &buffer_size, mem->flags, buffer_type); if (rc) { dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc); goto fail_device_address; } mem->mem_type = client->mem_type; mem->smem_priv = hndl; mem->device_addr = iova; mem->size = buffer_size; dprintk(VIDC_DBG, "%s: ion_handle = 0x%pK, fd = %d, device_addr = 0x%x, size = %d, kvaddr = 0x%pK, buffer_type = %d\n", __func__, mem->smem_priv, fd, (u32)mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type); return rc; fail_device_address: ion_free(client->clnt, hndl); fail_import_fd: return rc; }
static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, int domain, int partition, struct msm_smem *mem) { struct ion_handle *hndl; unsigned long iova = 0; unsigned long buffer_size = 0; int rc = 0; hndl = ion_import_dma_buf(client->clnt, fd); if (IS_ERR_OR_NULL(hndl)) { pr_err("Failed to get handle: %p, %d, %d, %p\n", client, fd, offset, hndl); rc = -ENOMEM; goto fail_import_fd; } mem->kvaddr = ion_map_kernel(client->clnt, hndl); if (!mem->kvaddr) { pr_err("Failed to map shared mem in kernel\n"); rc = -EIO; goto fail_map; } mem->domain = domain; mem->partition_num = partition; rc = get_device_address(client->clnt, hndl, mem->domain, mem->partition_num, 4096, &iova, &buffer_size); if (rc) { pr_err("Failed to get device address: %d\n", rc); goto fail_device_address; } mem->kvaddr += offset; mem->mem_type = client->mem_type; mem->smem_priv = hndl; mem->device_addr = iova + offset; mem->size = buffer_size; pr_debug("Buffer device address: 0x%lx, size: %d\n", mem->device_addr, mem->size); return rc; fail_device_address: ion_unmap_kernel(client->clnt, hndl); fail_map: ion_free(client->clnt, hndl); fail_import_fd: return rc; }
static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, int domain, int partition, struct msm_smem *mem) { struct ion_handle *hndl; unsigned long ionflag; unsigned long iova = 0; unsigned long buffer_size = 0; int rc = 0; hndl = ion_import_dma_buf(client->clnt, fd); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n", client, fd, offset, hndl); rc = -ENOMEM; goto fail_import_fd; } rc = ion_handle_get_flags(client->clnt, hndl, &ionflag); if (rc) { dprintk(VIDC_ERR, "Failed to get ion flags: %d", rc); goto fail_map; } mem->kvaddr = NULL; mem->domain = domain; mem->partition_num = partition; rc = get_device_address(client->clnt, hndl, mem->domain, mem->partition_num, 4096, &iova, &buffer_size, ionflag); if (rc) { dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc); goto fail_device_address; } mem->mem_type = client->mem_type; mem->smem_priv = hndl; mem->device_addr = iova; mem->size = buffer_size; dprintk(VIDC_DBG, "NOTE: Buffer device address: 0x%lx, size: %d\n", mem->device_addr, mem->size); return rc; fail_device_address: ion_unmap_kernel(client->clnt, hndl); fail_map: ion_free(client->clnt, hndl); fail_import_fd: return rc; }
static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, u32 flags, enum hal_buffer buffer_type, struct msm_smem *mem, int map_kernel) { struct ion_handle *hndl; unsigned long iova = 0; unsigned long buffer_size = 0; unsigned long heap_mask = 0; int rc = 0; align = ALIGN(align, SZ_4K); size = ALIGN(size, SZ_4K); if (flags & SMEM_SECURE) { size = ALIGN(size, SZ_1M); align = ALIGN(align, SZ_1M); } if (is_iommu_present(client->res)) { heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); } else { dprintk(VIDC_DBG, "allocate shared memory from adsp heap size %d align %d\n", size, align); heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); } if (flags & SMEM_SECURE) heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID); hndl = ion_alloc(client->clnt, size, align, heap_mask, flags); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, "Failed to allocate shared memory = %p, %d, %d, 0x%x\n", client, size, align, flags); rc = -ENOMEM; goto fail_shared_mem_alloc; } mem->mem_type = client->mem_type; mem->smem_priv = hndl; mem->flags = flags; mem->buffer_type = buffer_type; if (map_kernel) { mem->kvaddr = ion_map_kernel(client->clnt, hndl); if (!mem->kvaddr) { dprintk(VIDC_ERR, "Failed to map shared mem in kernel\n"); rc = -EIO; goto fail_map; } } else mem->kvaddr = NULL; rc = get_device_address(client, hndl, align, &iova, &buffer_size, flags, buffer_type); if (rc) { dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc); goto fail_device_address; } mem->device_addr = iova; dprintk(VIDC_DBG, "device_address = 0x%lx, kvaddr = 0x%p, size = %d\n", mem->device_addr, mem->kvaddr, size); mem->size = size; return rc; fail_device_address: ion_unmap_kernel(client->clnt, hndl); fail_map: ion_free(client->clnt, hndl); fail_shared_mem_alloc: return rc; }