diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index 7f16de3a61..bb6ccbdf80 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -583,6 +583,7 @@ static int cam_mem_mgr_get_dma_heaps(void) tbl.camera_heap = NULL; tbl.camera_uncached_heap = NULL; tbl.secure_display_heap = NULL; + tbl.ubwc_p_heap = NULL; tbl.system_heap = dma_heap_find("qcom,system"); if (IS_ERR_OR_NULL(tbl.system_heap)) { @@ -611,6 +612,12 @@ static int cam_mem_mgr_get_dma_heaps(void) } } + tbl.ubwc_p_heap = dma_heap_find("qcom,ubwcp"); + if (IS_ERR_OR_NULL(tbl.ubwc_p_heap)) { + CAM_DBG(CAM_MEM, "qcom ubwcp heap not found, err=%d", PTR_ERR(tbl.ubwc_p_heap)); + tbl.ubwc_p_heap = NULL; + } + tbl.secure_display_heap = dma_heap_find("qcom,display"); if (IS_ERR_OR_NULL(tbl.secure_display_heap)) { rc = PTR_ERR(tbl.secure_display_heap); @@ -637,10 +644,10 @@ static int cam_mem_mgr_get_dma_heaps(void) } CAM_INFO(CAM_MEM, - "Heaps : system=%pK, system_uncached=%pK, camera=%pK, camera-uncached=%pK, secure_display=%pK", + "Heaps : system=%pK, system_uncached=%pK, camera=%pK, camera-uncached=%pK, secure_display=%pK, ubwc_p_heap=%pK", tbl.system_heap, tbl.system_uncached_heap, tbl.camera_heap, tbl.camera_uncached_heap, - tbl.secure_display_heap); + tbl.secure_display_heap, tbl.ubwc_p_heap); return 0; put_heaps: @@ -648,6 +655,14 @@ put_heaps: return rc; } +bool cam_mem_mgr_ubwc_p_heap_supported(void) +{ + if (tbl.ubwc_p_heap) + return true; + + return false; +} + static int cam_mem_util_get_dma_buf(size_t len, unsigned int cam_flags, struct dma_buf **buf, @@ -715,6 +730,15 @@ static int cam_mem_util_get_dma_buf(size_t len, vmids[num_vmids] = VMID_CP_NON_PIXEL; perms[num_vmids] = PERM_READ | PERM_WRITE; num_vmids++; + } else if (cam_flags & CAM_MEM_FLAG_UBWC_P_HEAP) { + if (!tbl.ubwc_p_heap) { + CAM_ERR(CAM_MEM, "ubwc-p heap is not available, can't allocate"); + return -EINVAL; + } + + heap = tbl.ubwc_p_heap; + CAM_DBG(CAM_MEM, "Allocating from ubwc-p heap, size=%d, flags=0x%x", + len, cam_flags); } else if (use_cached_heap) { try_heap = tbl.camera_heap; heap = tbl.system_heap; @@ -793,6 +817,12 @@ end: return rc; } #else + +bool cam_mem_mgr_ubwc_p_heap_supported(void) +{ + return false; +} + static int cam_mem_util_get_dma_buf(size_t len, unsigned int cam_flags, struct dma_buf **buf, @@ -809,6 +839,11 @@ static int cam_mem_util_get_dma_buf(size_t len, return -EINVAL; } + if (cam_flags & CAM_MEM_FLAG_UBWC_P_HEAP) { + CAM_ERR(CAM_MEM, "ubwcp heap not supported"); + return -EINVAL; + } + if (g_cam_mem_mgr_debug.alloc_profile_enable) CAM_GET_TIMESTAMP(ts1); @@ -905,11 +940,25 @@ static int cam_mem_util_check_alloc_flags(struct cam_mem_mgr_alloc_cmd_v2 *cmd) if ((cmd->flags & CAM_MEM_FLAG_EVA_NOPIXEL) && (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE || - cmd->flags & CAM_MEM_FLAG_KMD_ACCESS)){ + cmd->flags & CAM_MEM_FLAG_KMD_ACCESS)) { CAM_ERR(CAM_MEM, "Kernel mapping and secure mode not allowed in no pixel mode"); return -EINVAL; } + + if (cmd->flags & CAM_MEM_FLAG_UBWC_P_HEAP && + (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE || + cmd->flags & CAM_MEM_FLAG_EVA_NOPIXEL || + cmd->flags & CAM_MEM_FLAG_KMD_ACCESS || + cmd->flags & CAM_MEM_FLAG_CMD_BUF_TYPE || + cmd->flags & CAM_MEM_FLAG_HW_SHARED_ACCESS || + cmd->flags & CAM_MEM_FLAG_HW_AND_CDM_OR_SHARED)) { + CAM_ERR(CAM_MEM, + "UBWC-P buffer not supported with this combinatation of flags 0x%x", + cmd->flags); + return -EINVAL; + } + return 0; } diff --git a/drivers/cam_req_mgr/cam_mem_mgr.h b/drivers/cam_req_mgr/cam_mem_mgr.h index ed406c5ceb..a3160421d0 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.h +++ b/drivers/cam_req_mgr/cam_mem_mgr.h @@ -94,6 +94,7 @@ struct cam_mem_buf_queue { * @camera_heap: Handle to camera heap * @camera_uncached_heap: Handle to camera uncached heap * @secure_display_heap: Handle to secure display heap + * @ubwc_p_heap: Handle to ubwc-p heap */ struct cam_mem_table { struct mutex m_lock; @@ -109,6 +110,7 @@ struct cam_mem_table { struct dma_heap *camera_heap; struct dma_heap *camera_uncached_heap; struct dma_heap *secure_display_heap; + struct dma_heap *ubwc_p_heap; #endif }; @@ -177,6 +179,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 + * + * @return true if supported, false otherwise + */ +bool cam_mem_mgr_ubwc_p_heap_supported(void); + /** * @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 e9da40ecc5..1683f6ce04 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/cam_req_mgr/cam_req_mgr_dev.c @@ -333,7 +333,7 @@ static int cam_unsubscribe_event(struct v4l2_fh *fh, static long cam_private_ioctl(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg) { - int rc; + int rc = 0; struct cam_control *k_ioctl; if ((!arg) || (cmd != VIDIOC_CAM_CONTROL)) @@ -701,6 +701,30 @@ static long cam_private_ioctl(struct file *file, void *fh, rc = -EBADRQC; CAM_ERR(CAM_CRM, "Unsupported Opcode: %d", k_ioctl->op_code); break; + case CAM_REQ_MGR_QUERY_CAP: { + struct cam_req_mgr_query_cap cmd; + + if (k_ioctl->size != sizeof(cmd)) + return -EINVAL; + + if (copy_from_user(&cmd, + u64_to_user_ptr(k_ioctl->handle), + sizeof(struct cam_req_mgr_query_cap))) { + rc = -EFAULT; + break; + } + + cmd.feature_mask = 0; + + if (cam_mem_mgr_ubwc_p_heap_supported()) + cmd.feature_mask |= CAM_REQ_MGR_MEM_UBWC_P_HEAP_SUPPORTED; + + if (copy_to_user( + u64_to_user_ptr(k_ioctl->handle), + &cmd, sizeof(struct cam_req_mgr_query_cap))) + rc = -EFAULT; + } + break; default: CAM_ERR(CAM_CRM, "Invalid Opcode %d", k_ioctl->op_code); rc = -ENOIOCTLCMD; diff --git a/include/uapi/camera/media/cam_req_mgr.h b/include/uapi/camera/media/cam_req_mgr.h index 22e44efbcb..73f493b117 100644 --- a/include/uapi/camera/media/cam_req_mgr.h +++ b/include/uapi/camera/media/cam_req_mgr.h @@ -345,6 +345,7 @@ struct cam_req_mgr_link_properties { #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_MEM_CPU_ACCESS_OP (CAM_COMMON_OPCODE_MAX + 20) +#define CAM_REQ_MGR_QUERY_CAP (CAM_COMMON_OPCODE_MAX + 21) /* end of cam_req_mgr opcodes */ @@ -365,6 +366,7 @@ struct cam_req_mgr_link_properties { #define CAM_MEM_FLAG_KMD_DEBUG_FLAG (1<<14) #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) #define CAM_MEM_MMU_MAX_HANDLE 16 @@ -424,6 +426,26 @@ struct cam_req_mgr_link_properties { #define CAM_MEM_CPU_ACCESS_READ BIT(0) #define CAM_MEM_CPU_ACCESS_WRITE BIT(1) +/** + * Feature mask returned in query_cap + */ +#define CAM_REQ_MGR_MEM_UBWC_P_HEAP_SUPPORTED BIT(0) + +/** + * struct cam_req_mgr_query_cap + * @version: Struct version + * @feature_mask Supported features + * @num_valid_params: Valid number of params being used + * @valid_param_mask: Mask to indicate the field types in params + * @params: Additional params + */ +struct cam_req_mgr_query_cap { + __u32 version; + __u64 feature_mask; + __u32 num_valid_params; + __u32 valid_param_mask; + __s32 params[5]; +}; /** * struct cam_mem_alloc_out_params