Просмотр исходного кода

msm: camera: common: Add debug infrastructure for camera drv

Add error handling and information logging for drv error and
info irqs for drv. Also, add debugfs for vote up and down irqs.
Add ddr and mnoc register value logging in vote up and down
irq bottom half.

CRs-Fixed: 3065551
Change-Id: I5332658924762a528625e628c3fa5d5dec07da62
Signed-off-by: Mukund Madhusudan Atre <[email protected]>
Mukund Madhusudan Atre 3 лет назад
Родитель
Сommit
b61b425af9

+ 16 - 3
drivers/cam_cpas/cam_cpas_hw.c

@@ -2384,7 +2384,7 @@ static int cam_cpas_hw_get_hw_info(void *hw_priv,
 	return 0;
 }
 
-static int cam_cpas_log_vote(struct cam_hw_info *cpas_hw)
+static int cam_cpas_log_vote(struct cam_hw_info *cpas_hw, bool ddr_only)
 {
 	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
 	struct cam_cpas_private_soc *soc_private =
@@ -2393,9 +2393,10 @@ static int cam_cpas_log_vote(struct cam_hw_info *cpas_hw)
 	struct cam_cpas_tree_node *curr_node;
 	struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
 
-	if ((cpas_core->streamon_clients > 0) && soc_private->enable_smart_qos)
+	if ((cpas_core->streamon_clients > 0) && soc_private->enable_smart_qos && !ddr_only)
 		cam_cpas_print_smart_qos_priority(cpas_hw);
 
+
 	/*
 	 * First print rpmh registers as early as possible to catch nearest
 	 * state of rpmh after an issue (overflow) occurs.
@@ -2439,6 +2440,9 @@ static int cam_cpas_log_vote(struct cam_hw_info *cpas_hw)
 		}
 	}
 
+	if (ddr_only)
+		return 0;
+
 	for (i = 0; i < cpas_core->num_axi_ports; i++) {
 		if (cpas_core->axi_port[i].bus_client.common_data.is_drv_port) {
 			CAM_INFO(CAM_PERF,
@@ -3131,7 +3135,16 @@ static int cam_cpas_hw_process_cmd(void *hw_priv,
 		break;
 	}
 	case CAM_CPAS_HW_CMD_LOG_VOTE: {
-		rc = cam_cpas_log_vote(hw_priv);
+		bool *ddr_only;
+
+		if (sizeof(bool) != arg_size) {
+			CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
+				cmd_type, arg_size);
+			break;
+		}
+
+		ddr_only = (bool *) cmd_args;
+		rc = cam_cpas_log_vote(hw_priv, *ddr_only);
 		break;
 	}
 

+ 3 - 4
drivers/cam_cpas/cam_cpas_intf.c

@@ -579,9 +579,8 @@ int cam_cpas_start(uint32_t client_handle,
 }
 EXPORT_SYMBOL(cam_cpas_start);
 
-void cam_cpas_log_votes(void)
+void cam_cpas_log_votes(bool ddr_only)
 {
-	uint32_t dummy_args;
 	int rc;
 
 	if (!CAM_CPAS_INTF_INITIALIZED()) {
@@ -592,8 +591,8 @@ void cam_cpas_log_votes(void)
 	if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
 		rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
 			g_cpas_intf->hw_intf->hw_priv,
-			CAM_CPAS_HW_CMD_LOG_VOTE, &dummy_args,
-			sizeof(dummy_args));
+			CAM_CPAS_HW_CMD_LOG_VOTE, &ddr_only,
+			sizeof(ddr_only));
 		if (rc)
 			CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
 	} else {

+ 3 - 1
drivers/cam_cpas/include/cam_cpas_api.h

@@ -769,10 +769,12 @@ const char *cam_cpas_axi_util_drv_vote_lvl_to_string(
  * @brief: API to print the all bw votes of axi client. It also print the
  *     applied camnoc axi clock vote value and ahb vote value
  *
+ * @ddr_only: Print only DDR info
+ *
  * @return 0 on success.
  *
  */
-void cam_cpas_log_votes(void);
+void cam_cpas_log_votes(bool ddr_only);
 
 /**
  * cam_cpas_select_qos_settings()

+ 5 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h

@@ -256,11 +256,10 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_780_top_irq_desc[] =
 		.bitmask  = BIT(1),
 		.err_type = CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR,
 		.err_name = "FATAL_SENSOR_SWITCHING_IRQ",
-		.desc = "Fatal Error duirng dynamically switching between 2 sensors",
+		.desc = "Fatal Error during dynamically switching between 2 sensors",
 	},
 	{
 		.bitmask  = BIT(18),
-		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_NO_VOTE_DN",
 		.desc = "vote_up is asserted before IDLE is encountered in a frame",
 	},
@@ -269,6 +268,7 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_780_top_irq_desc[] =
 		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_VOTE_UP_LATE",
 		.desc = "vote_up is asserted at the same time as an SOF",
+		.err_handler = cam_ife_csid_hw_ver2_drv_err_handler,
 	},
 	{
 		.bitmask  = BIT(20),
@@ -1244,6 +1244,8 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.drv_cfg0_addr                           = 0x13c,
 	.drv_cfg1_addr                           = 0x140,
 	.drv_cfg2_addr                           = 0x144,
+	.debug_drv_0_addr                        = 0x148,
+	.debug_drv_1_addr                        = 0x14C,
 
 	/*configurations */
 	.major_version                           = 6,
@@ -1292,7 +1294,7 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.ipp_irq_mask_all                        = 0x7FFF,
 	.rdi_irq_mask_all                        = 0x7FFF,
 	.ppp_irq_mask_all                        = 0xFFFF,
-	.top_err_irq_mask                        = 0x1C0002,
+	.top_err_irq_mask                        = 0x180002,
 	.rst_loc_path_only_val                   = 0x0,
 	.rst_loc_complete_csid_val               = 0x1,
 	.rst_mode_frame_boundary_val             = 0x0,

+ 5 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid880.h

@@ -264,11 +264,10 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_880_top_irq_desc[] =
 		.bitmask  = BIT(1),
 		.err_type = CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR,
 		.err_name = "FATAL_SENSOR_SWITCHING_IRQ",
-		.desc = "Fatal Error duirng dynamically switching between 2 sensors",
+		.desc = "Fatal Error during dynamically switching between 2 sensors",
 	},
 	{
 		.bitmask  = BIT(18),
-		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_NO_VOTE_DN",
 		.desc = "vote_up is asserted before IDLE is encountered in a frame",
 	},
@@ -277,6 +276,7 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_880_top_irq_desc[] =
 		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_VOTE_UP_LATE",
 		.desc = "vote_up is asserted at the same time as an SOF",
+		.err_handler = cam_ife_csid_hw_ver2_drv_err_handler,
 	},
 	{
 		.bitmask  = BIT(20),
@@ -1283,6 +1283,8 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.drv_cfg0_addr                           = 0x13c,
 	.drv_cfg1_addr                           = 0x140,
 	.drv_cfg2_addr                           = 0x144,
+	.debug_drv_0_addr                        = 0x148,
+	.debug_drv_1_addr                        = 0x14C,
 
 	/*configurations */
 	.major_version                           = 6,
@@ -1331,7 +1333,7 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.ipp_irq_mask_all                        = 0x7FFF,
 	.rdi_irq_mask_all                        = 0x7FFF,
 	.ppp_irq_mask_all                        = 0xFFFF,
-	.top_err_irq_mask                        = 0x1C0002,
+	.top_err_irq_mask                        = 0x180002,
 	.rst_loc_path_only_val                   = 0x0,
 	.rst_loc_complete_csid_val               = 0x1,
 	.rst_mode_frame_boundary_val             = 0x0,

+ 5 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h

@@ -61,6 +61,9 @@
 #define CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO            BIT(7)
 #define CAM_IFE_CSID_DEBUG_DISABLE_EARLY_EOF              BIT(8)
 #define CAM_IFE_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ           BIT(9)
+#define CAM_IFE_CSID_DEBUG_ENABLE_VOTE_UP_IRQ             BIT(10)
+#define CAM_IFE_CSID_DEBUG_ENABLE_VOTE_DN_IRQ             BIT(11)
+#define CAM_IFE_CSID_DEBUG_ENABLE_ERR_NO_VOTE_DN_IRQ      BIT(12)
 
 /* Binning supported masks. Binning support changes for specific paths
  * and also for targets. With the mask, we handle the supported features
@@ -300,6 +303,7 @@ struct cam_ife_csid_hw_counters {
  * @rx_capture_vc:         rx packet vc capture
  * @rx_capture_dt:         rx packet dt capture
  * @rst_capture_strobes:   rx packet capture rst strobes
+ * @top_mask:              Debug mask for top irq
  * @rx_mask:               Debug mask for rx irq
  * @path_mask:             Debug mask for path irq
  * @test_bus_val:          CSID test bus value
@@ -311,6 +315,7 @@ struct cam_ife_csid_debug_info {
 	uint32_t                          rx_capture_vc;
 	uint32_t                          rx_capture_dt;
 	uint32_t                          rst_capture_strobes;
+	uint32_t                          top_mask;
 	uint32_t                          rx_mask;
 	uint32_t                          path_mask;
 	uint32_t                          test_bus_val;

+ 156 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -179,6 +179,18 @@ static int cam_ife_csid_ver2_set_debug(
 			csid_hw->debug_info.rx_mask |=
 				IFE_CSID_VER2_RX_UNMAPPED_VC_DT;
 			break;
+		case CAM_IFE_CSID_DEBUG_ENABLE_VOTE_UP_IRQ:
+			csid_hw->debug_info.top_mask |=
+				IFE_CSID_VER2_TOP_INFO_VOTE_UP;
+			break;
+		case CAM_IFE_CSID_DEBUG_ENABLE_VOTE_DN_IRQ:
+			csid_hw->debug_info.top_mask |=
+				IFE_CSID_VER2_TOP_INFO_VOTE_DN;
+			break;
+		case CAM_IFE_CSID_DEBUG_ENABLE_ERR_NO_VOTE_DN_IRQ:
+			csid_hw->debug_info.top_mask |=
+				IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN;
+			break;
 		default:
 			break;
 		}
@@ -305,6 +317,36 @@ static int cam_ife_csid_ver2_put_evt_payload(
 	return 0;
 }
 
+static int cam_ife_csid_ver2_top_info_irq_top_half(
+	uint32_t                                   evt_id,
+	struct cam_irq_th_payload                 *th_payload)
+{
+	int rc = 0;
+	struct cam_ife_csid_ver2_hw               *csid_hw = NULL;
+	struct cam_ife_csid_ver2_evt_payload      *evt_payload;
+
+	csid_hw = th_payload->handler_priv;
+
+	rc  = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload,
+			&csid_hw->path_free_payload_list,
+			&csid_hw->path_payload_lock);
+	if (rc) {
+		CAM_WARN_RATE_LIMIT(CAM_ISP, "CSID:%d get payload failed, TOP info status: 0x%x",
+			csid_hw->hw_intf->hw_idx,
+			th_payload->evt_status_arr[0]);
+		return rc;
+	}
+
+	CAM_DBG(CAM_ISP, "CSID:%d TOP info status: 0x%x", csid_hw->hw_intf->hw_idx,
+		th_payload->evt_status_arr[0]);
+
+	evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
+	ktime_get_boottime_ts64(&evt_payload->timestamp);
+	th_payload->evt_payload_priv = evt_payload;
+
+	return 0;
+}
+
 static int cam_ife_csid_ver2_top_err_irq_top_half(
 	uint32_t                                   evt_id,
 	struct cam_irq_th_payload                 *th_payload)
@@ -312,11 +354,8 @@ static int cam_ife_csid_ver2_top_err_irq_top_half(
 	int rc = 0;
 	struct cam_ife_csid_ver2_hw               *csid_hw = NULL;
 	struct cam_ife_csid_ver2_evt_payload      *evt_payload;
-	struct cam_ife_csid_ver2_reg_info         *csid_reg = NULL;
 
 	csid_hw = th_payload->handler_priv;
-	csid_reg = (struct cam_ife_csid_ver2_reg_info *)
-			csid_hw->core_info->csid_reg;
 
 	rc  = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload,
 			&csid_hw->path_free_payload_list,
@@ -332,6 +371,7 @@ static int cam_ife_csid_ver2_top_err_irq_top_half(
 	}
 
 	evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
+	ktime_get_boottime_ts64(&evt_payload->timestamp);
 	th_payload->evt_payload_priv = evt_payload;
 
 	return 0;
@@ -484,7 +524,7 @@ static int cam_ife_csid_ver2_path_top_half(
 	}
 
 	evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
-
+	ktime_get_boottime_ts64(&evt_payload->timestamp);
 	th_payload->evt_payload_priv = evt_payload;
 
 	return 0;
@@ -1292,6 +1332,27 @@ void cam_ife_csid_hw_ver2_rdi_line_buffer_conflict_handler(
 
 }
 
+void cam_ife_csid_hw_ver2_drv_err_handler(void *csid)
+{
+	struct cam_ife_csid_ver2_hw       *csid_hw  = csid;
+	struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg;
+	struct cam_hw_soc_info            *soc_info = &csid_hw->hw_info->soc_info;
+	void __iomem                      *base =
+		soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
+	uint32_t cfg0_val = 0, cfg1_val = 0, cfg2_val = 0, debug_drv_0_val = 0, debug_drv_1_val = 0;
+
+	cfg0_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg0_addr);
+	cfg1_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg1_addr);
+	cfg2_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg2_addr);
+	debug_drv_0_val = cam_io_r_mb(base + csid_reg->cmn_reg->debug_drv_0_addr);
+	debug_drv_1_val = cam_io_r_mb(base + csid_reg->cmn_reg->debug_drv_1_addr);
+
+	CAM_INFO(CAM_ISP,
+		"CSID[%d] DRV cfg0:0x%x cfg1:0x%x cfg2:0x%x qtimer_val [start:end] [0x%x : 0x%x]",
+		csid_hw->hw_intf->hw_idx, cfg0_val, cfg1_val, cfg2_val, debug_drv_0_val,
+		debug_drv_1_val);
+}
+
 void cam_ife_csid_hw_ver2_mup_mismatch_handler(
 	void *csid, void *resource)
 {
@@ -1456,7 +1517,8 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
 	struct cam_isp_resource_node *res,
 	uint32_t                     index,
 	uint32_t                     err_mask,
-	uint32_t                     irq_status)
+	uint32_t                     irq_status,
+	struct cam_ife_csid_ver2_evt_payload *evt_payload)
 {
 	const uint8_t                          **irq_reg_tag;
 	const struct cam_ife_csid_ver2_reg_info *csid_reg;
@@ -1497,9 +1559,11 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
 	bit_pos = 0;
 	while (status) {
 		if (status & 0x1)
-			CAM_INFO(CAM_ISP, "CSID[%d] IRQ %s %s ",
+			CAM_INFO(CAM_ISP, "CSID[%d] IRQ %s %s timestamp:[%lld:%lld]",
 				csid_hw->hw_intf->hw_idx, irq_reg_tag[index],
-				csid_reg->path_irq_desc[bit_pos].desc);
+				csid_reg->path_irq_desc[bit_pos].desc,
+				evt_payload->timestamp.tv_sec,
+				evt_payload->timestamp.tv_nsec);
 
 		bit_pos++;
 		status >>= 1;
@@ -1520,6 +1584,57 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
 	return err_type;
 }
 
+static int cam_ife_csid_ver2_top_info_irq_bottom_half(
+	void                                      *handler_priv,
+	void                                      *evt_payload_priv)
+{
+	struct cam_ife_csid_ver2_evt_payload       *payload;
+	struct cam_ife_csid_ver2_hw                *csid_hw = NULL;
+	uint32_t                                    irq_status;
+
+	if (!handler_priv || !evt_payload_priv) {
+		CAM_ERR(CAM_ISP, "Invalid params");
+		return -EINVAL;
+	}
+
+	payload = evt_payload_priv;
+	csid_hw = handler_priv;
+
+	irq_status = payload->irq_reg_val & csid_hw->debug_info.top_mask;
+	if (!irq_status) {
+		CAM_ERR(CAM_ISP, "Unexpected Scenario");
+		return 0;
+	}
+
+	if (irq_status & IFE_CSID_VER2_TOP_INFO_VOTE_UP) {
+		cam_cpas_log_votes(true);
+		CAM_INFO(CAM_ISP, "CSID:%d INFO_VOTE_UP timestamp:[%lld:%lld]",
+			csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
+			payload->timestamp.tv_nsec);
+	}
+
+	if (irq_status & IFE_CSID_VER2_TOP_INFO_VOTE_DN) {
+		cam_cpas_log_votes(true);
+		CAM_INFO(CAM_ISP, "CSID:%d INFO_VOTE_DN timestamp:[%lld:%lld]",
+			csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
+			payload->timestamp.tv_nsec);
+	}
+
+	if (irq_status & IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN) {
+		CAM_INFO(CAM_ISP, "CSID:%d ERR_NO_VOTE_DN timestamp:[%lld:%lld]",
+			csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
+			payload->timestamp.tv_nsec);
+
+		cam_ife_csid_hw_ver2_drv_err_handler(csid_hw);
+	}
+
+	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
+		&csid_hw->path_free_payload_list,
+		&csid_hw->path_payload_lock);
+
+	return 0;
+}
+
 static int cam_ife_csid_ver2_top_err_irq_bottom_half(
 	void                                      *handler_priv,
 	void                                      *evt_payload_priv)
@@ -1555,8 +1670,10 @@ static int cam_ife_csid_ver2_top_err_irq_bottom_half(
 			CAM_ERR(CAM_ISP, "%s %s",
 				csid_reg->top_irq_desc[i].err_name,
 				csid_reg->top_irq_desc[i].desc);
+
 			if (csid_reg->top_irq_desc[i].err_handler)
 				csid_reg->top_irq_desc[i].err_handler(csid_hw);
+
 			event_type |= csid_reg->top_irq_desc[i].err_type;
 		}
 	}
@@ -1697,7 +1814,7 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
 	err_type = cam_ife_csid_ver2_parse_path_irq_status(
 		csid_hw, res,
 		CAM_IFE_CSID_IRQ_REG_IPP,
-		err_mask, irq_status_ipp);
+		err_mask, irq_status_ipp, payload);
 
 	if (err_type)
 		cam_ife_csid_ver2_handle_event_err(csid_hw,
@@ -1778,9 +1895,10 @@ static int cam_ife_csid_ver2_ppp_bottom_half(
 			csid_hw->hw_intf->hw_idx);
 		goto unlock;
 	}
+
 	err_type = cam_ife_csid_ver2_parse_path_irq_status(
 		csid_hw, res, CAM_IFE_CSID_IRQ_REG_PPP,
-		err_mask, irq_status_ppp);
+		err_mask, irq_status_ppp, payload);
 
 	if (err_type)
 		cam_ife_csid_ver2_handle_event_err(csid_hw,
@@ -1873,7 +1991,7 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
 
 	err_type = cam_ife_csid_ver2_parse_path_irq_status(csid_hw, res,
 		path_cfg->irq_reg_idx,
-		err_mask, irq_status_rdi);
+		err_mask, irq_status_rdi, payload);
 
 	spin_unlock(&csid_hw->lock_state);
 	if (err_type) {
@@ -4086,6 +4204,7 @@ static int cam_ife_csid_ver2_enable_hw(
 	const struct cam_ife_csid_ver2_path_reg_info *path_reg = NULL;
 	uint32_t top_err_irq_mask = 0;
 	uint32_t buf_done_irq_mask = 0;
+	uint32_t top_info_irq_mask = 0;
 
 	if (csid_hw->flags.device_enabled) {
 		CAM_DBG(CAM_ISP, "CSID[%d] hw has already been enabled",
@@ -4172,6 +4291,27 @@ static int cam_ife_csid_ver2_enable_hw(
 		goto unsubscribe_top_err;
 	}
 
+	if (csid_hw->debug_info.top_mask) {
+		top_info_irq_mask = csid_hw->debug_info.top_mask;
+		csid_hw->top_info_irq_handle = cam_irq_controller_subscribe_irq(
+						csid_hw->top_irq_controller,
+						CAM_IRQ_PRIORITY_1,
+						&top_info_irq_mask,
+						csid_hw,
+						cam_ife_csid_ver2_top_info_irq_top_half,
+						cam_ife_csid_ver2_top_info_irq_bottom_half,
+						csid_hw->tasklet,
+						&tasklet_bh_api,
+						CAM_IRQ_EVT_GROUP_0);
+
+		if (csid_hw->top_info_irq_handle < 1) {
+			CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Top Info Irq fail",
+				csid_hw->hw_intf->hw_idx);
+			return -EINVAL;
+			goto unsubscribe_top_err;
+		}
+	}
+
 	csid_hw->flags.device_enabled = true;
 	csid_hw->flags.fatal_err_detected = false;
 	CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
@@ -4581,6 +4721,12 @@ int cam_ife_csid_ver2_stop(void *hw_priv,
 		csid_hw->top_err_irq_handle = 0;
 	}
 
+	if (csid_hw->debug_info.top_mask) {
+		cam_irq_controller_unsubscribe_irq(csid_hw->top_irq_controller,
+			csid_hw->top_info_irq_handle);
+		csid_hw->top_info_irq_handle = 0;
+	}
+
 	cam_ife_csid_ver2_disable_csi2(csid_hw);
 	if (csid_hw->debug_info.test_bus_enabled)
 		cam_ife_csid_ver2_testbus_config(csid_hw, 0x0);

+ 23 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h

@@ -12,6 +12,10 @@
 #include "cam_ife_csid_soc.h"
 #include "cam_ife_csid_common.h"
 
+#define IFE_CSID_VER2_TOP_INFO_VOTE_UP                BIT(16)
+#define IFE_CSID_VER2_TOP_INFO_VOTE_DN                BIT(17)
+#define IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN              BIT(18)
+
 #define IFE_CSID_VER2_RX_DL0_EOT_CAPTURED             BIT(0)
 #define IFE_CSID_VER2_RX_DL1_EOT_CAPTURED             BIT(1)
 #define IFE_CSID_VER2_RX_DL2_EOT_CAPTURED             BIT(2)
@@ -114,6 +118,18 @@ struct cam_ife_csid_ver2_top_cfg {
 struct cam_ife_csid_ver2_evt_payload {
 	struct list_head            list;
 	uint32_t                    irq_reg_val;
+	struct timespec64           timestamp;
+};
+
+/*
+ * struct cam_ife_csid_ver2_camif_data: place holder for camif parameters
+ *
+ * @epoch0_cfg:   Epoch 0 configuration value
+ * @epoch1_cfg:   Epoch 1 configuration value
+ */
+struct cam_ife_csid_ver2_camif_data {
+	uint32_t epoch0;
+	uint32_t epoch1;
 };
 
 /*
@@ -382,6 +398,8 @@ struct cam_ife_csid_ver2_common_reg_info {
 	uint32_t drv_cfg0_addr;
 	uint32_t drv_cfg1_addr;
 	uint32_t drv_cfg2_addr;
+	uint32_t debug_drv_0_addr;
+	uint32_t debug_drv_1_addr;
 
 	/*Shift Bit Configurations*/
 	uint32_t rst_done_shift_val;
@@ -558,6 +576,8 @@ struct cam_ife_csid_ver2_reg_info {
  * @tasklet:                  Tasklet for irq events
  * @reset_irq_handle:         Reset irq handle
  * @buf_done_irq_handle:      Buf done irq handle
+ * @top_err_irq_handle:       Top Err IRQ handle
+ * @top_info_irq_handle:      Top Info IRQ handle
  * @sync_mode:                Master/Slave modes
  * @mup:                      MUP for incoming VC of next frame
  * @discard_frame_per_path:   Count of paths dropping initial frames
@@ -601,6 +621,7 @@ struct cam_ife_csid_ver2_hw {
 	int                                    reset_irq_handle;
 	int                                    buf_done_irq_handle;
 	int                                    top_err_irq_handle;
+	int                                    top_info_irq_handle;
 	enum cam_isp_hw_sync_mode              sync_mode;
 	uint32_t                               mup;
 	atomic_t                               discard_frame_per_path;
@@ -647,5 +668,7 @@ void cam_ife_csid_ver2_print_illegal_programming_irq_status(void *csid_hw, void
 void cam_ife_csid_ver2_print_format_measure_info(void *csid_hw, void *res);
 void cam_ife_csid_hw_ver2_mup_mismatch_handler(void *csid_hw, void *res);
 void cam_ife_csid_hw_ver2_rdi_line_buffer_conflict_handler(void *csid_hw);
+void cam_ife_csid_hw_ver2_drv_err_handler(void *csid);
+
 
 #endif

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c

@@ -883,7 +883,7 @@ static int cam_sfe_top_handle_overflow(
 	cam_sfe_top_print_debug_reg_info(top_priv);
 
 	if (bus_overflow_status) {
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 		overflow_info->is_bus_overflow = true;
 	}
 

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c

@@ -1,6 +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.
  */
 
 #include <linux/slab.h>
@@ -571,7 +572,7 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 
 		ret = CAM_VFE_IRQ_STATUS_OVERFLOW;
 
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 	}
 

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c

@@ -888,7 +888,7 @@ static void cam_vfe_camif_lite_print_status(uint32_t *status,
 
 		if (status_0 & 0x40000000) {
 			CAM_INFO(CAM_ISP, "PD PIPE OVERFLOW");
-			cam_cpas_log_votes();
+			cam_cpas_log_votes(false);
 		}
 	}
 
@@ -1020,7 +1020,7 @@ print_state:
 
 	if ((err_type == CAM_VFE_IRQ_STATUS_OVERFLOW) &&
 		bus_overflow_status)
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 }
 

+ 3 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c

@@ -1,6 +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.
  */
 
 #include <linux/slab.h>
@@ -903,7 +904,7 @@ static int cam_vfe_camif_handle_irq_bottom_half(void *handler_priv,
 		CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
 			soc_private->ife_clk_src);
 
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 		if (camif_priv->camif_debug & CAMIF_DEBUG_ENABLE_REG_DUMP)
 			cam_vfe_camif_reg_dump(camif_node->res_priv);
@@ -931,7 +932,7 @@ static int cam_vfe_camif_handle_irq_bottom_half(void *handler_priv,
 		CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
 			soc_private->ife_clk_src);
 
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 		if (camif_priv->camif_debug & CAMIF_DEBUG_ENABLE_REG_DUMP)
 			cam_vfe_camif_reg_dump(camif_node->res_priv);

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c

@@ -1283,7 +1283,7 @@ print_state:
 	if ((err_type == CAM_VFE_IRQ_STATUS_OVERFLOW) &&
 		((camif_priv->cam_common_cfg.input_mux_sel_pp & 0x3) ||
 		(bus_overflow_status)))
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 }
 
 static int cam_vfe_camif_ver3_handle_irq_top_half(uint32_t evt_id,

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c

@@ -1,6 +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.
  */
 
 #include <linux/slab.h>
@@ -572,7 +573,7 @@ static int cam_vfe_rdi_handle_irq_bottom_half(void *handler_priv,
 			rdi_priv->event_cb(rdi_priv->priv,
 			CAM_ISP_HW_EVENT_ERROR,
 			(void *)&evt_info);
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 	}
 end:
 	cam_vfe_rdi_put_evt_payload(rdi_priv, &payload);

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

@@ -560,7 +560,7 @@ static int cam_vfe_top_ver4_print_overflow_debug_info(
 	cam_vfe_top_ver4_dump_timestamps(top_priv, res_id);
 	cam_cpas_dump_camnoc_buff_fill_info(soc_private->cpas_handle);
 	if (bus_overflow_status)
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 	if (violation_status)
 		CAM_INFO(CAM_ISP, "VFE[%d] Bus violation status: 0x%x",