| /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #ifndef _CAM_SMMU_API_H_ |
| #define _CAM_SMMU_API_H_ |
| |
| #include <linux/dma-direction.h> |
| #include <linux/module.h> |
| #include <linux/dma-buf.h> |
| #include <asm/dma-iommu.h> |
| #include <linux/dma-direction.h> |
| #include <linux/of_platform.h> |
| #include <linux/iommu.h> |
| #include <linux/random.h> |
| #include <linux/spinlock_types.h> |
| #include <linux/mutex.h> |
| #include <linux/msm_ion.h> |
| |
| /*Enum for possible CAM SMMU operations */ |
| enum cam_smmu_ops_param { |
| CAM_SMMU_ATTACH, |
| CAM_SMMU_DETACH, |
| CAM_SMMU_VOTE, |
| CAM_SMMU_DEVOTE, |
| CAM_SMMU_OPS_INVALID |
| }; |
| |
| enum cam_smmu_map_dir { |
| CAM_SMMU_MAP_READ, |
| CAM_SMMU_MAP_WRITE, |
| CAM_SMMU_MAP_RW, |
| CAM_SMMU_MAP_INVALID |
| }; |
| |
| enum cam_smmu_region_id { |
| CAM_SMMU_REGION_FIRMWARE, |
| CAM_SMMU_REGION_SHARED, |
| CAM_SMMU_REGION_SCRATCH, |
| CAM_SMMU_REGION_IO |
| }; |
| |
| /** |
| * @brief : Gets an smmu handle |
| * |
| * @param identifier: Unique identifier to be used by clients which they |
| * should get from device tree. CAM SMMU driver will |
| * not enforce how this string is obtained and will |
| * only validate this against the list of permitted |
| * identifiers |
| * @param handle_ptr: Based on the indentifier, CAM SMMU drivier will |
| * fill the handle pointed by handle_ptr |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_get_handle(char *identifier, int *handle_ptr); |
| |
| /** |
| * @brief : Performs IOMMU operations |
| * |
| * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.) |
| * @param op : Operation to be performed. Can be either CAM_SMMU_ATTACH |
| * or CAM_SMMU_DETACH |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_ops(int handle, enum cam_smmu_ops_param op); |
| |
| /** |
| * @brief : Maps IOVA for calling driver |
| * |
| * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.) |
| * @param ion_fd: ION handle identifying the memory buffer. |
| * @dir : Mapping direction: which will traslate toDMA_BIDIRECTIONAL, |
| * DMA_TO_DEVICE or DMA_FROM_DEVICE |
| * @dma_addr : Pointer to physical address where mapped address will be |
| * returned if region_id is CAM_SMMU_REGION_IO. If region_id is |
| * CAM_SMMU_REGION_SHARED, dma_addr is used as an input parameter |
| * which specifies the cpu virtual address to map. |
| * @len : Length of buffer mapped returned by CAM SMMU driver. |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_map_iova(int handle, |
| int ion_fd, enum cam_smmu_map_dir dir, |
| dma_addr_t *dma_addr, size_t *len_ptr, |
| enum cam_smmu_region_id region_id); |
| |
| /** |
| * @brief : Unmaps IOVA for calling driver |
| * |
| * @param handle: Handle to identify the CAMSMMU client (VFE, CPP, FD etc.) |
| * @param ion_fd: ION handle identifying the memory buffer. |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_unmap_iova(int handle, |
| int ion_fd, |
| enum cam_smmu_region_id region_id); |
| |
| /** |
| * @brief : Allocates a scratch buffer |
| * |
| * This function allocates a scratch virtual buffer of length virt_len in the |
| * device virtual address space mapped to phys_len physically contiguous bytes |
| * in that device's SMMU. |
| * |
| * virt_len and phys_len are expected to be aligned to PAGE_SIZE and with each |
| * other, otherwise -EINVAL is returned. |
| * |
| * -EINVAL will be returned if virt_len is less than phys_len. |
| * |
| * Passing a too large phys_len might also cause failure if that much size is |
| * not available for allocation in a physically contiguous way. |
| * |
| * @param handle : Handle to identify the CAMSMMU client (VFE, CPP, FD etc.) |
| * @param dir : Direction of mapping which will translate to IOMMU_READ |
| * IOMMU_WRITE or a bit mask of both. |
| * @param paddr_ptr: Device virtual address that the client device will be |
| * able to read from/write to |
| * @param virt_len : Virtual length of the scratch buffer |
| * @param phys_len : Physical length of the scratch buffer |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| |
| int cam_smmu_get_scratch_iova(int handle, |
| enum cam_smmu_map_dir dir, |
| dma_addr_t *paddr_ptr, |
| size_t virt_len, |
| size_t phys_len); |
| |
| /** |
| * @brief : Frees a scratch buffer |
| * |
| * This function frees a scratch buffer and releases the corresponding SMMU |
| * mappings. |
| * |
| * @param handle : Handle to identify the CAMSMMU client (IFE, ICP, etc.) |
| * @param paddr : Device virtual address of client's scratch buffer that |
| * will be freed. |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| |
| int cam_smmu_put_scratch_iova(int handle, |
| dma_addr_t paddr); |
| |
| /** |
| *@brief : Destroys an smmu handle |
| * |
| * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.) |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_destroy_handle(int handle); |
| |
| /** |
| * @brief : Finds index by handle in the smmu client table |
| * |
| * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.) |
| * @return Index of SMMU client. Nagative in case of error. |
| */ |
| int cam_smmu_find_index_by_handle(int hdl); |
| |
| /** |
| * @brief : Registers smmu fault handler for client |
| * |
| * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.) |
| * @param client_page_fault_handler: It is triggered in IOMMU page fault |
| * @param token: It is input param when trigger page fault handler |
| */ |
| void cam_smmu_reg_client_page_fault_handler(int handle, |
| void (*client_page_fault_handler)(struct iommu_domain *, |
| struct device *, unsigned long, |
| int, void*), void *token); |
| |
| /** |
| * @brief Maps memory from an ION fd into IOVA space |
| * |
| * @param handle: SMMU handle identifying the context bank to map to |
| * @param ion_fd: ION fd of memory to map to |
| * @param paddr_ptr: Pointer IOVA address that will be returned |
| * @param len_ptr: Length of memory mapped |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_get_iova(int handle, int ion_fd, |
| dma_addr_t *paddr_ptr, size_t *len_ptr); |
| /** |
| * @brief Unmaps memory from context bank |
| * |
| * @param handle: SMMU handle identifying the context bank |
| * @param ion_fd: ION fd of memory to unmap |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_put_iova(int handle, int ion_fd); |
| |
| /** |
| * @brief Maps secure memory for SMMU handle |
| * |
| * @param handle: SMMU handle identifying context bank |
| * @param ion_fd: ION fd to map securely |
| * @param dir: DMA Direction for the mapping |
| * @param dma_addr: Returned IOVA address after mapping |
| * @param len_ptr: Length of memory mapped |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_map_sec_iova(int handle, |
| int ion_fd, enum cam_smmu_map_dir dir, |
| dma_addr_t *dma_addr, size_t *len_ptr); |
| |
| /** |
| * @brief Unmaps secure memopry for SMMU handle |
| * |
| * @param handle: SMMU handle identifying context bank |
| * @param ion_fd: ION fd to unmap |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_unmap_sec_iova(int handle, int ion_fd); |
| |
| |
| /** |
| * @brief Allocates firmware for context bank |
| * |
| * @param smmu_hdl: SMMU handle identifying context bank |
| * @param iova: IOVA address of allocated firmware |
| * @param kvaddr: CPU mapped address of allocated firmware |
| * @param len: Length of allocated firmware memory |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_alloc_firmware(int32_t smmu_hdl, |
| dma_addr_t *iova, |
| uint64_t *kvaddr, |
| size_t *len); |
| |
| /** |
| * @brief Deallocates firmware memory for context bank |
| * |
| * @param smmu_hdl: SMMU handle identifying the context bank |
| * |
| * @return Status of operation. Negative in case of error. Zero otherwise. |
| */ |
| int cam_smmu_dealloc_firmware(int32_t smmu_hdl); |
| #endif /* _CAM_SMMU_API_H_ */ |