Browse Source

msm: camera: tfe: Read last consumed address in 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: 3543220
Change-Id: I89a00ce0596747b79f3b5e0f66c72e760711829b
Signed-off-by: Pranav Sanwal <[email protected]>
Pranav Sanwal 1 year ago
parent
commit
ef6d34e2a6

+ 69 - 15
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -829,7 +829,8 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out_rdi(
 	struct cam_isp_tfe_out_port_generic_info *out_port = NULL;
 	struct cam_isp_hw_mgr_res                *tfe_out_res;
 	struct cam_hw_intf                       *hw_intf;
-	uint32_t  i, tfe_out_res_id, tfe_in_res_id;
+	struct cam_tfe_hw_comp_record            *comp_grp = NULL;
+	uint32_t  i, tfe_out_res_id, tfe_in_res_id, index;
 
 	/* take left resource */
 	tfe_in_res_id = tfe_in_res->hw_res[0]->res_id;
@@ -880,6 +881,11 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out_rdi(
 				 out_port->res_id);
 			goto err;
 		}
+
+		index = tfe_acquire.tfe_out.comp_grp_id;
+		comp_grp = &tfe_ctx->tfe_bus_comp_grp[index];
+		comp_grp->res_id[comp_grp->num_res] = tfe_out_res_id;
+		comp_grp->num_res++;
 		break;
 	}
 
@@ -912,6 +918,8 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out_pixel(
 	struct cam_isp_tfe_out_port_generic_info *out_port;
 	struct cam_isp_hw_mgr_res                *tfe_out_res;
 	struct cam_hw_intf                       *hw_intf;
+	struct cam_tfe_hw_comp_record            *comp_grp = NULL;
+	uint32_t                                  index;
 
 	for (i = 0; i < in_port->num_out_res; i++) {
 		out_port = &in_port->data[i];
@@ -970,9 +978,17 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out_pixel(
 
 			tfe_out_res->hw_res[j] =
 				tfe_acquire.tfe_out.rsrc_node;
-			CAM_DBG(CAM_ISP, "resource type :0x%x res id:0x%x",
+
+			index = tfe_acquire.tfe_out.comp_grp_id;
+			comp_grp = &tfe_ctx->tfe_bus_comp_grp[index];
+			comp_grp->res_id[comp_grp->num_res] =
+				tfe_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",
 				tfe_out_res->hw_res[j]->res_type,
-				tfe_out_res->hw_res[j]->res_id);
+				tfe_out_res->hw_res[j]->res_id,
+				tfe_acquire.tfe_out.comp_grp_id);
 
 		}
 		tfe_out_res->res_type = CAM_ISP_RESOURCE_TFE_OUT;
@@ -2054,6 +2070,14 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		goto free_cdm;
 	}
 
+	tfe_ctx->tfe_bus_comp_grp = kcalloc(CAM_TFE_BUS_COMP_NUM_MAX,
+		sizeof(struct cam_tfe_hw_comp_record), GFP_KERNEL);
+
+	if (!tfe_ctx->tfe_bus_comp_grp) {
+		CAM_ERR(CAM_CTXT, "No memory for tfe_bus_comp_grp");
+		rc = -ENOMEM;
+		goto free_ctx;
+	}
 	/* Update in_port structure */
 	for (i = 0; i < acquire_hw_info->num_inputs; i++) {
 		rc = cam_tfe_mgr_acquire_get_unified_structure(acquire_hw_info,
@@ -2152,6 +2176,8 @@ free_ctx:
 		kfree(in_port);
 		in_port = NULL;
 	}
+	kfree(tfe_ctx->tfe_bus_comp_grp);
+	tfe_ctx->tfe_bus_comp_grp = NULL;
 err:
 	/* Dump all the current acquired HW */
 	cam_tfe_hw_mgr_dump_all_ctx();
@@ -3634,6 +3660,8 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
 	ctx->is_dual = false;
 	ctx->num_reg_dump_buf = 0;
 	ctx->last_cdm_done_req = 0;
+	kfree(ctx->tfe_bus_comp_grp);
+	ctx->tfe_bus_comp_grp = NULL;
 	atomic_set(&ctx->overflow_pending, 0);
 
 	for (i = 0; i < ctx->last_submit_bl_cmd.bl_count; i++) {
@@ -4966,6 +4994,7 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 		hw_cmd_args->ctxt_to_hw_map;
 	struct cam_isp_hw_cmd_args *isp_hw_cmd_args = NULL;
 	struct cam_packet          *packet;
+	struct cam_tfe_comp_record_query *query_cmd;
 
 	if (!hw_mgr_priv || !cmd_args) {
 		CAM_ERR(CAM_ISP, "Invalid arguments");
@@ -5019,6 +5048,13 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 			isp_hw_cmd_args->u.last_cdm_done =
 				ctx->last_cdm_done_req;
 			break;
+		case CAM_ISP_HW_MGR_GET_BUS_COMP_GROUP:
+			query_cmd = (struct cam_tfe_comp_record_query *)
+				isp_hw_cmd_args->cmd_data;
+			memcpy(query_cmd->tfe_bus_comp_grp, ctx->tfe_bus_comp_grp,
+				sizeof(struct cam_tfe_hw_comp_record) *
+				CAM_TFE_BUS_COMP_NUM_MAX);
+			break;
 		default:
 			CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
 				hw_cmd_args->cmd_type);
@@ -5717,28 +5753,46 @@ static int cam_tfe_hw_mgr_handle_hw_buf_done(
 	void                                *evt_info)
 {
 	cam_hw_event_cb_func                 tfe_hwr_irq_wm_done_cb;
-	struct cam_tfe_hw_mgr_ctx           *tfe_hw_mgr_ctx = ctx;
+	struct cam_tfe_hw_mgr_ctx            *tfe_hw_mgr_ctx = ctx;
 	struct cam_isp_hw_done_event_data    buf_done_event_data = {0};
-	struct cam_isp_hw_event_info        *event_info = evt_info;
-
-	tfe_hwr_irq_wm_done_cb = tfe_hw_mgr_ctx->common.event_cb;
+	struct cam_isp_hw_event_info         *event_info = evt_info;
+	struct cam_isp_hw_bufdone_event_info *bufdone_evt_info = NULL;
 
-	buf_done_event_data.num_handles = 1;
-	buf_done_event_data.resource_handle[0] = event_info->res_id;
-	buf_done_event_data.last_consumed_addr[0] = event_info->reg_val;
 
 	if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
 		return 0;
 
-	if (buf_done_event_data.num_handles > 0 && tfe_hwr_irq_wm_done_cb) {
-		CAM_DBG(CAM_ISP, "Notify ISP context");
+	event_info = (struct cam_isp_hw_event_info *)evt_info;
+	if (!event_info->event_data) {
+		CAM_ERR(CAM_ISP,
+			"No additional buf done data failed to process for HW: %u",
+			event_info->hw_type);
+		return -EINVAL;
+	}
+
+	tfe_hwr_irq_wm_done_cb = tfe_hw_mgr_ctx->common.event_cb;
+
+	bufdone_evt_info = (struct cam_isp_hw_bufdone_event_info *)
+				event_info->event_data;
+	buf_done_event_data.resource_handle = 0;
+
+	CAM_DBG(CAM_ISP,
+		"Buf done for TFE: %d res_id: 0x%x last consumed addr: 0x%x ctx: %u",
+		event_info->hw_idx, event_info->res_id,
+		bufdone_evt_info->last_consumed_addr, tfe_hw_mgr_ctx->ctx_index);
+
+	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 (buf_done_event_data.resource_handle > 0 && tfe_hwr_irq_wm_done_cb) {
+		CAM_DBG(CAM_ISP, "Buf done for out_res->res_id: 0x%x in ctx: %u",
+			event_info->res_id, tfe_hw_mgr_ctx->ctx_index);
 		tfe_hwr_irq_wm_done_cb(tfe_hw_mgr_ctx->common.cb_priv,
 			CAM_ISP_HW_EVENT_DONE, (void *)&buf_done_event_data);
 	}
 
-	CAM_DBG(CAM_ISP, "Buf done for out_res->res_id: 0x%x",
-		event_info->res_id);
-
 	return 0;
 }
 

+ 30 - 0
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_TFE_HW_MGR_H_
@@ -43,6 +44,33 @@ struct cam_tfe_hw_mgr_debug {
 	uint32_t       per_req_reg_dump;
 };
 
+/**
+ * struct cam_tfe_hw_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
+ *
+ */
+struct cam_tfe_hw_comp_record {
+	uint32_t num_res;
+	uint32_t res_id[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
+};
+
+/**
+ * struct cam_tfe_comp_record_query
+ *
+ * @brief:              Structure record the bus comp group pointer information
+ * @tfe_bus_comp_grp:   Tfe bus comp group pointer
+ * @reserved:           used to make parent compatible with struct cam_isp_comp_record_query
+ *
+ */
+struct cam_tfe_comp_record_query {
+	struct cam_tfe_hw_comp_record        *tfe_bus_comp_grp;
+	void *reserved;
+};
+
 /**
  * struct cam_tfe_hw_mgr_ctx - TFE HW manager Context object
  *
@@ -84,6 +112,7 @@ struct cam_tfe_hw_mgr_debug {
  *                              dual TFE
  * @packet                     CSL packet from user mode driver
  * @bw_config_version          BW Config version
+ * @tfe_bus_comp_grp          pointer to tfe comp group info
  */
 struct cam_tfe_hw_mgr_ctx {
 	struct list_head                list;
@@ -126,6 +155,7 @@ struct cam_tfe_hw_mgr_ctx {
 	uint32_t                        dual_tfe_irq_mismatch_cnt;
 	struct cam_packet              *packet;
 	uint32_t                        bw_config_version;
+	struct cam_tfe_hw_comp_record  *tfe_bus_comp_grp;
 };
 
 /**

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -30,6 +30,7 @@
 #define CAM_IFE_BUS_COMP_NUM_MAX         18
 #define CAM_SFE_BUS_COMP_NUM_MAX         12
 #define CAM_TFE_BW_LIMITER_CONFIG_V1     1
+#define CAM_TFE_BUS_COMP_NUM_MAX         18
 
 /* maximum context numbers for TFE */
 #define CAM_TFE_CTX_MAX      4

+ 26 - 22
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c

@@ -1457,7 +1457,7 @@ static int cam_tfe_bus_acquire_tfe_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;
 	return rc;
 
 release_wm:
@@ -1829,12 +1829,13 @@ static int cam_tfe_bus_bufdone_bottom_half(
 	struct cam_tfe_bus_priv            *bus_priv,
 	struct cam_tfe_irq_evt_payload *evt_payload)
 {
-	struct cam_tfe_bus_common_data     *common_data;
-	struct cam_tfe_bus_tfe_out_data    *out_rsrc_data;
-	struct cam_isp_hw_event_info        evt_info;
-	struct cam_isp_resource_node       *out_rsrc = NULL;
-	struct cam_tfe_bus_comp_grp_data   *comp_rsrc_data;
-	uint32_t i, j;
+	struct cam_tfe_bus_common_data       *common_data;
+	struct cam_tfe_bus_tfe_out_data      *out_rsrc_data;
+	struct cam_isp_hw_event_info          evt_info;
+	struct cam_isp_resource_node         *out_rsrc = NULL;
+	struct cam_tfe_bus_comp_grp_data     *comp_rsrc_data;
+	struct cam_isp_hw_bufdone_event_info  bufdone_evt_info = {0};
+	uint32_t i;
 
 	common_data = &bus_priv->common_data;
 
@@ -1849,25 +1850,28 @@ static int cam_tfe_bus_bufdone_bottom_half(
 		if (evt_payload->bus_irq_val[0] &
 			BIT(comp_rsrc_data->comp_grp_id +
 			bus_priv->common_data.comp_done_shift)) {
-			for (j = 0; j < comp_rsrc_data->acquire_dev_cnt; j++) {
-				out_rsrc = comp_rsrc_data->out_rsrc[j];
-				out_rsrc_data = out_rsrc->res_priv;
-				evt_info.res_type = out_rsrc->res_type;
-				evt_info.hw_idx = out_rsrc->hw_intf->hw_idx;
-				evt_info.res_id = out_rsrc->res_id;
-				evt_info.reg_val =
-					cam_tfe_bus_get_last_consumed_addr(
-						out_rsrc_data->bus_priv,
-						out_rsrc_data->out_id);
+			out_rsrc = comp_rsrc_data->out_rsrc[0];
+			out_rsrc_data = out_rsrc->res_priv;
+			evt_info.res_type = out_rsrc->res_type;
+			evt_info.hw_idx = out_rsrc->hw_intf->hw_idx;
+			evt_info.res_id = out_rsrc->res_id;
+			bufdone_evt_info.res_id = out_rsrc->res_id;
+			bufdone_evt_info.comp_grp_id = comp_rsrc_data->comp_grp_id;
+			bufdone_evt_info.last_consumed_addr =
+				cam_tfe_bus_get_last_consumed_addr(
+					out_rsrc_data->bus_priv,
+					out_rsrc_data->out_id);
+			evt_info.event_data = (void *)&bufdone_evt_info;
+
+			if (out_rsrc_data->event_cb)
 				out_rsrc_data->event_cb(out_rsrc_data->priv,
 					CAM_ISP_HW_EVENT_DONE,
 					(void *)&evt_info);
-			}
-
-			evt_payload->bus_irq_val[0] &=
-				~BIT(comp_rsrc_data->comp_grp_id +
-				bus_priv->common_data.comp_done_shift);
 		}
+
+		evt_payload->bus_irq_val[0] &=
+			BIT(comp_rsrc_data->comp_grp_id +
+			bus_priv->common_data.comp_done_shift);
 	}
 
 	return 0;