msm: camera: isp: Read last consumed addr again if no matching res

Bus layer just read the consumed address from one port per group,
sometimes, this port isn't requested by userland, so it can't
match with any requested resources. This change reads consumed
address from other port which in same composite group if the buf
done event can't match any requested resources.

CRs-Fixed: 3590441
Change-Id: I1590e9a53ef7eff1df65682ae4ca77b011d1af39
Signed-off-by: Depeng Shao <quic_depengs@quicinc.com>
(cherry picked from commit 3ec040334581d347916871429de9374555656e4d)
This commit is contained in:
Depeng Shao
2023-08-31 07:20:58 +05:30
committed by Sridhar Gujje
부모 e01a63cc4f
커밋 56bb12e64b
11개의 변경된 파일297개의 추가작업 그리고 33개의 파일을 삭제

파일 보기

@@ -1880,7 +1880,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
struct cam_isp_hw_done_event_data *done_next_req)
{
int rc = 0;
int i, j;
int i, j, k;
bool not_found = false;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
const char *handle_type;
@@ -1902,7 +1903,38 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
break;
}
if (done->hw_type == CAM_ISP_HW_TYPE_SFE)
comp_grp = &ctx_isp->sfe_bus_comp_grp[done->comp_group_id];
else
comp_grp = &ctx_isp->vfe_bus_comp_grp[done->comp_group_id];
if (!comp_grp) {
CAM_ERR(CAM_ISP, "comp_grp is NULL");
rc = -EINVAL;
return rc;
}
if (i == req_isp->num_fence_map_out) {
for (j = 0; j < comp_grp->num_res; j++) {
not_found = false;
if (comp_grp->res_id[j] == done->resource_handle)
continue;
for (k = 0; k < req_isp->num_fence_map_out; k++)
if (comp_grp->res_id[j] ==
req_isp->fence_map_out[k].resource_handle)
break;
if ((k == req_isp->num_fence_map_out) && (j != comp_grp->num_res - 1))
continue;
else if (k != req_isp->num_fence_map_out)
break;
else
not_found = true;
}
}
if (not_found) {
/*
* If not found in current request, it could be
* belonging to next request, this can happen if
@@ -1922,17 +1954,6 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
goto check_deferred;
}
if (done->hw_type == CAM_ISP_HW_TYPE_SFE)
comp_grp = &ctx_isp->sfe_bus_comp_grp[done->comp_group_id];
else
comp_grp = &ctx_isp->vfe_bus_comp_grp[done->comp_group_id];
if (!comp_grp) {
CAM_ERR(CAM_ISP, "comp_grp is NULL");
rc = -EINVAL;
return rc;
}
for (i = 0; i < comp_grp->num_res; i++) {
for (j = 0; j < req_isp->num_fence_map_out; j++) {
if (comp_grp->res_id[i] ==
@@ -2177,6 +2198,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
{
int rc = 0;
int i, j, k, def_idx;
bool not_found = false;
bool duplicate_defer_buf_done = false;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
@@ -2184,6 +2206,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
uint32_t cmp_addr = 0;
struct cam_isp_hw_done_event_data unhandled_done = {0};
struct cam_isp_context_comp_record *comp_grp = NULL;
struct cam_hw_cmd_args hw_cmd_args;
struct cam_isp_hw_cmd_args isp_hw_cmd_args;
trace_cam_buf_done("ISP", ctx, req);
@@ -2207,26 +2231,6 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
}
}
if (i == req_isp->num_fence_map_out) {
/*
* If not found in current request, it could be
* belonging to next request, this can happen if
* IRQ delay happens. It is only valid when the
* platform doesn't have last consumed address.
*/
CAM_WARN(CAM_ISP,
"BUF_DONE for res %s not found in Req %lld ",
__cam_isp_resource_handle_id_to_type(
ctx_isp->isp_device_type, done->resource_handle),
req->request_id);
unhandled_done.hw_type = done->hw_type;
unhandled_done.resource_handle = done->resource_handle;
unhandled_done.comp_group_id = done->comp_group_id;
unhandled_done.last_consumed_addr = done->last_consumed_addr;
goto check_deferred;
}
if (done->hw_type == CAM_ISP_HW_TYPE_SFE)
comp_grp = &ctx_isp->sfe_bus_comp_grp[done->comp_group_id];
else
@@ -2238,6 +2242,91 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
return rc;
}
if (i == req_isp->num_fence_map_out) {
not_found = true;
for (j = 0; j < comp_grp->num_res; j++) {
/* If the res is same with original res, we don't need to read again */
if (comp_grp->res_id[j] == done->resource_handle)
continue;
/* Check if the res in the requested list */
for (k = 0; k < req_isp->num_fence_map_out; k++)
if (comp_grp->res_id[j] ==
req_isp->fence_map_out[k].resource_handle)
break;
/* If res_id[j] isn't in requested list, then try next res in the group */
if (k == req_isp->num_fence_map_out) {
if (j != comp_grp->num_res - 1)
continue;
else
break;
}
if (!verify_consumed_addr) {
not_found = false;
break;
}
/*
* Find out the res from the requested list,
* then we can get last consumed address from this port.
*/
done->resource_handle = comp_grp->res_id[j];
done->last_consumed_addr = 0;
hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
isp_hw_cmd_args.cmd_type =
CAM_ISP_HW_MGR_GET_LAST_CONSUMED_ADDR;
isp_hw_cmd_args.cmd_data = done;
hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
rc = ctx->hw_mgr_intf->hw_cmd(
ctx->hw_mgr_intf->hw_mgr_priv,
&hw_cmd_args);
if (rc) {
CAM_ERR(CAM_ISP, "HW command failed, ctx %u, link: 0x%x",
ctx->ctx_id, ctx->link_hdl);
return rc;
}
cmp_addr = cam_smmu_is_expanded_memory() ?
CAM_36BIT_INTF_GET_IOVA_BASE(
req_isp->fence_map_out[k].image_buf_addr[0]) :
req_isp->fence_map_out[k].image_buf_addr[0];
CAM_DBG(CAM_ISP, "Get res %s last_consumed_addr:0x%x cmp_addr:0x%x",
__cam_isp_resource_handle_id_to_type(
ctx_isp->isp_device_type, done->resource_handle),
done->last_consumed_addr, cmp_addr);
if (done->last_consumed_addr == cmp_addr) {
CAM_INFO(CAM_ISP, "found...");
not_found = false;
break;
}
}
}
if (not_found) {
/*
* If not found in current request, it could be
* belonging to next request, this can happen if
* IRQ delay happens. It is only valid when the
* platform doesn't have last consumed address.
*/
CAM_WARN(CAM_ISP,
"BUF_DONE for res %s last_consumed_addr:0x%x not found in Req %lld ",
__cam_isp_resource_handle_id_to_type(
ctx_isp->isp_device_type, done->resource_handle),
done->last_consumed_addr,
req->request_id);
unhandled_done.hw_type = done->hw_type;
unhandled_done.resource_handle = done->resource_handle;
unhandled_done.comp_group_id = done->comp_group_id;
unhandled_done.last_consumed_addr = done->last_consumed_addr;
goto check_deferred;
}
for (i = 0; i < comp_grp->num_res; i++) {
for (j = 0; j < req_isp->num_fence_map_out; j++) {
if (comp_grp->res_id[i] ==