diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index f6eec4446c..84bc7ce95b 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -505,12 +505,16 @@ static int cam_mem_util_map_hw_va(uint32_t flags, int i; int rc = -1; int dir = cam_mem_util_get_dma_dir(flags); + bool dis_delayed_unmap = false; if (dir < 0) { CAM_ERR(CAM_MEM, "fail to map DMA direction, dir=%d", dir); return dir; } + if (flags & CAM_MEM_FLAG_DISABLE_DELAYED_UNMAP) + dis_delayed_unmap = true; + CAM_DBG(CAM_MEM, "map_hw_va : fd = %d, flags = 0x%x, dir=%d, num_hdls=%d", fd, flags, dir, num_hdls); @@ -534,6 +538,7 @@ static int cam_mem_util_map_hw_va(uint32_t flags, for (i = 0; i < num_hdls; i++) { rc = cam_smmu_map_user_iova(mmu_hdls[i], fd, + dis_delayed_unmap, dir, (dma_addr_t *)hw_vaddr, len, diff --git a/drivers/cam_smmu/cam_smmu_api.c b/drivers/cam_smmu/cam_smmu_api.c index 3043bee219..78d1b2cee9 100644 --- a/drivers/cam_smmu/cam_smmu_api.c +++ b/drivers/cam_smmu/cam_smmu_api.c @@ -215,8 +215,9 @@ static struct cam_dma_buff_info *cam_smmu_find_mapping_by_virt_address(int idx, dma_addr_t virt_addr); static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, - enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, - size_t *len_ptr, enum cam_smmu_region_id region_id); + bool dis_delayed_unmap, enum dma_data_direction dma_dir, + dma_addr_t *paddr_ptr, size_t *len_ptr, + enum cam_smmu_region_id region_id); static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx, struct dma_buf *buf, enum dma_data_direction dma_dir, @@ -1676,7 +1677,7 @@ EXPORT_SYMBOL(cam_smmu_release_sec_heap); static int cam_smmu_map_buffer_validate(struct dma_buf *buf, int idx, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id, - struct cam_dma_buff_info **mapping_info) + bool dis_delayed_unmap, struct cam_dma_buff_info **mapping_info) { struct dma_buf_attachment *attach = NULL; struct sg_table *table = NULL; @@ -1751,7 +1752,8 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf, } iommu_cb_set.cb_info[idx].shared_mapping_size += *len_ptr; } else if (region_id == CAM_SMMU_REGION_IO) { - attach->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP; + if (!dis_delayed_unmap) + attach->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP; table = dma_buf_map_attachment(attach, dma_dir); if (IS_ERR_OR_NULL(table)) { @@ -1769,8 +1771,9 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf, goto err_unmap_sg; } - CAM_DBG(CAM_SMMU, "iova=%pK, region_id=%d, paddr=%pK, len=%d", - iova, region_id, *paddr_ptr, *len_ptr); + CAM_DBG(CAM_SMMU, + "iova=%pK, region_id=%d, paddr=%pK, len=%d, dma_map_attrs=%d", + iova, region_id, *paddr_ptr, *len_ptr, attach->dma_map_attrs); if (table->sgl) { CAM_DBG(CAM_SMMU, @@ -1838,8 +1841,9 @@ err_out: static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, - enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, - size_t *len_ptr, enum cam_smmu_region_id region_id) + bool dis_delayed_unmap, enum dma_data_direction dma_dir, + dma_addr_t *paddr_ptr, size_t *len_ptr, + enum cam_smmu_region_id region_id) { int rc = -1; struct cam_dma_buff_info *mapping_info = NULL; @@ -1849,7 +1853,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, buf = dma_buf_get(ion_fd); rc = cam_smmu_map_buffer_validate(buf, idx, dma_dir, paddr_ptr, len_ptr, - region_id, &mapping_info); + region_id, dis_delayed_unmap, &mapping_info); if (rc) { CAM_ERR(CAM_SMMU, "buffer validation failure"); @@ -1873,7 +1877,7 @@ static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx, struct cam_dma_buff_info *mapping_info = NULL; rc = cam_smmu_map_buffer_validate(buf, idx, dma_dir, paddr_ptr, len_ptr, - region_id, &mapping_info); + region_id, false, &mapping_info); if (rc) { CAM_ERR(CAM_SMMU, "buffer validation failure"); @@ -1910,6 +1914,11 @@ static int cam_smmu_unmap_buf_and_remove_from_list( return -EINVAL; } + CAM_DBG(CAM_SMMU, + "region_id=%d, paddr=%pK, len=%d, dma_map_attrs=%d", + mapping_info->region_id, mapping_info->paddr, mapping_info->len, + mapping_info->attach->dma_map_attrs); + if (mapping_info->region_id == CAM_SMMU_REGION_SHARED) { CAM_DBG(CAM_SMMU, "Removing SHARED buffer paddr = %pK, len = %zu", @@ -1938,7 +1947,6 @@ static int cam_smmu_unmap_buf_and_remove_from_list( iommu_cb_set.cb_info[idx].shared_mapping_size -= mapping_info->len; } else if (mapping_info->region_id == CAM_SMMU_REGION_IO) { - mapping_info->attach->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP; iommu_cb_set.cb_info[idx].io_mapping_size -= mapping_info->len; } @@ -2691,7 +2699,7 @@ static int cam_smmu_map_iova_validate_params(int handle, return rc; } -int cam_smmu_map_user_iova(int handle, int ion_fd, +int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id) { @@ -2742,8 +2750,8 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, goto get_addr_end; } - rc = cam_smmu_map_buffer_and_add_to_list(idx, ion_fd, dma_dir, - paddr_ptr, len_ptr, region_id); + rc = cam_smmu_map_buffer_and_add_to_list(idx, ion_fd, + dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id); if (rc < 0) { CAM_ERR(CAM_SMMU, "mapping or add list fail, idx=%d, fd=%d, region=%d, rc=%d", diff --git a/drivers/cam_smmu/cam_smmu_api.h b/drivers/cam_smmu/cam_smmu_api.h index 057eb74145..4c2a6a426e 100644 --- a/drivers/cam_smmu/cam_smmu_api.h +++ b/drivers/cam_smmu/cam_smmu_api.h @@ -98,6 +98,8 @@ int cam_smmu_ops(int handle, enum cam_smmu_ops_param op); * * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.) * @param ion_fd: ION handle identifying the memory buffer. + * @param dis_delayed_unmap: Whether to disable Delayed Unmap feature + * for this mapping * @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 @@ -107,9 +109,8 @@ int cam_smmu_ops(int handle, enum cam_smmu_ops_param op); * @len_ptr : Length of buffer mapped returned by CAM SMMU driver. * @return Status of operation. Negative in case of error. Zero otherwise. */ -int cam_smmu_map_user_iova(int handle, - int ion_fd, enum cam_smmu_map_dir dir, - dma_addr_t *dma_addr, size_t *len_ptr, +int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, + enum cam_smmu_map_dir dir, dma_addr_t *dma_addr, size_t *len_ptr, enum cam_smmu_region_id region_id); /** diff --git a/include/uapi/camera/media/cam_req_mgr.h b/include/uapi/camera/media/cam_req_mgr.h index 934e9bdf4b..b117000428 100644 --- a/include/uapi/camera/media/cam_req_mgr.h +++ b/include/uapi/camera/media/cam_req_mgr.h @@ -276,6 +276,7 @@ struct cam_req_mgr_link_control { #define CAM_MEM_FLAG_CACHE (1<<10) #define CAM_MEM_FLAG_HW_SHARED_ACCESS (1<<11) #define CAM_MEM_FLAG_CDSP_OUTPUT (1<<12) +#define CAM_MEM_FLAG_DISABLE_DELAYED_UNMAP (1<<13) #define CAM_MEM_MMU_MAX_HANDLE 16