msm: camera: memmgr: Add dma-buf-heaps usage in camera
Use dma-buf-heaps for allocating buffers. Keep ion usage to support kernels without dma-buf-heaps support. CRs-Fixed: 2852327 Change-Id: I3ebcb591827d9b8e5366f716efd08e4cd6f1070a Signed-off-by: Pavan Kumar Chilamkurthi <pchilamk@codeaurora.org>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -22,6 +22,11 @@
|
||||
static struct cam_mem_table tbl;
|
||||
static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||
static void cam_mem_mgr_put_dma_heaps(void);
|
||||
static int cam_mem_mgr_get_dma_heaps(void);
|
||||
#endif
|
||||
|
||||
static void cam_mem_mgr_print_tbl(void)
|
||||
{
|
||||
int i;
|
||||
@@ -163,6 +168,7 @@ int cam_mem_mgr_init(void)
|
||||
{
|
||||
int i;
|
||||
int bitmap_size;
|
||||
int rc = 0;
|
||||
|
||||
memset(tbl.bufq, 0, sizeof(tbl.bufq));
|
||||
|
||||
@@ -171,10 +177,19 @@ int cam_mem_mgr_init(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||
rc = cam_mem_mgr_get_dma_heaps();
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_MEM, "Failed in getting dma heaps rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
bitmap_size = BITS_TO_LONGS(CAM_MEM_BUFQ_MAX) * sizeof(long);
|
||||
tbl.bitmap = kzalloc(bitmap_size, GFP_KERNEL);
|
||||
if (!tbl.bitmap)
|
||||
return -ENOMEM;
|
||||
if (!tbl.bitmap) {
|
||||
rc = -ENOMEM;
|
||||
goto put_heaps;
|
||||
}
|
||||
|
||||
tbl.bits = bitmap_size * BITS_PER_BYTE;
|
||||
bitmap_zero(tbl.bitmap, tbl.bits);
|
||||
@@ -192,6 +207,11 @@ int cam_mem_mgr_init(void)
|
||||
cam_mem_mgr_create_debug_fs();
|
||||
|
||||
return 0;
|
||||
put_heaps:
|
||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||
cam_mem_mgr_put_dma_heaps();
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t cam_mem_get_slot(void)
|
||||
@@ -365,6 +385,10 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd)
|
||||
goto end;
|
||||
}
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||
CAM_DBG(CAM_MEM, "Calling dmap buf APIs for cache operations");
|
||||
cache_dir = DMA_BIDIRECTIONAL;
|
||||
#else
|
||||
if (dmabuf_flag & ION_FLAG_CACHED) {
|
||||
switch (cmd->mem_cache_ops) {
|
||||
case CAM_MEM_CLEAN_CACHE:
|
||||
@@ -386,7 +410,7 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd)
|
||||
CAM_DBG(CAM_MEM, "BUF is not cached");
|
||||
goto end;
|
||||
}
|
||||
|
||||
#endif
|
||||
rc = dma_buf_begin_cpu_access(tbl.bufq[idx].dma_buf,
|
||||
(cmd->mem_cache_ops == CAM_MEM_CLEAN_INV_CACHE) ?
|
||||
DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
|
||||
@@ -408,6 +432,192 @@ end:
|
||||
}
|
||||
EXPORT_SYMBOL(cam_mem_mgr_cache_ops);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||
static void cam_mem_mgr_put_dma_heaps(void)
|
||||
{
|
||||
CAM_DBG(CAM_MEM, "Releasing DMA Buf heaps usage");
|
||||
}
|
||||
|
||||
static int cam_mem_mgr_get_dma_heaps(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
tbl.system_heap = NULL;
|
||||
tbl.system_uncached_heap = NULL;
|
||||
tbl.camera_heap = NULL;
|
||||
tbl.camera_uncached_heap = NULL;
|
||||
tbl.secure_display_heap = NULL;
|
||||
|
||||
tbl.system_heap = dma_heap_find("qcom,system");
|
||||
if (IS_ERR_OR_NULL(tbl.system_heap)) {
|
||||
rc = PTR_ERR(tbl.system_heap);
|
||||
CAM_ERR(CAM_MEM, "qcom system heap not found, rc=%d", rc);
|
||||
tbl.system_heap = NULL;
|
||||
goto put_heaps;
|
||||
}
|
||||
|
||||
tbl.system_uncached_heap = dma_heap_find("qcom,system-uncached");
|
||||
if (IS_ERR_OR_NULL(tbl.system_uncached_heap)) {
|
||||
if (tbl.force_cache_allocs) {
|
||||
/* optional, we anyway do not use uncached */
|
||||
CAM_DBG(CAM_MEM,
|
||||
"qcom system-uncached heap not found, err=%d",
|
||||
PTR_ERR(tbl.system_uncached_heap));
|
||||
tbl.system_uncached_heap = NULL;
|
||||
} else {
|
||||
/* fatal, must need uncached heaps */
|
||||
rc = PTR_ERR(tbl.system_uncached_heap);
|
||||
CAM_ERR(CAM_MEM,
|
||||
"qcom system-uncached heap not found, rc=%d",
|
||||
rc);
|
||||
tbl.system_uncached_heap = NULL;
|
||||
goto put_heaps;
|
||||
}
|
||||
}
|
||||
|
||||
tbl.secure_display_heap = dma_heap_find("qcom,secure-display");
|
||||
if (IS_ERR_OR_NULL(tbl.secure_display_heap)) {
|
||||
rc = PTR_ERR(tbl.secure_display_heap);
|
||||
CAM_ERR(CAM_MEM, "qcom,secure-display heap not found, rc=%d",
|
||||
rc);
|
||||
tbl.secure_display_heap = NULL;
|
||||
goto put_heaps;
|
||||
}
|
||||
|
||||
tbl.camera_heap = dma_heap_find("qcom,camera");
|
||||
if (IS_ERR_OR_NULL(tbl.camera_heap)) {
|
||||
/* optional heap, not a fatal error */
|
||||
CAM_DBG(CAM_MEM, "qcom camera heap not found, err=%d",
|
||||
PTR_ERR(tbl.camera_heap));
|
||||
tbl.camera_heap = NULL;
|
||||
}
|
||||
|
||||
tbl.camera_uncached_heap = dma_heap_find("qcom,camera-uncached");
|
||||
if (IS_ERR_OR_NULL(tbl.camera_uncached_heap)) {
|
||||
/* optional heap, not a fatal error */
|
||||
CAM_DBG(CAM_MEM, "qcom camera heap not found, err=%d",
|
||||
PTR_ERR(tbl.camera_uncached_heap));
|
||||
tbl.camera_uncached_heap = NULL;
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_MEM,
|
||||
"Heaps : system=%pK, system_uncached=%pK, camera=%pK, camera-uncached=%pK, secure_display=%pK",
|
||||
tbl.system_heap, tbl.system_uncached_heap,
|
||||
tbl.camera_heap, tbl.camera_uncached_heap,
|
||||
tbl.secure_display_heap);
|
||||
|
||||
return 0;
|
||||
put_heaps:
|
||||
cam_mem_mgr_put_dma_heaps();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_mem_util_get_dma_buf(size_t len,
|
||||
unsigned int cam_flags,
|
||||
struct dma_buf **buf)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dma_heap *heap;
|
||||
struct dma_heap *try_heap = NULL;
|
||||
struct timespec64 ts1, ts2;
|
||||
long microsec = 0;
|
||||
bool use_cached_heap = false;
|
||||
|
||||
if (!buf) {
|
||||
CAM_ERR(CAM_MEM, "Invalid params");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tbl.alloc_profile_enable)
|
||||
CAM_GET_TIMESTAMP(ts1);
|
||||
|
||||
if ((cam_flags & CAM_MEM_FLAG_CACHE) ||
|
||||
(tbl.force_cache_allocs &&
|
||||
(!(cam_flags & CAM_MEM_FLAG_PROTECTED_MODE)))) {
|
||||
CAM_DBG(CAM_MEM,
|
||||
"Using CACHED heap, cam_flags=0x%x, force_cache_allocs=%d",
|
||||
cam_flags, tbl.force_cache_allocs);
|
||||
use_cached_heap = true;
|
||||
} else if (cam_flags & CAM_MEM_FLAG_PROTECTED_MODE) {
|
||||
use_cached_heap = true;
|
||||
CAM_DBG(CAM_MEM,
|
||||
"Using CACHED heap for secure, cam_flags=0x%x, force_cache_allocs=%d",
|
||||
cam_flags, tbl.force_cache_allocs);
|
||||
} else {
|
||||
use_cached_heap = false;
|
||||
CAM_ERR(CAM_MEM,
|
||||
"Using UNCACHED heap not supported, cam_flags=0x%x, force_cache_allocs=%d",
|
||||
cam_flags, tbl.force_cache_allocs);
|
||||
/*
|
||||
* Need a better handling based on whether dma-buf-heaps support
|
||||
* uncached heaps or not. For now, assume not supported.
|
||||
*/
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((cam_flags & CAM_MEM_FLAG_PROTECTED_MODE) &&
|
||||
(cam_flags & CAM_MEM_FLAG_CDSP_OUTPUT)) {
|
||||
heap = tbl.secure_display_heap;
|
||||
CAM_ERR(CAM_MEM, "Secure CDSP not supported yet");
|
||||
return -EBADR;
|
||||
} else if (cam_flags & CAM_MEM_FLAG_PROTECTED_MODE) {
|
||||
heap = tbl.secure_display_heap;
|
||||
CAM_ERR(CAM_MEM, "Secure mode not supported yet");
|
||||
return -EBADR;
|
||||
}
|
||||
|
||||
if (use_cached_heap) {
|
||||
try_heap = tbl.camera_heap;
|
||||
heap = tbl.system_heap;
|
||||
} else {
|
||||
try_heap = tbl.camera_uncached_heap;
|
||||
heap = tbl.system_uncached_heap;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_MEM, "Using heaps : try=%pK, heap=%pK", try_heap, heap);
|
||||
|
||||
*buf = NULL;
|
||||
|
||||
if (!try_heap && !heap) {
|
||||
CAM_ERR(CAM_MEM,
|
||||
"No heap available for allocation, cant allocate");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (try_heap) {
|
||||
*buf = dma_heap_buffer_alloc(try_heap, len, O_RDWR, 0);
|
||||
if (IS_ERR_OR_NULL(*buf)) {
|
||||
CAM_WARN(CAM_MEM,
|
||||
"Failed in allocating from try heap, heap=%pK, len=%zu, err=%d",
|
||||
try_heap, len, PTR_ERR(*buf));
|
||||
*buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (*buf == NULL) {
|
||||
*buf = dma_heap_buffer_alloc(heap, len, O_RDWR, 0);
|
||||
if (IS_ERR_OR_NULL(*buf)) {
|
||||
rc = PTR_ERR(*buf);
|
||||
CAM_ERR(CAM_MEM,
|
||||
"Failed in allocating from heap, heap=%pK, len=%zu, err=%d",
|
||||
heap, len, rc);
|
||||
*buf = NULL;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_MEM, "Allocate success, len=%zu, *buf=%pK", len, *buf);
|
||||
|
||||
if (tbl.alloc_profile_enable) {
|
||||
CAM_GET_TIMESTAMP(ts2);
|
||||
CAM_GET_TIMESTAMP_DIFF_IN_MICRO(ts1, ts2, microsec);
|
||||
trace_cam_log_event("IONAllocProfile", "size and time in micro",
|
||||
len, microsec);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static int cam_mem_util_get_dma_buf(size_t len,
|
||||
unsigned int cam_flags,
|
||||
struct dma_buf **buf)
|
||||
@@ -460,8 +670,9 @@ static int cam_mem_util_get_dma_buf(size_t len,
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cam_mem_util_ion_alloc(struct cam_mem_mgr_alloc_cmd *cmd,
|
||||
static int cam_mem_util_buffer_alloc(struct cam_mem_mgr_alloc_cmd *cmd,
|
||||
struct dma_buf **dmabuf,
|
||||
int *fd)
|
||||
{
|
||||
@@ -485,6 +696,9 @@ static int cam_mem_util_ion_alloc(struct cam_mem_mgr_alloc_cmd *cmd,
|
||||
goto put_buf;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_MEM, "Alloc success : len=%zu, *dmabuf=%pK, fd=%d",
|
||||
cmd->len, *dmabuf, *fd);
|
||||
|
||||
/*
|
||||
* increment the ref count so that ref count becomes 2 here
|
||||
* when we close fd, refcount becomes 1 and when we do
|
||||
@@ -655,7 +869,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_mem_util_ion_alloc(cmd,
|
||||
rc = cam_mem_util_buffer_alloc(cmd,
|
||||
&dmabuf,
|
||||
&fd);
|
||||
if (rc) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_MEM_MGR_H_
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||
#include <linux/dma-heap.h>
|
||||
#endif
|
||||
#include <media/cam_req_mgr.h>
|
||||
#include "cam_mem_mgr_api.h"
|
||||
|
||||
@@ -81,6 +84,14 @@ struct cam_mem_table {
|
||||
bool alloc_profile_enable;
|
||||
size_t dbg_buf_idx;
|
||||
bool force_cache_allocs;
|
||||
#if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
|
||||
struct dma_heap *system_heap;
|
||||
struct dma_heap *system_uncached_heap;
|
||||
struct dma_heap *camera_heap;
|
||||
struct dma_heap *camera_uncached_heap;
|
||||
struct dma_heap *secure_display_heap;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -2100,8 +2100,9 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf,
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SMMU,
|
||||
"iova=%pK, region_id=%d, paddr=%pK, len=%d, dma_map_attrs=%d",
|
||||
iova, region_id, *paddr_ptr, *len_ptr, attach->dma_map_attrs);
|
||||
"iova=%pK, region_id=%d, paddr=0x%x, len=%d, dma_map_attrs=%d",
|
||||
iova, region_id, (uint64_t)*paddr_ptr, *len_ptr,
|
||||
attach->dma_map_attrs);
|
||||
|
||||
if (iommu_cb_set.map_profile_enable) {
|
||||
CAM_GET_TIMESTAMP(ts2);
|
||||
@@ -2148,7 +2149,8 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf,
|
||||
rc = -ENOSPC;
|
||||
goto err_alloc;
|
||||
}
|
||||
CAM_DBG(CAM_SMMU, "idx=%d, dma_buf=%pK, dev=%pK, paddr=%pK, len=%u",
|
||||
|
||||
CAM_DBG(CAM_SMMU, "idx=%d, dma_buf=%pK, dev=%pK, paddr=0x%x, len=%u",
|
||||
idx, buf, (void *)iommu_cb_set.cb_info[idx].dev,
|
||||
(void *)*paddr_ptr, (unsigned int)*len_ptr);
|
||||
|
||||
@@ -2267,7 +2269,7 @@ static int cam_smmu_unmap_buf_and_remove_from_list(
|
||||
mapping_info);
|
||||
|
||||
CAM_DBG(CAM_SMMU,
|
||||
"region_id=%d, paddr=%pK, len=%d, dma_map_attrs=%d",
|
||||
"region_id=%d, paddr=0x%x, len=%d, dma_map_attrs=%d",
|
||||
mapping_info->region_id, mapping_info->paddr, mapping_info->len,
|
||||
mapping_info->attach->dma_map_attrs);
|
||||
|
||||
|
Reference in New Issue
Block a user