瀏覽代碼

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 <[email protected]>
Pavan Kumar Chilamkurthi 3 年之前
父節點
當前提交
5af17aad2a

+ 95 - 2
drivers/cam_req_mgr/cam_mem_mgr.c

@@ -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
- * @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 {
 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

+ 9 - 0
drivers/cam_req_mgr/cam_mem_mgr.h

@@ -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
  *
  *

+ 16 - 0
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -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;
 		}
 		}

+ 40 - 1
include/uapi/camera/media/cam_req_mgr.h

@@ -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