From 594b59a2df4494ff7a7017407fc3a7ebe6c8468f Mon Sep 17 00:00:00 2001 From: Karthik Anantha Ram Date: Mon, 14 Aug 2023 13:33:05 -0700 Subject: [PATCH] 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 --- drivers/cam_req_mgr/cam_mem_mgr.c | 53 ++++++++++++++++++------- drivers/cam_req_mgr/cam_mem_mgr.h | 8 ++-- drivers/cam_req_mgr/cam_req_mgr_dev.c | 7 +++- include/uapi/camera/media/cam_req_mgr.h | 5 +++ 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index 9575c75ff4..288b833c77 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/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) { - if (tbl.ubwc_p_heap) - return true; + uint64_t heap_caps = 0; - return false; + if (!heap_mask) + return -EINVAL; + + if (tbl.ubwc_p_heap) + heap_caps |= CAM_REQ_MGR_MEM_UBWC_P_HEAP_SUPPORTED; + + 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; } diff --git a/drivers/cam_req_mgr/cam_mem_mgr.h b/drivers/cam_req_mgr/cam_mem_mgr.h index 46954d9e40..c3e39b23f9 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.h +++ b/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 diff --git a/drivers/cam_req_mgr/cam_req_mgr_dev.c b/drivers/cam_req_mgr/cam_req_mgr_dev.c index 7ad066a085..1011f4a0ad 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_dev.c +++ b/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), diff --git a/include/uapi/camera/media/cam_req_mgr.h b/include/uapi/camera/media/cam_req_mgr.h index 1e2ee41f97..896269246f 100644 --- a/include/uapi/camera/media/cam_req_mgr.h +++ b/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