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 <quic_kartanan@quicinc.com>
This commit is contained in:
Karthik Anantha Ram
2023-08-14 13:33:05 -07:00
committed by Camera Software Integration
parent 1dd093a770
commit 594b59a2df
4 changed files with 53 additions and 20 deletions

View File

@@ -828,12 +828,21 @@ put_heaps:
return rc; 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) uint64_t heap_caps = 0;
return true;
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, 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) unsigned long *i_ino)
{ {
int rc = 0; int rc = 0;
struct dma_heap *heap; struct dma_heap *heap = NULL, *try_heap = NULL;
struct dma_heap *try_heap = NULL;
struct timespec64 ts1, ts2; struct timespec64 ts1, ts2;
long microsec = 0; long microsec = 0;
bool use_cached_heap = false; 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); cam_flags, tbl.force_cache_allocs);
} else { } else {
use_cached_heap = false; use_cached_heap = false;
if (!tbl.system_uncached_heap) { if (!tbl.system_uncached_heap && !tbl.camera_uncached_heap) {
CAM_ERR(CAM_MEM, CAM_ERR(CAM_MEM,
"Using UNCACHED heap not supported, cam_flags=0x%x, force_cache_allocs=%d", "Using UNCACHED heap not supported, cam_flags=0x%x, force_cache_allocs=%d",
cam_flags, tbl.force_cache_allocs); 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", CAM_DBG(CAM_MEM, "Allocating from ubwc-p heap %pK, size=%d, flags=0x%x",
heap, len, cam_flags); heap, len, cam_flags);
} else if (use_cached_heap) { } 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; * The default scheme is to try allocating from the camera heap
else * if available; if not, try for the system heap. Userland can also select
heap = tbl.system_heap; * 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 { } else {
try_heap = tbl.camera_uncached_heap; if (!(cam_flags & CAM_MEM_FLAG_USE_SYS_HEAP_ONLY))
heap = tbl.system_uncached_heap; 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); 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) { if (!try_heap && !heap) {
CAM_ERR(CAM_MEM, 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; return -EINVAL;
} }

View File

@@ -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); 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 * @brief: Initializes the memory manager

View File

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

View File

@@ -371,7 +371,11 @@ struct cam_req_mgr_link_properties {
#define CAM_MEM_FLAG_EVA_NOPIXEL (1<<15) #define CAM_MEM_FLAG_EVA_NOPIXEL (1<<15)
#define CAM_MEM_FLAG_HW_AND_CDM_OR_SHARED (1<<16) #define CAM_MEM_FLAG_HW_AND_CDM_OR_SHARED (1<<16)
#define CAM_MEM_FLAG_UBWC_P_HEAP (1<<17) #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 #define CAM_MEM_MMU_MAX_HANDLE 16
@@ -434,6 +438,7 @@ struct cam_req_mgr_link_properties {
* Feature mask returned in query_cap * Feature mask returned in query_cap
*/ */
#define CAM_REQ_MGR_MEM_UBWC_P_HEAP_SUPPORTED BIT(0) #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 * struct cam_req_mgr_query_cap