Browse Source

msm: camera: memmgr: Add provision for heap selection

Currently, userland can only choose whether to allocate memory as
cached/uncached if it's a protected buffer, ubwc_p buffer, etc.
This change provides some more granularity in terms of heap selection.
One could now force an allocation from the system heap or
try a dedicated heap. The change also provides heap capability info
to userland as part of the query caps call.

CRs-Fixed: 3584481
Change-Id: Id4c92fd64d975f761e7dd4cecca8453dd09b039f
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 1 year ago
parent
commit
594b59a2df

+ 37 - 14
drivers/cam_req_mgr/cam_mem_mgr.c

@@ -828,12 +828,21 @@ put_heaps:
 	return rc;
 }
 
-bool cam_mem_mgr_ubwc_p_heap_supported(void)
+int cam_mem_mgr_check_for_supported_heaps(uint64_t *heap_mask)
 {
+	uint64_t heap_caps = 0;
+
+	if (!heap_mask)
+		return -EINVAL;
+
 	if (tbl.ubwc_p_heap)
-		return true;
+		heap_caps |= CAM_REQ_MGR_MEM_UBWC_P_HEAP_SUPPORTED;
 
-	return false;
+	if ((tbl.camera_heap) || (tbl.camera_uncached_heap))
+		heap_caps |= CAM_REQ_MGR_MEM_CAMERA_HEAP_SUPPORTED;
+
+	*heap_mask = heap_caps;
+	return 0;
 }
 
 static int cam_mem_util_get_dma_buf(size_t len,
@@ -843,8 +852,7 @@ static int cam_mem_util_get_dma_buf(size_t len,
 	unsigned long *i_ino)
 {
 	int rc = 0;
-	struct dma_heap *heap;
-	struct dma_heap *try_heap = NULL;
+	struct dma_heap *heap = NULL, *try_heap = NULL;
 	struct timespec64 ts1, ts2;
 	long microsec = 0;
 	bool use_cached_heap = false;
@@ -875,7 +883,7 @@ static int cam_mem_util_get_dma_buf(size_t len,
 			cam_flags, tbl.force_cache_allocs);
 	} else {
 		use_cached_heap = false;
-		if (!tbl.system_uncached_heap) {
+		if (!tbl.system_uncached_heap && !tbl.camera_uncached_heap) {
 			CAM_ERR(CAM_MEM,
 				"Using UNCACHED heap not supported, cam_flags=0x%x, force_cache_allocs=%d",
 				cam_flags, tbl.force_cache_allocs);
@@ -919,15 +927,29 @@ static int cam_mem_util_get_dma_buf(size_t len,
 		CAM_DBG(CAM_MEM, "Allocating from ubwc-p heap %pK, size=%d, flags=0x%x",
 			heap, len, cam_flags);
 	} else if (use_cached_heap) {
-		try_heap = tbl.camera_heap;
 
-		if (tbl.system_movable_heap && (alloc_type == CAM_MEMMGR_ALLOC_USER))
-			heap = tbl.system_movable_heap;
-		else
-			heap = tbl.system_heap;
+		/*
+		 * The default scheme is to try allocating from the camera heap
+		 * if available; if not, try for the system heap. Userland can also select
+		 * to pick a specific heap for allocation; this will deviate from the
+		 * default selection scheme.
+		 *
+		 */
+		if (!(cam_flags & CAM_MEM_FLAG_USE_SYS_HEAP_ONLY))
+			try_heap = tbl.camera_heap;
+
+		if (!(cam_flags & CAM_MEM_FLAG_USE_CAMERA_HEAP_ONLY)) {
+			if (tbl.system_movable_heap && (alloc_type == CAM_MEMMGR_ALLOC_USER))
+				heap = tbl.system_movable_heap;
+			else
+				heap = tbl.system_heap;
+		}
 	} else {
-		try_heap = tbl.camera_uncached_heap;
-		heap = tbl.system_uncached_heap;
+		if (!(cam_flags & CAM_MEM_FLAG_USE_SYS_HEAP_ONLY))
+			try_heap = tbl.camera_uncached_heap;
+
+		if (!(cam_flags & CAM_MEM_FLAG_USE_CAMERA_HEAP_ONLY))
+			heap = tbl.system_uncached_heap;
 	}
 
 	CAM_DBG(CAM_MEM, "Using heaps : try=%pK, heap=%pK", try_heap, heap);
@@ -936,7 +958,8 @@ static int cam_mem_util_get_dma_buf(size_t len,
 
 	if (!try_heap && !heap) {
 		CAM_ERR(CAM_MEM,
-			"No heap available for allocation, cant allocate");
+			"No heap available for allocation, can't allocate flag: 0x%x",
+			cam_flags);
 		return -EINVAL;
 	}
 

+ 5 - 3
drivers/cam_req_mgr/cam_mem_mgr.h

@@ -224,11 +224,13 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd);
 int cam_mem_mgr_cpu_access_op(struct cam_mem_cpu_access_op *cmd);
 
 /**
- * @brief: Check whether ubwc-p heap is supported
+ * @brief: Provide all supported heap capabilities
  *
- * @return true if supported, false otherwise
+ * @heap_mask: Update mask for all supported heaps
+ *
+ * @return Status of operation. Negative in case of error. Zero otherwise.
  */
-bool cam_mem_mgr_ubwc_p_heap_supported(void);
+int cam_mem_mgr_check_for_supported_heaps(uint64_t *heap_mask);
 
 /**
  * @brief: Initializes the memory manager

+ 5 - 2
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -751,8 +751,11 @@ static long cam_private_ioctl(struct file *file, void *fh,
 
 		cmd.feature_mask = 0;
 
-		if (cam_mem_mgr_ubwc_p_heap_supported())
-			cmd.feature_mask |= CAM_REQ_MGR_MEM_UBWC_P_HEAP_SUPPORTED;
+		rc = cam_mem_mgr_check_for_supported_heaps(&cmd.feature_mask);
+		if (rc) {
+			CAM_ERR(CAM_CRM, "Failed to retrieve heap capability rc: %d", rc);
+			break;
+		}
 
 		if (copy_to_user(
 			u64_to_user_ptr(k_ioctl->handle),

+ 5 - 0
include/uapi/camera/media/cam_req_mgr.h

@@ -371,7 +371,11 @@ struct cam_req_mgr_link_properties {
 #define CAM_MEM_FLAG_EVA_NOPIXEL                (1<<15)
 #define CAM_MEM_FLAG_HW_AND_CDM_OR_SHARED       (1<<16)
 #define CAM_MEM_FLAG_UBWC_P_HEAP                (1<<17)
+/* Allocation forced to camera heap */
+#define CAM_MEM_FLAG_USE_CAMERA_HEAP_ONLY       (1<<18)
 
+/* Allocation forced to system heap */
+#define CAM_MEM_FLAG_USE_SYS_HEAP_ONLY          (1<<19)
 
 #define CAM_MEM_MMU_MAX_HANDLE                  16
 
@@ -434,6 +438,7 @@ struct cam_req_mgr_link_properties {
  * Feature mask returned in query_cap
  */
 #define CAM_REQ_MGR_MEM_UBWC_P_HEAP_SUPPORTED   BIT(0)
+#define CAM_REQ_MGR_MEM_CAMERA_HEAP_SUPPORTED   BIT(1)
 
 /**
  * struct cam_req_mgr_query_cap