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:

committed by
Camera Software Integration

parent
909b2ed98e
commit
5af17aad2a
@@ -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
|
/* cam_mem_mgr_debug - global struct to keep track of debug settings for mem mgr
|
||||||
*
|
*
|
||||||
* @dentry : Directory entry to the mem mgr root folder
|
* @dentry : Directory entry to the mem mgr root folder
|
||||||
* @alloc_profile_enable : Whether to enable alloc profiling
|
* @alloc_profile_enable : Whether to enable alloc profiling
|
||||||
|
* @override_cpu_access_dir : Override cpu access direction to BIDIRECTIONAL
|
||||||
*/
|
*/
|
||||||
static struct {
|
static struct {
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
bool alloc_profile_enable;
|
bool alloc_profile_enable;
|
||||||
|
bool override_cpu_access_dir;
|
||||||
} g_cam_mem_mgr_debug;
|
} g_cam_mem_mgr_debug;
|
||||||
|
|
||||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
#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,
|
debugfs_create_bool("alloc_profile_enable", 0644, g_cam_mem_mgr_debug.dentry,
|
||||||
&g_cam_mem_mgr_debug.alloc_profile_enable);
|
&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:
|
end:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -472,6 +477,94 @@ end:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cam_mem_mgr_cache_ops);
|
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)
|
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||||
|
|
||||||
#define CAM_MAX_VMIDS 4
|
#define CAM_MAX_VMIDS 4
|
||||||
|
@@ -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);
|
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
|
* @brief: Initializes the memory manager
|
||||||
*
|
*
|
||||||
|
@@ -617,6 +617,22 @@ static long cam_private_ioctl(struct file *file, void *fh,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = cam_mem_mgr_cache_ops(&cmd);
|
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)
|
if (rc)
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
}
|
}
|
||||||
|
@@ -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_LINK_PROPERTIES (CAM_COMMON_OPCODE_MAX + 17)
|
||||||
#define CAM_REQ_MGR_ALLOC_BUF_V2 (CAM_COMMON_OPCODE_MAX + 18)
|
#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_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 */
|
/* 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_TO_DEVICE 2
|
||||||
#define CAM_MEM_DMA_FROM_DEVICE 3
|
#define CAM_MEM_DMA_FROM_DEVICE 3
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memory cache operation
|
* memory cache operation
|
||||||
*/
|
*/
|
||||||
@@ -412,6 +412,18 @@ struct cam_req_mgr_link_properties {
|
|||||||
#define CAM_MEM_INV_CACHE 2
|
#define CAM_MEM_INV_CACHE 2
|
||||||
#define CAM_MEM_CLEAN_INV_CACHE 3
|
#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
|
* struct cam_mem_alloc_out_params
|
||||||
@@ -560,6 +572,33 @@ struct cam_mem_cache_ops_cmd {
|
|||||||
__u32 mem_cache_ops;
|
__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
|
* Request Manager : error message type
|
||||||
* @CAM_REQ_MGR_ERROR_TYPE_DEVICE: Device error message, fatal to session
|
* @CAM_REQ_MGR_ERROR_TYPE_DEVICE: Device error message, fatal to session
|
||||||
|
Reference in New Issue
Block a user