msm: camera: memmgr: Add interface to support cpu access operation

Add ioctl interfaces to support dma begin and end cpu access
operations for camera buffers.

CRs-Fixed: 3197463
Change-Id: Ibeb31e8f425489abfdd47df6f92271ac40ace407
Signed-off-by: Pavan Kumar Chilamkurthi <quic_pchilamk@quicinc.com>
This commit is contained in:
Pavan Kumar Chilamkurthi
2022-05-16 01:17:08 -07:00
committed by Camera Software Integration
parent 909b2ed98e
commit 5af17aad2a
4 changed files with 160 additions and 3 deletions

View File

@@ -33,12 +33,14 @@ static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED);
/* cam_mem_mgr_debug - global struct to keep track of debug settings for mem mgr
*
* @dentry : Directory entry to the mem mgr root folder
* @alloc_profile_enable : Whether to enable alloc profiling
* @dentry : Directory entry to the mem mgr root folder
* @alloc_profile_enable : Whether to enable alloc profiling
* @override_cpu_access_dir : Override cpu access direction to BIDIRECTIONAL
*/
static struct {
struct dentry *dentry;
bool alloc_profile_enable;
bool override_cpu_access_dir;
} g_cam_mem_mgr_debug;
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
@@ -195,6 +197,9 @@ static int cam_mem_mgr_create_debug_fs(void)
debugfs_create_bool("alloc_profile_enable", 0644, g_cam_mem_mgr_debug.dentry,
&g_cam_mem_mgr_debug.alloc_profile_enable);
debugfs_create_bool("override_cpu_access_dir", 0644, g_cam_mem_mgr_debug.dentry,
&g_cam_mem_mgr_debug.override_cpu_access_dir);
end:
return rc;
}
@@ -472,6 +477,94 @@ end:
}
EXPORT_SYMBOL(cam_mem_mgr_cache_ops);
int cam_mem_mgr_cpu_access_op(struct cam_mem_cpu_access_op *cmd)
{
int rc = 0, idx;
uint32_t direction;
if (!atomic_read(&cam_mem_mgr_state)) {
CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized");
return -EINVAL;
}
if (!cmd) {
CAM_ERR(CAM_MEM, "Invalid cmd");
return -EINVAL;
}
idx = CAM_MEM_MGR_GET_HDL_IDX(cmd->buf_handle);
if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0) {
CAM_ERR(CAM_MEM, "Invalid idx=%d, buf_handle 0x%x, access=0x%x",
idx, cmd->buf_handle, cmd->access);
return -EINVAL;
}
mutex_lock(&tbl.m_lock);
if (!test_bit(idx, tbl.bitmap)) {
CAM_ERR(CAM_MEM, "Buffer at idx=%d is already freed/unmapped", idx);
mutex_unlock(&tbl.m_lock);
return -EINVAL;
}
mutex_lock(&tbl.bufq[idx].q_lock);
mutex_unlock(&tbl.m_lock);
if (cmd->buf_handle != tbl.bufq[idx].buf_handle) {
CAM_ERR(CAM_MEM,
"Buffer at idx=%d is different incoming handle 0x%x, actual handle 0x%x",
idx, cmd->buf_handle, tbl.bufq[idx].buf_handle);
rc = -EINVAL;
goto end;
}
CAM_DBG(CAM_MEM, "buf_handle=0x%x, access=0x%x, access_type=0x%x, override_access=%d",
cmd->buf_handle, cmd->access, cmd->access_type,
g_cam_mem_mgr_debug.override_cpu_access_dir);
if (cmd->access_type & CAM_MEM_CPU_ACCESS_READ &&
cmd->access_type & CAM_MEM_CPU_ACCESS_WRITE) {
direction = DMA_BIDIRECTIONAL;
} else if (cmd->access_type & CAM_MEM_CPU_ACCESS_READ) {
direction = DMA_FROM_DEVICE;
} else if (cmd->access_type & CAM_MEM_CPU_ACCESS_WRITE) {
direction = DMA_TO_DEVICE;
} else {
direction = DMA_BIDIRECTIONAL;
CAM_WARN(CAM_MEM,
"Invalid access type buf_handle=0x%x, access=0x%x, access_type=0x%x",
cmd->buf_handle, cmd->access, cmd->access_type);
}
if (g_cam_mem_mgr_debug.override_cpu_access_dir)
direction = DMA_BIDIRECTIONAL;
if (cmd->access & CAM_MEM_BEGIN_CPU_ACCESS) {
rc = dma_buf_begin_cpu_access(tbl.bufq[idx].dma_buf, direction);
if (rc) {
CAM_ERR(CAM_MEM,
"dma begin cpu access failed rc=%d, buf_handle=0x%x, access=0x%x, access_type=0x%x",
rc, cmd->buf_handle, cmd->access, cmd->access_type);
goto end;
}
}
if (cmd->access & CAM_MEM_END_CPU_ACCESS) {
rc = dma_buf_end_cpu_access(tbl.bufq[idx].dma_buf, direction);
if (rc) {
CAM_ERR(CAM_MEM,
"dma end cpu access failed rc=%d, buf_handle=0x%x, access=0x%x, access_type=0x%x",
rc, cmd->buf_handle, cmd->access, cmd->access_type);
goto end;
}
}
end:
mutex_unlock(&tbl.bufq[idx].q_lock);
return rc;
}
EXPORT_SYMBOL(cam_mem_mgr_cpu_access_op);
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
#define CAM_MAX_VMIDS 4

View File

@@ -168,6 +168,15 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd_v2 *cmd);
*/
int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd);
/**
* @brief: Perform cpu access ops on the buffer
*
* @cmd: CPU access ops information
*
* @return Status of operation. Negative in case of error. Zero otherwise.
*/
int cam_mem_mgr_cpu_access_op(struct cam_mem_cpu_access_op *cmd);
/**
* @brief: Initializes the memory manager
*

View File

@@ -617,6 +617,22 @@ static long cam_private_ioctl(struct file *file, void *fh,
}
rc = cam_mem_mgr_cache_ops(&cmd);
}
break;
case CAM_REQ_MGR_MEM_CPU_ACCESS_OP: {
struct cam_mem_cpu_access_op cmd;
if (k_ioctl->size != sizeof(cmd))
return -EINVAL;
if (copy_from_user(&cmd,
u64_to_user_ptr(k_ioctl->handle),
sizeof(struct cam_mem_cpu_access_op))) {
rc = -EFAULT;
break;
}
rc = cam_mem_mgr_cpu_access_op(&cmd);
if (rc)
rc = -EINVAL;
}

View File

@@ -344,6 +344,7 @@ struct cam_req_mgr_link_properties {
#define CAM_REQ_MGR_LINK_PROPERTIES (CAM_COMMON_OPCODE_MAX + 17)
#define CAM_REQ_MGR_ALLOC_BUF_V2 (CAM_COMMON_OPCODE_MAX + 18)
#define CAM_REQ_MGR_MAP_BUF_V2 (CAM_COMMON_OPCODE_MAX + 19)
#define CAM_REQ_MGR_MEM_CPU_ACCESS_OP (CAM_COMMON_OPCODE_MAX + 20)
/* end of cam_req_mgr opcodes */
@@ -404,7 +405,6 @@ struct cam_req_mgr_link_properties {
#define CAM_MEM_DMA_TO_DEVICE 2
#define CAM_MEM_DMA_FROM_DEVICE 3
/**
* memory cache operation
*/
@@ -412,6 +412,18 @@ struct cam_req_mgr_link_properties {
#define CAM_MEM_INV_CACHE 2
#define CAM_MEM_CLEAN_INV_CACHE 3
/**
* memory CPU access operation
*/
#define CAM_MEM_BEGIN_CPU_ACCESS BIT(0)
#define CAM_MEM_END_CPU_ACCESS BIT(1)
/**
* memory CPU access type
*/
#define CAM_MEM_CPU_ACCESS_READ BIT(0)
#define CAM_MEM_CPU_ACCESS_WRITE BIT(1)
/**
* struct cam_mem_alloc_out_params
@@ -560,6 +572,33 @@ struct cam_mem_cache_ops_cmd {
__u32 mem_cache_ops;
};
/**
* struct cam_mem_cpu_access_op
* @version: Struct version
* @buf_handle: buffer handle
* @access: CPU access operation. Allowed params :
* CAM_MEM_BEGIN_CPU_ACCESS
* CAM_MEM_END_CPU_ACCESS
* both
* @access_type: CPU access type. Allowed params :
* CAM_MEM_CPU_ACCESS_READ
* CAM_MEM_CPU_ACCESS_WRITE
* both
* @num_valid_params: Valid number of params being used
* @valid_param_mask: Mask to indicate the field types in params
* @params: Additional params
*/
/* CAM_REQ_MGR_MEM_CPU_ACCESS_OP */
struct cam_mem_cpu_access_op {
__u32 version;
__s32 buf_handle;
__u32 access;
__u32 access_type;
__u32 num_valid_params;
__u32 valid_param_mask;
__s32 params[4];
};
/**
* Request Manager : error message type
* @CAM_REQ_MGR_ERROR_TYPE_DEVICE: Device error message, fatal to session