浏览代码

msm: camera: isp: Read bus consumed addr at bus irq top half

Move the read of consumed addr to bus top half, as the tasklet
may delay and cannot readout the consumed addr in time.

CRs-Fixed: 3362499
Change-Id: I9742b117f433df6275ae5058d62e77ffce1f9a3f
Signed-off-by: chengxue <[email protected]>
chengxue 2 年之前
父节点
当前提交
2242eaefa8

+ 157 - 61
drivers/cam_isp/cam_isp_context.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/debugfs.h>
@@ -1668,6 +1668,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
 	struct cam_isp_ctx_req *req_isp;
 	struct cam_context *ctx = ctx_isp->base;
 	const char *handle_type;
+	struct cam_isp_context_comp_record *comp_grp = NULL;
 
 	trace_cam_buf_done("ISP", ctx, req);
 
@@ -1676,12 +1677,49 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
 	CAM_DBG(CAM_ISP, "Enter with bubble_state %d, req_bubble_detected %d",
 		bubble_state, req_isp->bubble_detected);
 
-	done_next_req->num_handles = 0;
+	done_next_req->resource_handle = 0;
 	done_next_req->timestamp = done->timestamp;
 
-	for (i = 0; i < done->num_handles; i++) {
+	for (i = 0; i < req_isp->num_fence_map_out; i++) {
+		if (done->resource_handle ==
+			req_isp->fence_map_out[i].resource_handle)
+			break;
+	}
+
+	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);
+
+		done_next_req->hw_type = done->hw_type;
+		done_next_req->resource_handle = done->resource_handle;
+		done_next_req->comp_group_id = done->comp_group_id;
+		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 (done->resource_handle[i] ==
+			if (comp_grp->res_id[i] ==
 				req_isp->fence_map_out[j].resource_handle)
 				break;
 		}
@@ -1689,20 +1727,15 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
 		if (j == 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.
+			 * belonging to an active port with no valid fence
+			 * bound to it, we needn't process it.
 			 */
-			CAM_WARN(CAM_ISP,
-				"BUF_DONE for res %s not found in Req %lld ",
+			CAM_DBG(CAM_ISP,
+				"BUF_DONE for res %s not active in Req %lld ",
 				__cam_isp_resource_handle_id_to_type(
 				ctx_isp->isp_device_type,
-				done->resource_handle[i]),
+				comp_grp->res_id[i]),
 				req->request_id);
-
-			done_next_req->resource_handle
-				[done_next_req->num_handles++] =
-				done->resource_handle[i];
 			continue;
 		}
 
@@ -1718,10 +1751,6 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
 
 			trace_cam_log_event("Duplicate BufDone",
 				handle_type, req->request_id, ctx->ctx_id);
-
-			done_next_req->resource_handle
-				[done_next_req->num_handles++] =
-				done->resource_handle[i];
 			continue;
 		}
 
@@ -1799,6 +1828,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
 				req->request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS);
 	}
 
+check_deferred:
 	if (req_isp->num_acked > req_isp->num_fence_map_out) {
 		/* Should not happen */
 		CAM_ERR(CAM_ISP,
@@ -1928,7 +1958,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 	struct cam_context *ctx = ctx_isp->base;
 	const char *handle_type;
 	uint32_t cmp_addr = 0;
-	struct cam_isp_hw_done_event_data unhandled_done = {0};
+	struct cam_isp_hw_done_event_data   unhandled_done = {0};
+	struct cam_isp_context_comp_record *comp_grp = NULL;
 
 	trace_cam_buf_done("ISP", ctx, req);
 
@@ -1937,24 +1968,55 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 	CAM_DBG(CAM_ISP, "Enter with bubble_state %d, req_bubble_detected %d",
 		bubble_state, req_isp->bubble_detected);
 
-	if (done->num_handles > CAM_NUM_OUT_PER_COMP_IRQ_MAX) {
-		CAM_ERR(CAM_ISP, "ctx: %u req: %llu num_handles: %u is more than %u",
-			ctx->ctx_id, req->request_id,
-			done->num_handles, CAM_NUM_OUT_PER_COMP_IRQ_MAX);
-		return -EINVAL;
-	}
-
 	unhandled_done.timestamp = done->timestamp;
 
-	for (i = 0; i < done->num_handles; i++) {
-		for (j = 0; j < req_isp->num_fence_map_out; j++) {
+	for (i = 0; i < req_isp->num_fence_map_out; i++) {
+		if (done->resource_handle ==
+			req_isp->fence_map_out[i].resource_handle) {
 			cmp_addr = cam_smmu_is_expanded_memory() ? CAM_36BIT_INTF_GET_IOVA_BASE(
-				req_isp->fence_map_out[j].image_buf_addr[0]) :
-				req_isp->fence_map_out[j].image_buf_addr[0];
-			if (verify_consumed_addr && (done->last_consumed_addr[i] != cmp_addr))
-				continue;
+				req_isp->fence_map_out[i].image_buf_addr[0]) :
+				req_isp->fence_map_out[i].image_buf_addr[0];
+			if (!verify_consumed_addr ||
+				(verify_consumed_addr && (done->last_consumed_addr == cmp_addr))) {
+				break;
+			}
+		}
+	}
 
-			if (done->resource_handle[i] ==
+	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
+		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] ==
 				req_isp->fence_map_out[j].resource_handle)
 				break;
 		}
@@ -1962,20 +2024,14 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 		if (j == 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.
+			 * belonging to an active port with no valid fence
+			 * bound to it, we needn't process it.
 			 */
 			CAM_DBG(CAM_ISP,
-				"BUF_DONE for res %s not found in Req %lld ",
+				"BUF_DONE for res %s not active in Req %lld ",
 				__cam_isp_resource_handle_id_to_type(
-				ctx_isp->isp_device_type, done->resource_handle[i]),
+				ctx_isp->isp_device_type, comp_grp->res_id[i]),
 				req->request_id);
-			unhandled_done.resource_handle[unhandled_done.num_handles] =
-				done->resource_handle[i];
-			unhandled_done.last_consumed_addr[unhandled_done.num_handles] =
-				done->last_consumed_addr[i];
-			unhandled_done.num_handles++;
 			continue;
 		}
 
@@ -2125,7 +2181,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
 				req->request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS);
 	}
 
-	if ((unhandled_done.num_handles > 0) && (!defer_buf_done))
+check_deferred:
+	if ((unhandled_done.resource_handle > 0) && (!defer_buf_done))
 		__cam_isp_ctx_check_deferred_buf_done(
 			ctx_isp, &unhandled_done, bubble_state);
 
@@ -2152,7 +2209,7 @@ static int __cam_isp_ctx_handle_buf_done(
 	int rc = 0;
 	struct cam_ctx_request *req;
 	struct cam_context *ctx = ctx_isp->base;
-	struct cam_isp_hw_done_event_data done_next_req;
+	struct cam_isp_hw_done_event_data done_next_req = {0};
 
 	if (list_empty(&ctx->active_req_list)) {
 		CAM_WARN(CAM_ISP, "Buf done with no active request");
@@ -2165,8 +2222,8 @@ static int __cam_isp_ctx_handle_buf_done(
 	rc = __cam_isp_ctx_handle_buf_done_for_request(ctx_isp, req, done,
 		bubble_state, &done_next_req);
 
-	if (done_next_req.num_handles) {
-		struct cam_isp_hw_done_event_data unhandled_res;
+	if (done_next_req.resource_handle) {
+		struct cam_isp_hw_done_event_data unhandled_res = {0};
 		struct cam_ctx_request  *next_req = list_last_entry(
 			&ctx->active_req_list, struct cam_ctx_request, list);
 
@@ -2190,7 +2247,7 @@ static int __cam_isp_ctx_handle_buf_done(
 				next_req, &done_next_req,
 				bubble_state, &unhandled_res);
 
-			if (unhandled_res.num_handles == 0)
+			if (unhandled_res.resource_handle == 0)
 				CAM_INFO(CAM_ISP,
 					"BUF Done event handed for next request %lld",
 					next_req->request_id);
@@ -2213,24 +2270,22 @@ static void __cam_isp_ctx_buf_done_match_req(
 	struct cam_isp_hw_done_event_data *done,
 	bool *irq_delay_detected)
 {
-	int i, j;
+	int i;
 	uint32_t match_count = 0;
 	struct cam_isp_ctx_req *req_isp;
 	uint32_t cmp_addr = 0;
 
 	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
 
-	for (i = 0; i < done->num_handles; i++) {
-		for (j = 0; j < req_isp->num_fence_map_out; j++) {
-			cmp_addr = cam_smmu_is_expanded_memory() ? CAM_36BIT_INTF_GET_IOVA_BASE(
-				req_isp->fence_map_out[j].image_buf_addr[0]) :
-				req_isp->fence_map_out[j].image_buf_addr[0];
-			if ((done->resource_handle[i] ==
-				 req_isp->fence_map_out[j].resource_handle) &&
-				(done->last_consumed_addr[i] == cmp_addr)) {
-				match_count++;
-				break;
-			}
+	for (i = 0; i < req_isp->num_fence_map_out; i++) {
+		cmp_addr = cam_smmu_is_expanded_memory() ? CAM_36BIT_INTF_GET_IOVA_BASE(
+			req_isp->fence_map_out[i].image_buf_addr[0]) :
+			req_isp->fence_map_out[i].image_buf_addr[0];
+		if ((done->resource_handle ==
+			 req_isp->fence_map_out[i].resource_handle) &&
+			(done->last_consumed_addr == cmp_addr)) {
+			match_count++;
+			break;
 		}
 	}
 
@@ -2241,7 +2296,7 @@ static void __cam_isp_ctx_buf_done_match_req(
 
 	CAM_DBG(CAM_ISP,
 		"buf done num handles %d match count %d for next req:%lld",
-		done->num_handles, match_count, req->request_id);
+		done->resource_handle, match_count, req->request_id);
 	CAM_DBG(CAM_ISP,
 		"irq_delay_detected %d", *irq_delay_detected);
 }
@@ -6022,6 +6077,10 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
 	ctx_isp->support_consumed_addr = false;
 	ctx_isp->aeb_enabled = false;
 	ctx_isp->req_info.last_bufdone_req_id = 0;
+	kfree(ctx_isp->vfe_bus_comp_grp);
+	kfree(ctx_isp->sfe_bus_comp_grp);
+	ctx_isp->vfe_bus_comp_grp = NULL;
+	ctx_isp->sfe_bus_comp_grp = NULL;
 
 	atomic64_set(&ctx_isp->state_monitor_head, -1);
 
@@ -6787,6 +6846,7 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
 	struct cam_hw_cmd_args           hw_cmd_args;
 	struct cam_isp_hw_cmd_args       isp_hw_cmd_args;
 	struct cam_isp_acquire_hw_info  *acquire_hw_info = NULL;
+	struct cam_isp_comp_record_query query_cmd;
 
 	if (!ctx->hw_mgr_intf) {
 		CAM_ERR(CAM_ISP, "HW interface is not ready");
@@ -6863,6 +6923,42 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
 	ctx_isp->aeb_enabled =
 		(param.op_flags & CAM_IFE_CTX_AEB_EN);
 
+	/* Query the context bus comp group information */
+	ctx_isp->vfe_bus_comp_grp = kcalloc(CAM_IFE_BUS_COMP_NUM_MAX,
+		sizeof(struct cam_isp_context_comp_record), GFP_KERNEL);
+	if (!ctx_isp->vfe_bus_comp_grp) {
+		CAM_ERR(CAM_CTXT, "%s[%d] no memory for vfe_bus_comp_grp",
+			ctx->dev_name, ctx->ctx_id);
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	if (param.op_flags & CAM_IFE_CTX_SFE_EN) {
+		ctx_isp->sfe_bus_comp_grp = kcalloc(CAM_SFE_BUS_COMP_NUM_MAX,
+			sizeof(struct cam_isp_context_comp_record), GFP_KERNEL);
+		if (!ctx_isp->sfe_bus_comp_grp) {
+			CAM_ERR(CAM_CTXT, "%s[%d] no memory for sfe_bus_comp_grp",
+				ctx->dev_name, ctx->ctx_id);
+			rc = -ENOMEM;
+			goto end;
+		}
+	}
+
+	query_cmd.vfe_bus_comp_grp = ctx_isp->vfe_bus_comp_grp;
+	if (ctx_isp->sfe_bus_comp_grp)
+		query_cmd.sfe_bus_comp_grp = ctx_isp->sfe_bus_comp_grp;
+	hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
+	hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
+	isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_GET_BUS_COMP_GROUP;
+	isp_hw_cmd_args.cmd_data = &query_cmd;
+	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");
+		goto free_hw;
+	}
+
 	/* Query the context has rdi only resource */
 	hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
 	hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;

+ 5 - 1
drivers/cam_isp/cam_isp_context.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_ISP_CONTEXT_H_
@@ -300,6 +300,8 @@ struct cam_isp_context_event_record {
  * @aeb_enabled:               Indicate if stream is for AEB
  * @last_sof_jiffies:          Record the jiffies of last sof
  * @last_applied_jiffies:      Record the jiffiest of last applied req
+ * @vfe_bus_comp_grp:          Vfe bus comp group record
+ * @sfe_bus_comp_grp:          Sfe bus comp group record
  *
  */
 struct cam_isp_context {
@@ -360,6 +362,8 @@ struct cam_isp_context {
 	bool                                  aeb_enabled;
 	uint64_t                              last_sof_jiffies;
 	uint64_t                              last_applied_jiffies;
+	struct cam_isp_context_comp_record   *vfe_bus_comp_grp;
+	struct cam_isp_context_comp_record   *sfe_bus_comp_grp;
 };
 
 /**

+ 98 - 34
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -2005,6 +2005,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_rdi(
 	struct cam_isp_out_port_generic_info     *out_port = NULL;
 	struct cam_isp_hw_mgr_res                *ife_out_res;
 	struct cam_hw_intf                       *hw_intf;
+	struct cam_isp_context_comp_record       *comp_grp = NULL;
+	uint32_t                                  index;
 	uint32_t  i, vfe_out_res_id, vfe_in_res_id;
 
 	/* take left resource */
@@ -2063,6 +2065,11 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_rdi(
 				 out_port->res_type);
 			goto err;
 		}
+
+		index = vfe_acquire.vfe_out.comp_grp_id;
+		comp_grp = &ife_ctx->vfe_bus_comp_grp[index];
+		comp_grp->res_id[comp_grp->num_res] = vfe_out_res_id;
+		comp_grp->num_res++;
 		break;
 	}
 
@@ -2097,6 +2104,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel(
 	struct cam_isp_out_port_generic_info     *out_port;
 	struct cam_isp_hw_mgr_res                *ife_out_res;
 	struct cam_hw_intf                       *hw_intf;
+	struct cam_isp_context_comp_record       *comp_grp = NULL;
+	uint32_t                                  index;
 
 	for (i = 0; i < in_port->num_out_res; i++) {
 		out_port = &in_port->data[i];
@@ -2167,10 +2176,16 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel(
 
 			ife_out_res->hw_res[j] =
 				vfe_acquire.vfe_out.rsrc_node;
-			CAM_DBG(CAM_ISP, "resource type :0x%x res id:0x%x",
-				ife_out_res->hw_res[j]->res_type,
-				ife_out_res->hw_res[j]->res_id);
+			index = vfe_acquire.vfe_out.comp_grp_id;
+			comp_grp = &ife_ctx->vfe_bus_comp_grp[index];
+			comp_grp->res_id[comp_grp->num_res] =
+				ife_out_res->hw_res[j]->res_id;
+			comp_grp->num_res++;
 
+			CAM_DBG(CAM_ISP, "resource type:0x%x res id:0x%x comp grp id:%d",
+				ife_out_res->hw_res[j]->res_type,
+				ife_out_res->hw_res[j]->res_id,
+				vfe_acquire.vfe_out.comp_grp_id);
 		}
 		ife_out_res->res_type = CAM_ISP_RESOURCE_VFE_OUT;
 		ife_out_res->res_id = out_port->res_type;
@@ -2195,6 +2210,8 @@ static int cam_ife_hw_mgr_acquire_res_sfe_out_rdi(
 	struct cam_isp_out_port_generic_info     *out_port = NULL;
 	struct cam_isp_hw_mgr_res                *sfe_out_res;
 	struct cam_hw_intf                       *hw_intf;
+	struct cam_isp_context_comp_record       *comp_grp = NULL;
+	uint32_t                                  index;
 
 	/* take left resource */
 	sfe_in_res_id = sfe_src_res->hw_res[0]->res_id;
@@ -2258,6 +2275,11 @@ static int cam_ife_hw_mgr_acquire_res_sfe_out_rdi(
 				 out_port->res_type);
 			goto err;
 		}
+
+		index = sfe_acquire.sfe_out.comp_grp_id;
+		comp_grp = &ife_ctx->sfe_bus_comp_grp[index];
+		comp_grp->res_id[comp_grp->num_res] = sfe_out_res_id;
+		comp_grp->num_res++;
 		break;
 	}
 
@@ -2292,6 +2314,8 @@ static int cam_ife_hw_mgr_acquire_res_sfe_out_pix(
 	struct cam_isp_out_port_generic_info     *out_port;
 	struct cam_isp_hw_mgr_res                *sfe_out_res;
 	struct cam_hw_intf                       *hw_intf;
+	struct cam_isp_context_comp_record       *comp_grp = NULL;
+	uint32_t                                  index;
 
 	for (i = 0; i < in_port->num_out_res; i++) {
 		out_port = &in_port->data[i];
@@ -2349,11 +2373,17 @@ static int cam_ife_hw_mgr_acquire_res_sfe_out_pix(
 
 			sfe_out_res->hw_res[j] =
 				sfe_acquire.sfe_out.rsrc_node;
-			CAM_DBG(CAM_ISP, "resource type: 0x%x res: %s res id: 0x%x",
+			index = sfe_acquire.sfe_out.comp_grp_id;
+			comp_grp = &ife_ctx->sfe_bus_comp_grp[index];
+			comp_grp->res_id[comp_grp->num_res] =
+				sfe_out_res->hw_res[j]->res_id;
+			comp_grp->num_res++;
+
+			CAM_DBG(CAM_ISP, "resource type:0x%x res: %s res id: 0x%x comp grp id:%d",
 				sfe_out_res->hw_res[j]->res_type,
 				sfe_out_res->hw_res[j]->res_name,
-				sfe_out_res->hw_res[j]->res_id);
-
+				sfe_out_res->hw_res[j]->res_id,
+				sfe_acquire.sfe_out.comp_grp_id);
 		}
 		sfe_out_res->res_type = CAM_ISP_RESOURCE_SFE_OUT;
 		sfe_out_res->res_id = out_port->res_type;
@@ -5274,6 +5304,22 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		goto free_ctx;
 	}
 
+	ife_ctx->vfe_bus_comp_grp = kcalloc(CAM_IFE_BUS_COMP_NUM_MAX,
+		sizeof(struct cam_isp_context_comp_record), GFP_KERNEL);
+	if (!ife_ctx->vfe_bus_comp_grp) {
+		CAM_ERR(CAM_CTXT, "No memory for vfe_bus_comp_grp");
+		rc = -ENOMEM;
+		goto free_mem;
+	}
+
+	ife_ctx->sfe_bus_comp_grp = kcalloc(CAM_SFE_BUS_COMP_NUM_MAX,
+		sizeof(struct cam_isp_context_comp_record), GFP_KERNEL);
+	if (!ife_ctx->sfe_bus_comp_grp) {
+		CAM_ERR(CAM_CTXT, "No memory for sfe_bus_comp_grp");
+		rc = -ENOMEM;
+		goto free_mem;
+	}
+
 	/* Update in_port structure */
 	for (i = 0; i < acquire_hw_info->num_inputs; i++) {
 		rc = cam_ife_mgr_acquire_get_unified_structure(acquire_hw_info,
@@ -5507,6 +5553,12 @@ free_mem:
 		kfree(in_port);
 		in_port = NULL;
 	}
+
+	kfree(ife_ctx->vfe_bus_comp_grp);
+	kfree(ife_ctx->sfe_bus_comp_grp);
+	ife_ctx->vfe_bus_comp_grp = NULL;
+	ife_ctx->sfe_bus_comp_grp = NULL;
+
 free_ctx:
 	cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->free_ctx_list, &ife_ctx);
 err:
@@ -7560,6 +7612,10 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
 	ctx->try_recovery_cnt = 0;
 	ctx->recovery_req_id = 0;
 	ctx->drv_path_idle_en = 0;
+	kfree(ctx->vfe_bus_comp_grp);
+	kfree(ctx->sfe_bus_comp_grp);
+	ctx->vfe_bus_comp_grp = NULL;
+	ctx->sfe_bus_comp_grp = NULL;
 
 	memset(&ctx->flags, 0, sizeof(struct cam_ife_hw_mgr_ctx_flags));
 	atomic_set(&ctx->overflow_pending, 0);
@@ -12668,6 +12724,7 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 	struct cam_isp_hw_cmd_args *isp_hw_cmd_args = NULL;
 	struct cam_packet          *packet;
 	unsigned long rem_jiffies = 0;
+	struct cam_isp_comp_record_query *query_cmd;
 
 	if (!hw_mgr_priv || !cmd_args) {
 		CAM_ERR(CAM_ISP, "Invalid arguments");
@@ -12743,6 +12800,17 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 				cam_ife_mgr_user_dump_stream_info, ctx,
 				sizeof(int32_t), "ISP_STREAM_INFO_FROM_IFE_HW_MGR:");
 			break;
+		case CAM_ISP_HW_MGR_GET_BUS_COMP_GROUP:
+			query_cmd = (struct cam_isp_comp_record_query *)
+				isp_hw_cmd_args->cmd_data;
+			memcpy(query_cmd->vfe_bus_comp_grp, ctx->vfe_bus_comp_grp,
+				sizeof(struct cam_isp_context_comp_record) *
+				CAM_IFE_BUS_COMP_NUM_MAX);
+			if (ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE)
+				memcpy(query_cmd->sfe_bus_comp_grp, ctx->sfe_bus_comp_grp,
+					sizeof(struct cam_isp_context_comp_record) *
+					CAM_SFE_BUS_COMP_NUM_MAX);
+			break;
 		default:
 			CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
 				hw_cmd_args->cmd_type);
@@ -14066,8 +14134,8 @@ static int cam_ife_hw_mgr_handle_hw_buf_done(
 {
 	cam_hw_event_cb_func                   ife_hwr_irq_wm_done_cb;
 	struct cam_isp_hw_done_event_data      buf_done_event_data = {0};
-	struct cam_isp_hw_compdone_event_info *compdone_evt_info = NULL;
-	int32_t                                rc = 0, i;
+	struct cam_isp_hw_bufdone_event_info  *bufdone_evt_info = NULL;
+	int32_t                                rc = 0;
 
 	if (!event_info->event_data) {
 		CAM_ERR(CAM_ISP,
@@ -14077,40 +14145,36 @@ static int cam_ife_hw_mgr_handle_hw_buf_done(
 	}
 
 	ife_hwr_irq_wm_done_cb = ife_hw_mgr_ctx->common.event_cb;
-	compdone_evt_info = (struct cam_isp_hw_compdone_event_info *)event_info->event_data;
-	buf_done_event_data.num_handles = 0;
-
-	for (i = 0; i < compdone_evt_info->num_res; i++) {
-		CAM_DBG(CAM_ISP,
-			"Buf done for %s: %d res_id: 0x%x last consumed addr: 0x%x ctx: %u",
-			((event_info->hw_type == CAM_ISP_HW_TYPE_SFE) ? "SFE" : "IFE"),
-			event_info->hw_idx, compdone_evt_info->res_id[i],
-			compdone_evt_info->last_consumed_addr[i], ife_hw_mgr_ctx->ctx_index);
-
-		/* Check scratch for sHDR/FS use-cases */
-		if (ife_hw_mgr_ctx->flags.is_sfe_fs || ife_hw_mgr_ctx->flags.is_sfe_shdr) {
-			rc = cam_ife_hw_mgr_check_for_scratch_buf_done(ife_hw_mgr_ctx,
-				event_info->hw_type, compdone_evt_info->res_id[i],
-				compdone_evt_info->last_consumed_addr[i]);
-			if (rc)
-				continue;
-		}
+	bufdone_evt_info = (struct cam_isp_hw_bufdone_event_info *)event_info->event_data;
+	buf_done_event_data.resource_handle = 0;
 
-		buf_done_event_data.resource_handle[buf_done_event_data.num_handles] =
-			compdone_evt_info->res_id[i];
-		buf_done_event_data.last_consumed_addr[buf_done_event_data.num_handles] =
-			compdone_evt_info->last_consumed_addr[i];
-		buf_done_event_data.num_handles++;
+	CAM_DBG(CAM_ISP,
+		"Buf done for %s: %d res_id: 0x%x last consumed addr: 0x%x ctx: %u",
+		((event_info->hw_type == CAM_ISP_HW_TYPE_SFE) ? "SFE" : "IFE"),
+		event_info->hw_idx, event_info->res_id,
+		bufdone_evt_info->last_consumed_addr, ife_hw_mgr_ctx->ctx_index);
+
+	/* Check scratch for sHDR/FS use-cases */
+	if (ife_hw_mgr_ctx->flags.is_sfe_fs || ife_hw_mgr_ctx->flags.is_sfe_shdr) {
+		rc = cam_ife_hw_mgr_check_for_scratch_buf_done(ife_hw_mgr_ctx,
+			event_info->hw_type, event_info->res_id,
+			bufdone_evt_info->last_consumed_addr);
+		if (rc)
+			return 0;
 	}
 
+	buf_done_event_data.hw_type = event_info->hw_type;
+	buf_done_event_data.resource_handle = event_info->res_id;
+	buf_done_event_data.last_consumed_addr = bufdone_evt_info->last_consumed_addr;
+	buf_done_event_data.comp_group_id = bufdone_evt_info->comp_grp_id;
 
 	if (atomic_read(&ife_hw_mgr_ctx->overflow_pending))
 		return 0;
 
-	if (buf_done_event_data.num_handles > 0 && ife_hwr_irq_wm_done_cb) {
+	if (buf_done_event_data.resource_handle > 0 && ife_hwr_irq_wm_done_cb) {
 		CAM_DBG(CAM_ISP,
 			"Notify ISP context for %u handles in ctx: %u",
-			buf_done_event_data.num_handles, ife_hw_mgr_ctx->ctx_index);
+			buf_done_event_data.resource_handle, ife_hw_mgr_ctx->ctx_index);
 		ife_hwr_irq_wm_done_cb(ife_hw_mgr_ctx->common.cb_priv,
 			CAM_ISP_HW_EVENT_DONE, (void *)&buf_done_event_data);
 	}

+ 32 - 1
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_IFE_HW_MGR_H_
@@ -233,6 +233,35 @@ struct cam_ife_cdm_user_data {
 	uint64_t                                  request_id;
 };
 
+/**
+ * struct cam_isp_context_comp_record:
+ *
+ * @brief:              Structure record the res id reserved on a comp group
+ *
+ * @num_res:            Number of valid resource IDs in this record
+ * @res_id:             Resource IDs to report buf dones
+ * @last_consumed_addr: Last consumed addr for resource ID at that index
+ *
+ */
+struct cam_isp_context_comp_record {
+	uint32_t num_res;
+	uint32_t res_id[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
+};
+
+/**
+ * struct cam_isp_comp_record_query:
+ *
+ * @brief:              Structure record the bus comp group pointer information
+ *
+ * @vfe_bus_comp_grp:   Vfe bus comp group pointer
+ * @vfe_bus_comp_grp:   Sfe bus comp group pointer
+ *
+ */
+struct cam_isp_comp_record_query {
+	struct cam_isp_context_comp_record        *vfe_bus_comp_grp;
+	struct cam_isp_context_comp_record        *sfe_bus_comp_grp;
+};
+
 /**
  * struct cam_ife_hw_mgr_ctx - IFE HW manager Context object
  *
@@ -350,6 +379,8 @@ struct cam_ife_hw_mgr_ctx {
 	uint32_t                                   try_recovery_cnt;
 	uint64_t                                   recovery_req_id;
 	uint32_t                                   drv_path_idle_en;
+	struct cam_isp_context_comp_record        *vfe_bus_comp_grp;
+	struct cam_isp_context_comp_record        *sfe_bus_comp_grp;
 };
 
 /**

+ 14 - 12
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_ISP_HW_MGR_INTF_H_
@@ -27,7 +27,8 @@
 #define CAM_TFE_HW_NUM_MAX       3
 #define CAM_TFE_RDI_NUM_MAX      3
 #define CAM_IFE_SCRATCH_NUM_MAX  2
-
+#define CAM_IFE_BUS_COMP_NUM_MAX 18
+#define CAM_SFE_BUS_COMP_NUM_MAX 12
 
 /* maximum context numbers for TFE */
 #define CAM_TFE_CTX_MAX      4
@@ -307,19 +308,19 @@ struct cam_isp_hw_epoch_event_data {
 /**
  * struct cam_isp_hw_done_event_data - Event payload for CAM_HW_EVENT_DONE
  *
- * @num_handles:           Number of resource handeles
- * @resource_handle:       Resource handle array
- * @last_consumed_addr:    Last consumed addr
- * @timestamp:             Timestamp for the buf done event
+ * @hw_type:             Hw type sending the event
+ * @resource_handle:     Resource handle
+ * @comp_group_id:       Bus comp group id
+ * @last_consumed_addr:  Last consumed addr
+ * @timestamp:           Timestamp for the buf done event
  *
  */
 struct cam_isp_hw_done_event_data {
-	uint32_t             num_handles;
-	uint32_t             resource_handle[
-				CAM_NUM_OUT_PER_COMP_IRQ_MAX];
-	uint32_t             last_consumed_addr[
-				CAM_NUM_OUT_PER_COMP_IRQ_MAX];
-	uint64_t       timestamp;
+	uint32_t             hw_type;
+	uint32_t             resource_handle;
+	uint32_t             comp_group_id;
+	uint32_t             last_consumed_addr;
+	uint64_t             timestamp;
 };
 
 /**
@@ -372,6 +373,7 @@ enum cam_isp_hw_mgr_command {
 	CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG,
 	CAM_ISP_HW_MGR_GET_SOF_TS,
 	CAM_ISP_HW_MGR_DUMP_STREAM_INFO,
+	CAM_ISP_HW_MGR_GET_BUS_COMP_GROUP,
 	CAM_ISP_HW_MGR_CMD_MAX,
 };
 

+ 7 - 7
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_ISP_HW_H_
@@ -313,19 +313,19 @@ struct cam_isp_hw_error_event_info {
 };
 
 /**
- * struct cam_isp_hw_compdone_event_info:
+ * struct cam_isp_hw_bufdone_event_info:
  *
  * @brief:              Structure to pass bufdone event details to hw mgr
  *
- * @num_res:            Number of valid resource IDs in this event
  * @res_id:             Resource IDs to report buf dones
+ * @comp_grp_id:        Bus comp group id
  * @last_consumed_addr: Last consumed addr for resource ID at that index
  *
  */
-struct cam_isp_hw_compdone_event_info {
-	uint32_t num_res;
-	uint32_t res_id[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
-	uint32_t last_consumed_addr[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
+struct cam_isp_hw_bufdone_event_info {
+	uint32_t res_id;
+	uint32_t comp_grp_id;
+	uint32_t last_consumed_addr;
 };
 
 /*

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_sfe_hw_intf.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_SFE_HW_INTF_H_
@@ -202,6 +202,7 @@ struct cam_sfe_top_irq_evt_payload {
  * @error_type:              Identify different errors
  * @evt_id:                  IRQ event
  * @ts:                      Timestamp
+ * @last_consumed_addr:      Last consumed addr for resource
  */
 struct cam_sfe_bus_wr_irq_evt_payload {
 	struct list_head           list;
@@ -213,6 +214,7 @@ struct cam_sfe_bus_wr_irq_evt_payload {
 	uint32_t                   error_type;
 	uint32_t                   evt_id;
 	struct cam_isp_timestamp   ts;
+	uint32_t                   last_consumed_addr;
 };
 
 /*
@@ -313,6 +315,7 @@ struct cam_sfe_hw_sfe_in_acquire_args {
  * @is_master:               In case of Dual SFE, this is Master or Slave.
  * @cdm_ops:                 CDM operations
  * @use_wm_pack:             Flag to indicalte packing at WM side
+ * @comp_grp_id:             SFE bus comp group id
  */
 struct cam_sfe_hw_sfe_out_acquire_args {
 	struct cam_isp_resource_node         *rsrc_node;
@@ -323,6 +326,7 @@ struct cam_sfe_hw_sfe_out_acquire_args {
 	uint32_t                              is_master;
 	struct cam_cdm_utils_ops             *cdm_ops;
 	bool                                  use_wm_pack;
+	uint32_t                              comp_grp_id;
 };
 
 /*

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_VFE_HW_INTF_H_
@@ -146,6 +146,7 @@ struct cam_vfe_hw_vfe_bus_rd_acquire_args {
  * @cdm_ops:                 CDM operations
  * @disable_ubwc_comp:       Disable UBWC compression
  * @use_wm_pack:             Use WM Packing
+ * @comp_grp_id:             VFE bus comp group id
  */
 struct cam_vfe_hw_vfe_out_acquire_args {
 	struct cam_isp_resource_node         *rsrc_node;
@@ -158,6 +159,7 @@ struct cam_vfe_hw_vfe_out_acquire_args {
 	struct cam_cdm_utils_ops             *cdm_ops;
 	bool                                  disable_ubwc_comp;
 	bool                                  use_wm_pack;
+	uint32_t                              comp_grp_id;
 };
 
 /*
@@ -313,6 +315,7 @@ struct cam_vfe_top_irq_evt_payload {
  *                           handled
  * @error_type:              Identify different errors
  * @ts:                      Timestamp
+ * @last_consumed_addr:      Last consumed addr for resource
  */
 struct cam_vfe_bus_irq_evt_payload {
 	struct list_head            list;
@@ -324,6 +327,7 @@ struct cam_vfe_bus_irq_evt_payload {
 	uint32_t                    evt_id;
 	uint32_t                    irq_reg_val[CAM_IFE_BUS_IRQ_REGISTERS_MAX];
 	struct cam_isp_timestamp    ts;
+	uint32_t                    last_consumed_addr;
 };
 
 /**

+ 22 - 127
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/ratelimit.h>
@@ -289,69 +289,6 @@ static enum cam_sfe_bus_sfe_out_type
 	}
 }
 
-static int cam_sfe_bus_get_comp_sfe_out_res_id_list(
-	uint32_t comp_mask, uint32_t *out_list, int *num_out)
-{
-	int count = 0;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI0)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_0;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI1)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_1;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI2)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_2;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI3)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_3;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI4)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_4;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RAW_DUMP)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_RAW_DUMP;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BE_0)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BE_STATS_0;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BHIST_0)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BHIST_STATS_0;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BE_1)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BE_STATS_1;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BHIST_1)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BHIST_STATS_1;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BE_2)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BE_STATS_2;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BHIST_2)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BHIST_STATS_2;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_LCR)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_LCR;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_IR)))
-		out_list[count++] = CAM_ISP_SFE_OUT_RES_IR;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BAYER_RS_0)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BAYER_RS_STATS_0;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BAYER_RS_1)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BAYER_RS_STATS_1;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BAYER_RS_2)))
-		out_list[count++] = CAM_ISP_SFE_OUT_BAYER_RS_STATS_2;
-
-	if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_HDR_STATS)))
-		out_list[count++] = CAM_ISP_SFE_OUT_HDR_STATS;
-
-	*num_out = count;
-	return 0;
-}
-
 bool cam_sfe_is_mipi_pcking_needed(
 	struct cam_sfe_bus_wr_priv *bus_priv,
 	int wm_index)
@@ -1475,6 +1412,7 @@ static int cam_sfe_bus_acquire_sfe_out(void *priv, void *acquire_args,
 
 	rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
 	out_acquire_args->rsrc_node = rsrc_node;
+	out_acquire_args->comp_grp_id = comp_grp_id;
 
 	CAM_DBG(CAM_SFE, "Acquire successful");
 	return rc;
@@ -1773,6 +1711,7 @@ static int cam_sfe_bus_handle_sfe_out_done_top_half(
 	struct cam_sfe_bus_wr_out_data             *rsrc_data = NULL;
 	struct cam_sfe_bus_wr_irq_evt_payload      *evt_payload;
 	struct cam_sfe_bus_wr_comp_grp_data        *resource_data;
+	struct cam_sfe_bus_wr_wm_resource_data     *wm_rsrc_data = NULL;
 	uint32_t                                    status_0;
 
 	sfe_out = th_payload->handler_priv;
@@ -1811,6 +1750,11 @@ static int cam_sfe_bus_handle_sfe_out_done_top_half(
 	status_0 = th_payload->evt_status_arr[CAM_SFE_IRQ_BUS_WR_REG_STATUS0];
 
 	if (status_0 & resource_data->comp_done_mask) {
+		/* All SFE out ports have single WM */
+		wm_rsrc_data = rsrc_data->wm_res->res_priv;
+		evt_payload->last_consumed_addr = cam_io_r_mb(
+			wm_rsrc_data->common_data->mem_base +
+			wm_rsrc_data->hw_regs->addr_status_0);
 		trace_cam_log_event("bufdone", "bufdone_IRQ",
 			status_0, resource_data->comp_grp_type);
 	}
@@ -1821,7 +1765,7 @@ static int cam_sfe_bus_handle_sfe_out_done_top_half(
 static int cam_sfe_bus_handle_comp_done_bottom_half(
 	void                *handler_priv,
 	void                *evt_payload_priv,
-	uint32_t            *comp_mask)
+	uint32_t            *comp_grp_id)
 {
 	int rc = CAM_SFE_IRQ_STATUS_ERR;
 	struct cam_isp_resource_node          *comp_grp = handler_priv;
@@ -1851,62 +1795,32 @@ static int cam_sfe_bus_handle_comp_done_bottom_half(
 		rsrc_data->common_data->core_index, rsrc_data->comp_grp_type,
 		status_0, rc);
 
-	*comp_mask = rsrc_data->composite_mask;
+	*comp_grp_id = rsrc_data->comp_grp_type;
 
 	return rc;
 }
 
-static uint32_t cam_sfe_bus_get_last_consumed_addr(
-	struct cam_sfe_bus_wr_priv *bus_priv,
-	uint32_t res_type,
-	uint32_t *val)
-{
-	struct cam_isp_resource_node             *rsrc_node = NULL;
-	struct cam_sfe_bus_wr_out_data           *rsrc_data = NULL;
-	struct cam_sfe_bus_wr_wm_resource_data   *wm_rsrc_data = NULL;
-	enum cam_sfe_bus_sfe_out_type             res_id;
-
-	res_id = cam_sfe_bus_wr_get_out_res_id(res_type);
-
-	if (res_id >= CAM_SFE_BUS_SFE_OUT_MAX) {
-		CAM_ERR(CAM_ISP, "invalid res id:%u", res_id);
-		return 0;
-	}
-
-	rsrc_node = &bus_priv->sfe_out[res_id];
-	rsrc_data = rsrc_node->res_priv;
-
-	/* All SFE out ports have single WM */
-	wm_rsrc_data = rsrc_data->wm_res->res_priv;
-	*val = cam_io_r_mb(
-		wm_rsrc_data->common_data->mem_base +
-		wm_rsrc_data->hw_regs->addr_status_0);
-
-	return 0;
-}
-
 static int cam_sfe_bus_handle_sfe_out_done_bottom_half(
 	void                *handler_priv,
 	void                *evt_payload_priv)
 {
-	int rc = -EINVAL, num_out = 0, i;
-	uint32_t evt_id = 0, comp_mask = 0, val = 0;
+	int rc = -EINVAL;
+	uint32_t evt_id = 0;
 	struct cam_isp_resource_node           *sfe_out = handler_priv;
 	struct cam_sfe_bus_wr_out_data         *rsrc_data = sfe_out->res_priv;
 	struct cam_sfe_bus_wr_irq_evt_payload  *evt_payload = evt_payload_priv;
 	struct cam_isp_hw_event_info            evt_info;
-	struct cam_isp_hw_compdone_event_info   compdone_evt_info = {0};
+	struct cam_isp_hw_bufdone_event_info    bufdone_evt_info = {0};
 	void                                   *ctx = NULL;
-	uint32_t                       out_list[CAM_SFE_BUS_SFE_OUT_MAX];
+	uint32_t                                comp_grp_id = 0;
 
 	rc = cam_sfe_bus_handle_comp_done_bottom_half(
-		rsrc_data->comp_grp, evt_payload_priv, &comp_mask);
-	CAM_DBG(CAM_SFE, "SFE:%d out_type:0x%X rc:%d",
+		rsrc_data->comp_grp, evt_payload_priv, &comp_grp_id);
+	CAM_DBG(CAM_SFE, "SFE:%d out_type:0x%x comp_grp_id:%d rc:%d",
 		rsrc_data->common_data->core_index,
-		rsrc_data->out_type, rc);
+		rsrc_data->out_type, comp_grp_id, rc);
 
 	ctx = rsrc_data->priv;
-	memset(out_list, 0, sizeof(out_list));
 
 	switch (rc) {
 	case CAM_SFE_IRQ_STATUS_SUCCESS:
@@ -1915,30 +1829,12 @@ static int cam_sfe_bus_handle_sfe_out_done_bottom_half(
 		evt_info.res_type = sfe_out->res_type;
 		evt_info.hw_idx   = sfe_out->hw_intf->hw_idx;
 		evt_info.hw_type  = CAM_ISP_HW_TYPE_SFE;
+		evt_info.res_id = sfe_out->res_id;
+		bufdone_evt_info.res_id = sfe_out->res_id;
+		bufdone_evt_info.comp_grp_id = comp_grp_id;
+		bufdone_evt_info.last_consumed_addr = evt_payload->last_consumed_addr;
+		evt_info.event_data = (void *)&bufdone_evt_info;
 
-		cam_sfe_bus_get_comp_sfe_out_res_id_list(
-			comp_mask, out_list, &num_out);
-		if (num_out > CAM_NUM_OUT_PER_COMP_IRQ_MAX) {
-			CAM_ERR(CAM_ISP,
-				"num_out: %d  exceeds max_port_per_comp_grp: %d for comp_mask: %u",
-				num_out, CAM_NUM_OUT_PER_COMP_IRQ_MAX, comp_mask);
-			for (i = 0; i < num_out; i++)
-				CAM_ERR(CAM_ISP,
-					"Skipping buf done notify for outport: %u",
-					out_list[i]);
-			rc = -EINVAL;
-			goto end;
-		}
-
-		compdone_evt_info.num_res = num_out;
-		for (i = 0; i < num_out; i++) {
-			compdone_evt_info.res_id[i] = out_list[i];
-			cam_sfe_bus_get_last_consumed_addr(
-				rsrc_data->bus_priv,
-				compdone_evt_info.res_id[i], &val);
-			compdone_evt_info.last_consumed_addr[i] = val;
-		}
-		evt_info.event_data = (void *)&compdone_evt_info;
 		if (rsrc_data->common_data->event_cb)
 			rsrc_data->common_data->event_cb(ctx, evt_id,
 				(void *)&evt_info);
@@ -1947,7 +1843,6 @@ static int cam_sfe_bus_handle_sfe_out_done_bottom_half(
 		break;
 	}
 
-end:
 	cam_sfe_bus_wr_put_evt_payload(rsrc_data->common_data, &evt_payload);
 
 	return rc;

+ 11 - 102
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/ratelimit.h>
@@ -858,77 +858,6 @@ static int cam_vfe_bus_get_wm_idx(
 	return wm_idx;
 }
 
-static void cam_vfe_bus_get_comp_vfe_out_res_id_list(
-	uint32_t comp_mask, uint32_t *out_list, int *num_out)
-{
-	int count = 0;
-
-	if (comp_mask & 0x1)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_0;
-
-	if (comp_mask & 0x2)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_1;
-
-	if (comp_mask & 0x4)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_2;
-
-	if ((comp_mask & 0x8) && (((comp_mask >> 4) & 0x1) == 0))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_3;
-
-	if (comp_mask & 0x18)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_FULL;
-
-	if (comp_mask & 0x20)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS4;
-
-	if (comp_mask & 0x40)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16;
-
-	if (comp_mask & 0x180)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_FD;
-
-	if (comp_mask & 0x200)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RAW_DUMP;
-
-	if (comp_mask & 0x800)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_HDR_BE;
-
-	if (comp_mask & 0x1000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST;
-
-	if (comp_mask & 0x2000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_TL_BG;
-
-	if (comp_mask & 0x4000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BF;
-
-	if (comp_mask & 0x8000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_AWB_BG;
-
-	if (comp_mask & 0x10000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BHIST;
-
-	if (comp_mask & 0x20000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_RS;
-
-	if (comp_mask & 0x40000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_CS;
-
-	if (comp_mask & 0x80000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_IHIST;
-
-	if (comp_mask & 0x300000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_FULL_DISP;
-
-	if (comp_mask & 0x400000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS4_DISP;
-
-	if (comp_mask & 0x800000)
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16_DISP;
-
-	*num_out = count;
-}
-
 static enum cam_vfe_bus_packer_format
 	cam_vfe_bus_get_packer_fmt(uint32_t out_fmt, int wm_index)
 {
@@ -1938,7 +1867,7 @@ static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
 }
 
 static int cam_vfe_bus_handle_comp_done_bottom_half(void *handler_priv,
-	void  *evt_payload_priv, uint32_t *comp_mask)
+	void  *evt_payload_priv, uint32_t *grp_id)
 {
 	int rc = CAM_VFE_IRQ_STATUS_ERR;
 	struct cam_isp_resource_node          *comp_grp = handler_priv;
@@ -2041,7 +1970,7 @@ static int cam_vfe_bus_handle_comp_done_bottom_half(void *handler_priv,
 		break;
 	}
 
-	*comp_mask = rsrc_data->composite_mask;
+	*grp_id = rsrc_data->comp_grp_type;
 
 	return rc;
 }
@@ -2486,14 +2415,12 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 	struct cam_isp_resource_node             *vfe_out = handler_priv;
 	struct cam_vfe_bus_ver2_vfe_out_data     *rsrc_data = vfe_out->res_priv;
 	struct cam_isp_hw_event_info              evt_info;
-	struct cam_isp_hw_compdone_event_info     compdone_evt_info = {0};
+	struct cam_isp_hw_bufdone_event_info      bufdone_evt_info = {0};
 	void                                     *ctx = NULL;
 	uint32_t                                  evt_id = 0;
-	uint32_t                                  comp_mask = 0;
-	int                                       num_out = 0, i = 0;
+	uint32_t                                  comp_grp_id = 0;
 	struct cam_vfe_bus_irq_evt_payload       *evt_payload =
 		evt_payload_priv;
-	uint32_t                   out_list[CAM_VFE_BUS_VER2_VFE_OUT_MAX] = {0};
 
 	/*
 	 * If this resource has Composite Group then we only handle
@@ -2502,7 +2429,7 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 	 */
 	if (rsrc_data->comp_grp) {
 		rc = cam_vfe_bus_handle_comp_done_bottom_half(
-			rsrc_data->comp_grp, evt_payload_priv, &comp_mask);
+			rsrc_data->comp_grp, evt_payload_priv, &comp_grp_id);
 	} else {
 		rc = rsrc_data->wm_res[0]->bottom_half_handler(
 			rsrc_data->wm_res[0], evt_payload_priv);
@@ -2520,29 +2447,12 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 		evt_info.res_type = vfe_out->res_type;
 		evt_info.hw_idx   = vfe_out->hw_intf->hw_idx;
 		if (rsrc_data->comp_grp) {
-			cam_vfe_bus_get_comp_vfe_out_res_id_list(
-				comp_mask, out_list, &num_out);
-			if (num_out > CAM_NUM_OUT_PER_COMP_IRQ_MAX) {
-				CAM_ERR(CAM_ISP,
-					"num_out: %d  exceeds max_port_per_comp_grp: %d for comp_mask: %u",
-					num_out, CAM_NUM_OUT_PER_COMP_IRQ_MAX, comp_mask);
-				for (i = 0; i < num_out; i++)
-					CAM_ERR(CAM_ISP,
-						"Skipping buf done notify for outport: %u",
-						out_list[i]);
-				rc = -EINVAL;
-				goto end;
-			}
+			bufdone_evt_info.res_id = vfe_out->res_id;
+			bufdone_evt_info.comp_grp_id = comp_grp_id;
+		} else
+			bufdone_evt_info.res_id = vfe_out->res_id;
 
-			compdone_evt_info.num_res = num_out;
-			for (i = 0; i < num_out; i++) {
-				compdone_evt_info.res_id[i] = out_list[i];
-			}
-		} else {
-			compdone_evt_info.num_res = 1;
-			compdone_evt_info.res_id[0] = vfe_out->res_id;
-		}
-		evt_info.event_data = (void *)&compdone_evt_info;
+		evt_info.event_data = (void *)&bufdone_evt_info;
 		if (rsrc_data->common_data->event_cb)
 			rsrc_data->common_data->event_cb(ctx,
 				evt_id, (void *)&evt_info);
@@ -2551,7 +2461,6 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 		break;
 	}
 
-end:
 	cam_vfe_bus_put_evt_payload(rsrc_data->common_data, &evt_payload);
 
 	return rc;

+ 21 - 185
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 
@@ -467,123 +467,6 @@ static enum cam_vfe_bus_ver3_vfe_out_type
 	return vfe_out_type;
 }
 
-static int cam_vfe_bus_ver3_get_comp_vfe_out_res_id_list(
-	uint64_t comp_mask, uint32_t *out_list, int *num_out)
-{
-	int count = 0;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_RDI0)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_0;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_RDI1)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_1;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_RDI2)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_2;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_RDI3)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_3;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_FULL)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_FULL;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_DS4)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS4;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_DS16)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_RAW_DUMP;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_FD)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_FD;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_PDAF)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_PDAF;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_HDR_BE;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BHIST)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_TL_BG)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_TL_BG;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BF;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_AWB_BG;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BHIST;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_RS;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_CS;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_IHIST;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_FULL_DISP;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS4_DISP;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16_DISP;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_2PD)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_2PD;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_LCR)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_LCR;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_AWB_BFW)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_AWB_BFW;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_PREPROCESS_2PD)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_PREPROCESS_2PD;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_AEC_BE;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_LTM_STATS;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_GTM_BHIST;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_BG)))
-		out_list[count++] = CAM_ISP_IFE_LITE_OUT_RES_STATS_BG;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_PREPROCESS_RAW)))
-		out_list[count++] = CAM_ISP_IFE_LITE_OUT_RES_PREPROCESS_RAW;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_SPARSE_PD)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_SPARSE_PD;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_CAF)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_CAF;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_BAYER_RS)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BAYER_RS;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_PDAF_PARSED)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_PDAF_PARSED_DATA;
-
-	if (comp_mask & (BIT_ULL(CAM_VFE_BUS_VER3_VFE_OUT_STATS_ALSC)))
-		out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_ALSC;
-
-	*num_out = count;
-	return 0;
-}
-
 static enum cam_vfe_bus_ver3_packer_format
 	cam_vfe_bus_ver3_get_packer_fmt(uint32_t out_fmt, int wm_index)
 {
@@ -1843,7 +1726,7 @@ static int cam_vfe_bus_ver3_handle_comp_done_top_half(uint32_t evt_id,
 static int cam_vfe_bus_ver3_handle_comp_done_bottom_half(
 	void                *handler_priv,
 	void                *evt_payload_priv,
-	uint64_t            *comp_mask)
+	uint32_t            *comp_grp_id)
 {
 	int rc = CAM_VFE_IRQ_STATUS_ERR;
 	struct cam_vfe_bus_ver3_vfe_out_data  *vfe_out  = handler_priv;
@@ -1874,7 +1757,7 @@ static int cam_vfe_bus_ver3_handle_comp_done_bottom_half(
 		rsrc_data->common_data->core_index, rsrc_data->comp_grp_type,
 		status_0, rc);
 
-	*comp_mask = rsrc_data->composite_mask;
+	*comp_grp_id = rsrc_data->comp_grp_type;
 
 	return rc;
 }
@@ -2115,6 +1998,7 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args,
 
 	rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
 	out_acquire_args->rsrc_node = rsrc_node;
+	out_acquire_args->comp_grp_id = comp_acq_args.comp_grp_id;
 
 	CAM_DBG(CAM_ISP, "Acquire successful");
 	return rc;
@@ -2364,6 +2248,7 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_top_half(uint32_t evt_id,
 	struct cam_vfe_bus_irq_evt_payload         *evt_payload;
 	struct cam_vfe_bus_ver3_comp_grp_data      *resource_data;
 	uint32_t                                    status_0;
+	struct cam_vfe_bus_ver3_wm_resource_data   *wm_rsrc_data = NULL;
 
 	vfe_out = th_payload->handler_priv;
 	if (!vfe_out) {
@@ -2403,6 +2288,10 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_top_half(uint32_t evt_id,
 	status_0 = th_payload->evt_status_arr[CAM_IFE_IRQ_BUS_VER3_REG_STATUS0];
 
 	if (status_0 & resource_data->comp_done_mask) {
+		wm_rsrc_data = rsrc_data->wm_res[PLANE_Y].res_priv;
+		evt_payload->last_consumed_addr = cam_io_r_mb(
+			wm_rsrc_data->common_data->mem_base +
+			wm_rsrc_data->hw_regs->addr_status_0);
 		trace_cam_log_event("bufdone", "bufdone_IRQ",
 			status_0, resource_data->comp_grp_type);
 	}
@@ -2414,61 +2303,27 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_top_half(uint32_t evt_id,
 	return rc;
 }
 
-static uint32_t cam_vfe_bus_ver3_get_last_consumed_addr(
-	struct cam_vfe_bus_ver3_priv *bus_priv,
-	uint32_t res_type)
-{
-	uint32_t                                  val = 0;
-	struct cam_isp_resource_node             *rsrc_node = NULL;
-	struct cam_vfe_bus_ver3_vfe_out_data     *rsrc_data = NULL;
-	struct cam_vfe_bus_ver3_wm_resource_data *wm_rsrc_data = NULL;
-	enum cam_vfe_bus_ver3_vfe_out_type        res_id;
-	uint32_t           outmap_index = CAM_VFE_BUS_VER3_VFE_OUT_MAX;
-
-	res_id = cam_vfe_bus_ver3_get_out_res_id_and_index(bus_priv,
-		res_type, &outmap_index);
-
-	if ((res_id >= CAM_VFE_BUS_VER3_VFE_OUT_MAX) ||
-		(outmap_index >= bus_priv->num_out)) {
-		CAM_WARN(CAM_ISP,
-			"target does not support req res id :0x%x outtype:%d index:%d",
-			res_type, res_id, outmap_index);
-		return 0;
-	}
-
-	rsrc_node = &bus_priv->vfe_out[outmap_index];
-	rsrc_data = rsrc_node->res_priv;
-	wm_rsrc_data = rsrc_data->wm_res[PLANE_Y].res_priv;
-
-	val = cam_io_r_mb(
-		wm_rsrc_data->common_data->mem_base +
-		wm_rsrc_data->hw_regs->addr_status_0);
-
-	return val;
-}
-
 static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half(
 	void                *handler_priv,
 	void                *evt_payload_priv)
 {
-	int                                    rc = -EINVAL, num_out = 0, i = 0;
+	int                                    rc = -EINVAL;
 	struct cam_isp_resource_node          *vfe_out = handler_priv;
 	struct cam_vfe_bus_ver3_vfe_out_data  *rsrc_data = vfe_out->res_priv;
 	struct cam_vfe_bus_irq_evt_payload    *evt_payload = evt_payload_priv;
 	struct cam_isp_hw_event_info           evt_info;
-	struct cam_isp_hw_compdone_event_info  compdone_evt_info = {0};
+	struct cam_isp_hw_bufdone_event_info   bufdone_evt_info = {0};
 	void                                  *ctx = NULL;
 	uint32_t                               evt_id = 0;
-	uint64_t                               comp_mask = 0;
-	uint32_t                               out_list[CAM_VFE_BUS_VER3_VFE_OUT_MAX];
+	uint32_t                               comp_grp_id = 0;
 
 	rc = cam_vfe_bus_ver3_handle_comp_done_bottom_half(
-		rsrc_data, evt_payload_priv, &comp_mask);
-	CAM_DBG(CAM_ISP, "VFE:%d out_type:0x%X comp_mask: 0x%lx rc:%d",
-		rsrc_data->common_data->core_index, rsrc_data->out_type, comp_mask, rc);
+		rsrc_data, evt_payload_priv, &comp_grp_id);
+	CAM_DBG(CAM_ISP, "VFE:%d out_type:0x%x comp_grp_id:%d rc:%d",
+		rsrc_data->common_data->core_index, rsrc_data->out_type,
+		comp_grp_id, rc);
 
 	ctx = rsrc_data->priv;
-	memset(out_list, 0, sizeof(out_list));
 
 	switch (rc) {
 	case CAM_VFE_IRQ_STATUS_SUCCESS:
@@ -2477,30 +2332,12 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half(
 		evt_info.res_type = vfe_out->res_type;
 		evt_info.hw_idx   = vfe_out->hw_intf->hw_idx;
 		evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
+		evt_info.res_id = vfe_out->res_id;
+		bufdone_evt_info.res_id = vfe_out->res_id;
+		bufdone_evt_info.comp_grp_id = comp_grp_id;
+		bufdone_evt_info.last_consumed_addr = evt_payload->last_consumed_addr;
+		evt_info.event_data = (void *)&bufdone_evt_info;
 
-		cam_vfe_bus_ver3_get_comp_vfe_out_res_id_list(
-			comp_mask, out_list, &num_out);
-		if (num_out > CAM_NUM_OUT_PER_COMP_IRQ_MAX) {
-			CAM_ERR(CAM_ISP,
-				"num_out: %d  exceeds max_port_per_comp_grp: %d for comp_mask: %u",
-				num_out, CAM_NUM_OUT_PER_COMP_IRQ_MAX, comp_mask);
-			for (i = 0; i < num_out; i++)
-				CAM_ERR(CAM_ISP,
-					"Skipping buf done notify for outport: %u",
-					out_list[i]);
-			rc = -EINVAL;
-			goto end;
-		}
-
-		compdone_evt_info.num_res = num_out;
-		for (i = 0; i < num_out; i++) {
-			compdone_evt_info.res_id[i] = out_list[i];
-			compdone_evt_info.last_consumed_addr[i] =
-				cam_vfe_bus_ver3_get_last_consumed_addr(
-				rsrc_data->bus_priv,
-				compdone_evt_info.res_id[i]);
-		}
-		evt_info.event_data = (void *)&compdone_evt_info;
 		if (rsrc_data->common_data->event_cb)
 			rsrc_data->common_data->event_cb(ctx, evt_id,
 				(void *)&evt_info);
@@ -2509,7 +2346,6 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half(
 		break;
 	}
 
-end:
 	cam_vfe_bus_ver3_put_evt_payload(rsrc_data->common_data, &evt_payload);
 
 	return rc;