msm: camera: utils: Add logic to maintain unique buffer handle for patch

Currently smmu_get_iova is called for every patch, regardless of the same
source handle. This change avoids this by checking if io virtual address
is already being quried with earlier patch. This can reduce the call and
mutex operation from smmu prospective.

CRs-Fixed: 2711810
Change-Id: I681589cd1328389e0828a3318edad1a2a91d8547
Signed-off-by: Jigarkumar Zala <jzala@codeaurora.org>
这个提交包含在:
Jigarkumar Zala
2020-05-07 15:00:01 -07:00
父节点 f860d9fb11
当前提交 968d954b75

查看文件

@@ -10,6 +10,14 @@
#include "cam_packet_util.h"
#include "cam_debug_util.h"
#define CAM_UNIQUE_SRC_HDL_MAX 50
struct cam_patch_unique_src_buf_tbl {
int32_t hdl;
dma_addr_t iova;
size_t buf_size;
};
int cam_packet_util_get_cmd_mem_addr(int handle, uint32_t **buf_addr,
size_t *len)
{
@@ -207,6 +215,63 @@ void cam_packet_dump_patch_info(struct cam_packet *packet,
}
}
static int cam_packet_util_get_patch_iova(
struct cam_patch_unique_src_buf_tbl *tbl,
int32_t hdl, uint32_t buf_hdl, dma_addr_t *iova, size_t *buf_size)
{
int idx = 0;
int rc = 0;
size_t src_buf_size;
dma_addr_t iova_addr;
bool is_found = false;
for (idx = 0; idx < CAM_UNIQUE_SRC_HDL_MAX; idx++) {
if (buf_hdl == tbl[idx].hdl) {
CAM_DBG(CAM_UTIL,
"Matched entry for src_buf_hdl: 0x%x with src_hdl[%d]: 0x%x",
buf_hdl, idx, tbl[idx].hdl);
*iova = tbl[idx].iova;
*buf_size = tbl[idx].buf_size;
is_found = true;
break;
} else if ((tbl[idx].hdl == 0) || (tbl[idx].iova == 0)) {
CAM_DBG(CAM_UTIL, "New src handle detected 0x%x",
buf_hdl);
is_found = false;
break;
}
CAM_DBG(CAM_UTIL,
"Index: %d is filled with differnt src_hdl: 0x%x",
idx, buf_hdl);
}
if (!is_found) {
CAM_DBG(CAM_UTIL, "src_hdl 0x%x not found in table entries",
buf_hdl);
rc = cam_mem_get_io_buf(buf_hdl, hdl,
&iova_addr, &src_buf_size);
if (rc < 0) {
CAM_ERR(CAM_UTIL,
"unable to get iova for src_hdl: 0x%x",
buf_hdl);
return rc;
}
/* Update the table entry with unique src buf handle */
if (idx < CAM_UNIQUE_SRC_HDL_MAX && tbl[idx].hdl == 0) {
tbl[idx].buf_size = src_buf_size;
tbl[idx].iova = iova_addr;
tbl[idx].hdl = buf_hdl;
CAM_DBG(CAM_UTIL,
"Updated table index: %d with src_buf_hdl: 0x%x",
idx, tbl[idx].hdl);
}
*iova = iova_addr;
*buf_size = src_buf_size;
}
return rc;
}
int cam_packet_util_process_patches(struct cam_packet *packet,
int32_t iommu_hdl, int32_t sec_mmu_hdl)
{
@@ -218,9 +283,14 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
uint32_t *src_buf_iova_addr;
size_t dst_buf_len;
size_t src_buf_size;
int i;
int i = 0;
int rc = 0;
int32_t hdl;
struct cam_patch_unique_src_buf_tbl
tbl[CAM_UNIQUE_SRC_HDL_MAX];
memset(tbl, 0, CAM_UNIQUE_SRC_HDL_MAX *
sizeof(struct cam_patch_unique_src_buf_tbl));
/* process patch descriptor */
patch_desc = (struct cam_patch_desc *)
@@ -233,12 +303,23 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
for (i = 0; i < packet->num_patches; i++) {
hdl = cam_mem_is_secure_buf(patch_desc[i].src_buf_hdl) ?
sec_mmu_hdl : iommu_hdl;
rc = cam_mem_get_io_buf(patch_desc[i].src_buf_hdl,
hdl, &iova_addr, &src_buf_size);
if (rc < 0) {
CAM_ERR(CAM_UTIL, "unable to get src buf address");
rc = cam_packet_util_get_patch_iova(&tbl[0], hdl,
patch_desc[i].src_buf_hdl, &iova_addr, &src_buf_size);
if (rc) {
CAM_ERR(CAM_UTIL,
"get_iova failed for patch[%d], src_buf_hdl: 0x%x: rc: %d",
i, patch_desc[i].src_buf_hdl, rc);
return rc;
}
if ((size_t)patch_desc[i].src_offset >= src_buf_size) {
CAM_ERR(CAM_UTIL,
"Invalid src buf patch offset: patch:src_offset: 0x%x, src_buf_size: %zu",
patch_desc[i].src_offset, src_buf_size);
return -EINVAL;
}
src_buf_iova_addr = (uint32_t *)iova_addr;
temp = iova_addr;
@@ -254,12 +335,6 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
patch_desc[i].dst_buf_hdl, patch_desc[i].dst_offset,
patch_desc[i].src_buf_hdl, patch_desc[i].src_offset);
if ((size_t)patch_desc[i].src_offset >= src_buf_size) {
CAM_ERR(CAM_UTIL,
"Invalid src buf patch offset");
return -EINVAL;
}
if ((dst_buf_len < sizeof(void *)) ||
((dst_buf_len - sizeof(void *)) <
(size_t)patch_desc[i].dst_offset)) {