Browse Source

msm: camera: isp: Add VFE/SFE overflow debug info

For new targets, VFE/SFE overflow errors are back pressured to
CSID recovery module. Error IRQs are not available with VFE/SFE
blocks for such errors.
Above errors are to be propagated from CSID driver to downstream
module drivers to print the relevant debug data and handle
the error.
This commit implements propagation of error and
printing the debug info in VFE and SFE.

CRs-Fixed: 2830502
Change-Id: I24ecd7433b3324505e92d9d55576ca3107e66fdd
Signed-off-by: Gaurav Jindal <[email protected]>
Gaurav Jindal 4 years ago
parent
commit
ee3a268ce0
21 changed files with 976 additions and 271 deletions
  1. 91 46
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
  2. 3 1
      drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
  3. 10 10
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h
  4. 0 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid580.h
  5. 18 14
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid680.h
  6. 4 4
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c
  7. 204 53
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c
  8. 5 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h
  9. 3 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
  10. 58 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe680.h
  11. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_core.c
  12. 80 42
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c
  13. 7 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.h
  14. 1 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
  15. 153 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h
  16. 65 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h
  17. 15 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.h
  18. 2 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
  19. 2 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c
  20. 244 85
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c
  21. 10 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.h

+ 91 - 46
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -400,36 +400,74 @@ static int cam_ife_hw_mgr_is_rdi_res(uint32_t res_id)
 	return rc;
 }
 
-static int cam_ife_hw_mgr_dump_hw_src_clock(uint8_t hw_idx,
-	enum cam_isp_hw_type hw_type)
-{
+static int cam_ife_hw_mgr_notify_overflow(
+	struct cam_isp_hw_event_info    *evt,
+	void                            *ctx)
+{
+	int                             i;
+	int                             res_id;
+	int                             ife_res_id = -1;
+	int                             sfe_res_id = -1;
+	struct cam_hw_intf             *hw_if = NULL;
+	struct cam_ife_hw_mgr_ctx      *hw_mgr_ctx = ctx;
+
+	switch(evt->res_id) {
+	case  CAM_IFE_PIX_PATH_RES_IPP:
+		ife_res_id = CAM_ISP_HW_VFE_IN_CAMIF;
+		sfe_res_id = CAM_ISP_HW_SFE_IN_PIX;
+		break;
+	case CAM_IFE_PIX_PATH_RES_RDI_0:
+		ife_res_id = CAM_ISP_HW_VFE_IN_RDI0;
+		sfe_res_id =CAM_ISP_HW_SFE_IN_RDI0;
+		break;
+	case CAM_IFE_PIX_PATH_RES_RDI_1:
+		ife_res_id = CAM_ISP_HW_VFE_IN_RDI1;
+		sfe_res_id = CAM_ISP_HW_SFE_IN_RDI1;
+		break;
+	case CAM_IFE_PIX_PATH_RES_RDI_2:
+		ife_res_id = CAM_ISP_HW_VFE_IN_RDI2;
+		sfe_res_id = CAM_ISP_HW_SFE_IN_RDI2;
+		break;
+	case CAM_IFE_PIX_PATH_RES_RDI_3:
+		ife_res_id = CAM_ISP_HW_VFE_IN_RDI3;
+		sfe_res_id = CAM_ISP_HW_SFE_IN_RDI3;
+		break;
+	case CAM_IFE_PIX_PATH_RES_RDI_4:
+		sfe_res_id = CAM_ISP_HW_SFE_IN_RDI4;
+		break;
+	default:
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id %d", evt->res_id);
+		return -EINVAL;
+	}
 
-	struct cam_isp_hw_intf_data               *hw_intf_data = NULL;
-	struct cam_hw_intf                        *hw_intf = NULL;
-	uint8_t                                    dummy_args;
+	for (i = 0; i < hw_mgr_ctx->num_base; i++) {
 
-	switch (hw_type) {
-	case CAM_ISP_HW_TYPE_VFE:
-		if (!g_ife_hw_mgr.ife_devices[hw_idx]) {
-			CAM_ERR(CAM_ISP, "No vfe device added yet");
-			return -ENODEV;
+		res_id = -1;
+		if (hw_mgr_ctx->base[i].idx != evt->hw_idx)
+			continue;
+
+		if (hw_mgr_ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE) {
+			hw_if = g_ife_hw_mgr.ife_devices[evt->hw_idx]->hw_intf;
+			res_id = ife_res_id;
+		} else if (hw_mgr_ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) {
+			hw_if = g_ife_hw_mgr.sfe_devices[evt->hw_idx];
+			res_id = sfe_res_id;
+		} else {
+			continue;
 		}
 
-		hw_intf_data = g_ife_hw_mgr.ife_devices[hw_idx];
-		if (!hw_intf_data->hw_intf) {
-			CAM_ERR(CAM_ISP, "hw_intf is null");
+		if (res_id < 0)
+			continue;
+
+		if (!hw_if) {
+			CAM_ERR_RATE_LIMIT(CAM_ISP, "hw_intf is null");
 			return -EINVAL;
 		}
 
-		hw_intf = hw_intf_data->hw_intf;
-		if (hw_intf->hw_ops.process_cmd) {
-			hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
-				CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE,
-				(void *)&dummy_args, sizeof(uint8_t));
-		}
-		break;
-	default:
-		CAM_ERR(CAM_ISP, "Unsupported HW Type: %u", hw_type);
+		if (hw_if->hw_ops.process_cmd)
+			hw_if->hw_ops.process_cmd(hw_if->hw_priv,
+				CAM_ISP_HW_NOTIFY_OVERFLOW,
+				&res_id, sizeof(int));
 	}
 
 	return 0;
@@ -10255,35 +10293,45 @@ end:
 }
 
 static int cam_ife_hw_mgr_handle_csid_error(
-	struct   cam_isp_hw_event_info *event_info)
+	struct   cam_isp_hw_event_info *event_info,
+	void                           *ctx)
 {
-	int rc = 0;
-	struct cam_isp_hw_error_event_data error_event_data = {0};
+	int                                      rc = -EINVAL;
+	struct cam_isp_hw_error_event_data       error_event_data = {0};
 	struct cam_ife_hw_event_recovery_data    recovery_data = {0};
 
+	CAM_DBG(CAM_ISP, "Entry CSID[%u] error %d", event_info->hw_idx,
+		event_info->err_type);
+
 	if ((event_info->err_type & CAM_ISP_HW_ERROR_CSID_FATAL) &&
 		g_ife_hw_mgr.debug_cfg.enable_csid_recovery) {
 
-		error_event_data.error_type = event_info->err_type;
-		cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
+		error_event_data.error_type = CAM_ISP_HW_ERROR_CSID_FATAL;
+		rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
 			event_info->hw_idx, &recovery_data);
+		goto end;
 	}
 
-	if (event_info->err_type & CAM_ISP_HW_ERROR_CSID_OVERFLOW) {
-		if (cam_ife_hw_mgr_dump_hw_src_clock(event_info->hw_idx,
-			CAM_ISP_HW_TYPE_VFE))
-			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"VFE%d src_clk_rate dump failed");
-	}
+	if (event_info->err_type & (CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW |
+		CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW |
+		CAM_ISP_HW_ERROR_CSID_FRAME_SIZE)) {
 
-	if (event_info->err_type & ~(CAM_ISP_HW_ERROR_CSID_FATAL |
-		CAM_ISP_HW_ERROR_CSID_OVERFLOW)) {
-		CAM_ERR(CAM_ISP, "Invalid event ID 0x%x",
-			event_info->err_type);
-		rc = -EINVAL;
+		cam_ife_hw_mgr_notify_overflow(event_info, ctx);
+		error_event_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
+		rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
+			event_info->hw_idx, &recovery_data);
 	}
+end:
 
-	return rc;
+	if (rc || !recovery_data.no_of_context)
+		return 0;
+
+	recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
+	cam_ife_hw_mgr_do_error_recovery(&recovery_data);
+	CAM_DBG(CAM_ISP, "Exit CSID[%u] error %d", event_info->hw_idx,
+		event_info->err_type);
+
+	return 0;
 }
 
 static int cam_ife_hw_mgr_handle_csid_rup(
@@ -10346,13 +10394,13 @@ static int cam_ife_hw_mgr_handle_csid_event(
 	struct    cam_isp_hw_event_info *event_info,
 	uint32_t                         evt_id)
 {
-	int rc = 0;
+	int                        rc = 0;
 
 	CAM_DBG(CAM_ISP, "CSID event %u", evt_id);
 
 	switch (evt_id) {
 	case CAM_ISP_HW_EVENT_ERROR:
-		rc = cam_ife_hw_mgr_handle_csid_error(event_info);
+		rc = cam_ife_hw_mgr_handle_csid_error(event_info, ctx);
 		break;
 	default:
 		CAM_ERR(CAM_ISP, "Invalid event ID %d",
@@ -10457,8 +10505,7 @@ static int cam_ife_hw_mgr_handle_hw_err(
 
 	spin_lock(&g_ife_hw_mgr.ctx_lock);
 
-	if (event_info->err_type & (CAM_ISP_HW_ERROR_CSID_FATAL |
-					CAM_ISP_HW_ERROR_CSID_OVERFLOW)) {
+	if (event_info->hw_type == CAM_ISP_HW_TYPE_CSID) {
 		rc = cam_ife_hw_mgr_handle_csid_event(ctx, event_info,
 			evt_id);
 		goto end;
@@ -10493,8 +10540,6 @@ static int cam_ife_hw_mgr_handle_hw_err(
 
 	rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
 		core_idx, &recovery_data);
-	if ((rc != 0) || !(recovery_data.no_of_context))
-		goto end;
 
 	if (rc || !recovery_data.no_of_context)
 		goto end;

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

@@ -69,7 +69,9 @@ enum cam_isp_hw_err_type {
 	CAM_ISP_HW_ERROR_VIOLATION = 0x0008,
 	CAM_ISP_HW_ERROR_BUSIF_OVERFLOW = 0x0010,
 	CAM_ISP_HW_ERROR_CSID_FATAL = 0x0020,
-	CAM_ISP_HW_ERROR_CSID_OVERFLOW = 0x0040,
+	CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW = 0x0040,
+	CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW = 0x0080,
+	CAM_ISP_HW_ERROR_CSID_FRAME_SIZE = 0x0100,
 };
 
 /**

+ 10 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h

@@ -82,8 +82,8 @@ static struct cam_ife_csid_ver1_path_reg_info
 	.crop_h_en_shift_val              = 5,
 	.timestamp_en_shift_val           = 1,
 	.format_measure_en_shift_val      = 0,
-	.fatal_err_mask                   = 0x4,
-	.non_fatal_err_mask               = 0x2e000,
+	.fatal_err_mask                   = 0x26004,
+	.non_fatal_err_mask               = 0xe000,
 };
 
 static struct cam_ife_csid_ver1_path_reg_info
@@ -149,8 +149,8 @@ static struct cam_ife_csid_ver1_path_reg_info
 	.overflow_ctrl_mode_val           = 0x8,
 	.timestamp_en_shift_val           = 1,
 	.format_measure_en_shift_val      = 0,
-	.fatal_err_mask                   = 0x4,
-	.non_fatal_err_mask               = 0x2e000,
+	.fatal_err_mask                   = 0x26004,
+	.non_fatal_err_mask               = 0xe000,
 };
 
 static struct cam_ife_csid_ver1_path_reg_info
@@ -217,8 +217,8 @@ static struct cam_ife_csid_ver1_path_reg_info
 	.mipi_pack_supported              = 1,
 	.timestamp_en_shift_val           = 2,
 	.format_measure_en_shift_val      = 1,
-	.fatal_err_mask                   = 0x4,
-	.non_fatal_err_mask               = 0x2e000,
+	.fatal_err_mask                   = 0x26004,
+	.non_fatal_err_mask               = 0xe000,
 };
 
 static struct cam_ife_csid_ver1_path_reg_info
@@ -285,8 +285,8 @@ static struct cam_ife_csid_ver1_path_reg_info
 	.mipi_pack_supported             = 1,
 	.timestamp_en_shift_val          = 2,
 	.format_measure_en_shift_val     = 1,
-	.fatal_err_mask                  = 0x4,
-	.non_fatal_err_mask              = 0x2e000,
+	.fatal_err_mask                  = 0x26004,
+	.non_fatal_err_mask              = 0xe000,
 };
 
 static struct cam_ife_csid_ver1_path_reg_info
@@ -354,8 +354,8 @@ static struct cam_ife_csid_ver1_path_reg_info
 	.mipi_pack_supported             = 1,
 	.timestamp_en_shift_val          = 2,
 	.format_measure_en_shift_val     = 1,
-	.fatal_err_mask                  = 0x4,
-	.non_fatal_err_mask              = 0x2e000,
+	.fatal_err_mask                  = 0x26004,
+	.non_fatal_err_mask              = 0xe000,
 };
 
 static struct cam_ife_csid_csi2_rx_reg_info

+ 0 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid580.h

@@ -12,7 +12,6 @@
 #include "cam_ife_csid_common.h"
 #include "cam_ife_csid_hw_ver1.h"
 
-
 /* Settings for 580 CSID are leveraged from 480 */
 static struct cam_ife_csid_ver1_reg_info cam_ife_csid_580_reg_info = {
 	.cmn_reg          = &cam_ife_csid_480_cmn_reg_info,

+ 18 - 14
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid680.h

@@ -200,8 +200,8 @@ static struct cam_ife_csid_ver2_pxl_reg_info
 		.stripe_loc_shift_val             = 20,
 		.lut_bank_0_sel_val               = 0,
 		.lut_bank_1_sel_val               = 1,
-		.fatal_err_mask                   = 0x4,
-		.non_fatal_err_mask               = 0x10080000,
+		.fatal_err_mask                   = 0x186004,
+		.non_fatal_err_mask               = 0x10000000,
 		.camif_irq_mask                   = 0x800000,
 		.rup_aup_mask                     = 0x10001,
 };
@@ -296,8 +296,8 @@ static struct cam_ife_csid_ver2_pxl_reg_info
 		.start_master_sel_shift_val       = 4,
 		.lut_bank_0_sel_val               = 0,
 		.lut_bank_1_sel_val               = 1,
-		.fatal_err_mask                   = 0x4,
-		.non_fatal_err_mask               = 0x10080000,
+		.fatal_err_mask                   = 0x186004,
+		.non_fatal_err_mask               = 0x10000000,
 		.rup_aup_mask                     = 0x40004,
 };
 
@@ -388,8 +388,8 @@ static struct cam_ife_csid_ver2_rdi_reg_info
 		.pix_pattern_shift_val            = 24,
 		.stripe_loc_shift_val             = 20,
 		.ccif_violation_en                = 1,
-		.fatal_err_mask                   = 0x4,
-		.non_fatal_err_mask               = 0x10080000,
+		.fatal_err_mask                   = 0x186004,
+		.non_fatal_err_mask               = 0x10000000,
 		.camif_irq_mask                   = 0x800000,
 		.rup_aup_mask                     = 0x100010,
 };
@@ -481,8 +481,8 @@ static struct cam_ife_csid_ver2_rdi_reg_info
 		.pix_pattern_shift_val            = 24,
 		.stripe_loc_shift_val             = 20,
 		.ccif_violation_en                = 1,
-		.fatal_err_mask                   = 0x4,
-		.non_fatal_err_mask               = 0x10080000,
+		.fatal_err_mask                   = 0x186004,
+		.non_fatal_err_mask               = 0x10000000,
 		.camif_irq_mask                   = 0x800000,
 		.rup_aup_mask                     = 0x200020,
 };
@@ -574,8 +574,8 @@ static struct cam_ife_csid_ver2_rdi_reg_info
 		.pix_pattern_shift_val            = 24,
 		.stripe_loc_shift_val             = 20,
 		.ccif_violation_en                = 1,
-		.fatal_err_mask                   = 0x4,
-		.non_fatal_err_mask               = 0x10080000,
+		.fatal_err_mask                   = 0x186004,
+		.non_fatal_err_mask               = 0x10000000,
 		.camif_irq_mask                   = 0x800000,
 		.rup_aup_mask                     = 0x400040,
 };
@@ -667,8 +667,8 @@ static struct cam_ife_csid_ver2_rdi_reg_info
 		.pix_pattern_shift_val            = 24,
 		.stripe_loc_shift_val             = 20,
 		.ccif_violation_en                = 1,
-		.fatal_err_mask                   = 0x4,
-		.non_fatal_err_mask               = 0x10080000,
+		.fatal_err_mask                   = 0x186004,
+		.non_fatal_err_mask               = 0x10000000,
 		.camif_irq_mask                   = 0x800000,
 		.rup_aup_mask                     = 0x800080,
 };
@@ -760,8 +760,8 @@ static struct cam_ife_csid_ver2_rdi_reg_info
 		.pix_pattern_shift_val           = 24,
 		.stripe_loc_shift_val            = 20,
 		.ccif_violation_en               = 1,
-		.fatal_err_mask                  = 0x4,
-		.non_fatal_err_mask              = 0x10080000,
+		.fatal_err_mask                  = 0x186004,
+		.non_fatal_err_mask              = 0x10000000,
 		.camif_irq_mask                  = 0x800000,
 		.rup_aup_mask                    = 0x1000100,
 };
@@ -910,6 +910,10 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.rup_supported                           = 1,
 	.only_master_rup                         = 1,
 	.need_separate_base                      = 1,
+	.format_measure_height_mask_val          = 0xFFFF,
+	.format_measure_height_shift_val         = 0x10,
+	.format_measure_width_mask_val           = 0xFFFF,
+	.format_measure_width_shift_val          = 0x0,
 };
 
 static struct cam_ife_csid_ver2_top_reg_info

+ 4 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c

@@ -3857,15 +3857,15 @@ static int cam_ife_csid_ver1_handle_event_err(
 {
 	struct cam_isp_hw_event_info event_info;
 	int rc = 0;
-	int dummy = 0;
 
 	event_info.hw_idx = evt_payload->hw_idx;
 	event_info.err_type = err_type;
+	event_info.hw_type = CAM_ISP_HW_TYPE_CSID;
 
 	CAM_DBG(CAM_ISP, "CSID[%d] Error type %d",
 		csid_hw->hw_intf->hw_idx, err_type);
 
-	rc = csid_hw->event_cb((void *)&dummy,
+	rc = csid_hw->event_cb(csid_hw->token,
 		CAM_ISP_HW_EVENT_ERROR, (void *)&event_info);
 
 	return rc;
@@ -3978,7 +3978,7 @@ static int cam_ife_csid_ver1_rx_bottom_half_handler(
 				soc_info->applied_src_clk_rate);
 
 		if (irq_status & IFE_CSID_VER1_RX_TG_FIFO_OVERFLOW) {
-			event_type |= CAM_ISP_HW_ERROR_CSID_OVERFLOW;
+			event_type |= CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW;
 			len += scnprintf(log_buf + len,
 				CAM_IFE_CSID_LOG_BUF_LEN - len,
 				"RX_ERROR_TPG_FIFO_OVERFLOW: Backpressure from IFE\n");
@@ -4111,7 +4111,7 @@ static int cam_ife_csid_ver1_path_bottom_half_handler(
 	if (evt_payload->irq_status[index] &
 		IFE_CSID_VER1_PATH_ERROR_FIFO_OVERFLOW)
 		cam_ife_csid_ver1_handle_event_err(csid_hw,
-			evt_payload, CAM_ISP_HW_ERROR_CSID_OVERFLOW);
+			evt_payload, CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW);
 
 	return 0;
 }

+ 204 - 53
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -190,10 +190,10 @@ static const struct cam_ife_csid_irq_desc ver2_path_irq_desc[] = {
 		.desc = "FRAME_DROP",
 	},
 	{
-		.desc = "OVERFLOW_RECOVERY",
+		.desc = "OVERFLOW_RECOVERY: Back pressure/output fifo ovrfl",
 	},
 	{
-		.desc = "ERROR_REC_CCIF_VIOLATION",
+		.desc = "ERROR_REC_CCIF_VIOLATION From Camif",
 	},
 	{
 		.desc = "CAMIF_EPOCH0",
@@ -220,7 +220,7 @@ static const struct cam_ife_csid_irq_desc ver2_path_irq_desc[] = {
 		.desc = "SENSOR_SWITCH_OUT_OF_SYNC_FRAME_DROP",
 	},
 	{
-		.desc = "CCIF_VIOLATION",
+		.desc = "CCIF_VIOLATION: Bad frame timings",
 	},
 };
 
@@ -503,15 +503,16 @@ static int cam_ife_csid_ver2_rx_err_top_half(
 	struct cam_ife_csid_ver2_evt_payload            *evt_payload;
 	const struct cam_ife_csid_csi2_rx_reg_info      *csi2_reg;
 
+	if (!csid_hw) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "No private returned");
+		return -ENODEV;
+	}
+
 	csid_hw = th_payload->handler_priv;
 	csid_reg = (struct cam_ife_csid_ver2_reg_info *)
 				csid_hw->core_info->csid_reg;
 	csi2_reg = csid_reg->csi2_reg;
 
-	if (!csid_hw) {
-		CAM_ERR_RATE_LIMIT(CAM_ISP, "No private returned");
-		return -ENODEV;
-	}
 
 	if (csid_hw->flags.fatal_err_detected) {
 		CAM_INFO_RATE_LIMIT(CAM_ISP,
@@ -735,6 +736,7 @@ static int cam_ife_csid_ver2_rx_err_bottom_half(
 
 	log_buf = csid_hw->log_buf;
 	memset(log_buf, 0, sizeof(csid_hw->log_buf));
+
 	csid_reg = (struct cam_ife_csid_ver2_reg_info *)
 			csid_hw->core_info->csid_reg;
 	csi2_reg = csid_reg->csi2_reg;
@@ -854,45 +856,73 @@ static int cam_ife_csid_ver2_rx_err_bottom_half(
 	return 0;
 }
 
+static int cam_ife_csid_ver2_handle_event_err(
+	struct cam_ife_csid_ver2_hw  *csid_hw,
+	uint32_t                      irq_status,
+	uint32_t                      err_type)
+{
+	struct cam_isp_hw_event_info      evt = {0};
+
+	if (!csid_hw->event_cb) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%u] event cb not registered",
+			csid_hw->hw_intf->hw_idx );
+		return 0;
+	}
+
+	evt.hw_idx   = csid_hw->hw_intf->hw_idx;
+	evt.reg_val  = irq_status;
+	evt.hw_type  = CAM_ISP_HW_TYPE_CSID;
+	evt.err_type = err_type;
+
+	csid_hw->event_cb(csid_hw->token,
+		CAM_ISP_HW_EVENT_ERROR, (void *)&evt);
+
+	return 0;
+}
+
 static int cam_ife_csid_ver2_parse_path_irq_status(
 	struct cam_ife_csid_ver2_hw *csid_hw,
 	uint32_t                     index,
 	uint32_t                     err_mask,
 	uint32_t                     irq_status)
 {
-	const uint8_t                        **irq_reg_tag;
-	uint32_t                               bit_pos = 0;
-	uint32_t                               temp_status;
-	uint32_t                               sof_irq_debug_en = 0;
-
-	irq_reg_tag = cam_ife_csid_get_irq_reg_tag_ptr();
-	temp_status = irq_status & err_mask;
+	const uint8_t                  **irq_reg_tag;
+	uint32_t                         bit_pos = 0;
+	uint32_t                         status;
+	uint32_t                         sof_irq_debug_en = 0;
+	uint32_t                         len = 0;
+	uint8_t                         *log_buf = NULL;
 
-	while (temp_status) {
+	log_buf = csid_hw->log_buf;
+	memset(log_buf, 0, sizeof(csid_hw->log_buf));
 
-		if (temp_status & 0x1)
-			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"CSID[%d] IRQ %s %s ",
-				csid_hw->hw_intf->hw_idx, irq_reg_tag[index],
-				ver2_path_irq_desc[bit_pos].desc);
+	irq_reg_tag = cam_ife_csid_get_irq_reg_tag_ptr();
 
+	status = irq_status & err_mask;
+	while (status) {
+		if (status & 0x1 )
+			len += scnprintf(log_buf + len, CAM_IFE_CSID_LOG_BUF_LEN - len,
+			"\n%s", ver2_path_irq_desc[bit_pos].desc);
 		bit_pos++;
-		temp_status >>= 1;
+		status >>= 1;
 	}
 
-	temp_status = irq_status & csid_hw->debug_info.path_mask;
-	bit_pos = 0;
+	if (len)
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%d] %s status: 0x%x Errors:%s",
+			csid_hw->hw_intf->hw_idx, irq_reg_tag[index],
+			irq_status, log_buf);
 
-	while (temp_status) {
+	status = irq_status & csid_hw->debug_info.path_mask;
+	bit_pos = 0;
+	while (status) {
 
-		if (temp_status & 0x1)
-			CAM_INFO_RATE_LIMIT(CAM_ISP,
-				"CSID[%d] IRQ %s %s ",
+		if (status & 0x1)
+			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID[%d] IRQ %s %s ",
 				csid_hw->hw_intf->hw_idx, irq_reg_tag[index],
 				ver2_path_irq_desc[bit_pos].desc);
 
 		bit_pos++;
-		temp_status >>= 1;
+		status >>= 1;
 	}
 
 	if (csid_hw->flags.sof_irq_triggered) {
@@ -919,8 +949,13 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
 	struct cam_ife_csid_ver2_reg_info         *csid_reg;
 	struct cam_ife_csid_ver2_hw               *csid_hw = NULL;
 	struct cam_isp_hw_event_info               evt_info;
+	struct cam_hw_soc_info                    *soc_info;
 	uint32_t                                   irq_status_ipp;
 	uint32_t                                   err_mask;
+	uint32_t                                   err_type = 0;
+	uint32_t                                   expected_frame = 0;
+	uint32_t                                   actual_frame = 0;
+	void    __iomem                           *base;
 	char                                       tag[15];
 	int                                        irq_idx;
 
@@ -932,6 +967,8 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
 	payload = evt_payload_priv;
 	csid_hw = handler_priv;
 	csid_reg = csid_hw->core_info->csid_reg;
+	soc_info = &csid_hw->hw_info->soc_info;
+	base  = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
 
 	irq_idx = cam_ife_csid_get_rt_irq_idx(
 			CAM_IFE_CSID_IRQ_REG_IPP,
@@ -981,6 +1018,37 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
 		CAM_IFE_CSID_IRQ_REG_IPP,
 		err_mask, irq_status_ipp);
 
+	if (irq_status_ipp & IFE_CSID_VER2_PATH_RECOVERY_OVERFLOW)
+		err_type |= CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW;
+
+	if (irq_status_ipp & (IFE_CSID_VER2_PATH_ERROR_PIX_COUNT |
+		IFE_CSID_VER2_PATH_ERROR_LINE_COUNT)) {
+
+		expected_frame = cam_io_r_mb(base +
+				csid_reg->ipp_reg->format_measure0_addr);
+		actual_frame = cam_io_r_mb(base +
+				csid_reg->ipp_reg->format_measure_cfg1_addr);
+
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%d] IPP Frame Size Error Expected[h: %u w: %u] Actual[h: %u w: %u]",
+			csid_hw->hw_intf->hw_idx,
+			((expected_frame >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			expected_frame &
+			csid_reg->cmn_reg->format_measure_width_mask_val,
+			((actual_frame >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			actual_frame &
+			csid_reg->cmn_reg->format_measure_width_mask_val);
+		err_type |= CAM_ISP_HW_ERROR_CSID_FRAME_SIZE;
+	}
+
+	if (err_type)
+		cam_ife_csid_ver2_handle_event_err(csid_hw,
+			irq_status_ipp,
+			err_type);
+
 	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
 			&csid_hw->path_free_payload_list,
 			&csid_hw->path_payload_lock);
@@ -995,8 +1063,13 @@ static int cam_ife_csid_ver2_ppp_bottom_half(
 	struct cam_ife_csid_ver2_evt_payload      *payload;
 	struct cam_ife_csid_ver2_reg_info         *csid_reg;
 	struct cam_ife_csid_ver2_hw               *csid_hw = NULL;
+	struct cam_hw_soc_info                    *soc_info;
+	void    __iomem                           *base;
 	uint32_t                                   irq_status_ppp;
 	uint32_t                                   err_mask;
+	uint32_t                                   err_type = 0;
+	uint32_t                                   expected_frame = 0;
+	uint32_t                                   actual_frame = 0;
 
 	if (!handler_priv || !evt_payload_priv) {
 		CAM_ERR(CAM_ISP, "Invalid params");
@@ -1005,6 +1078,8 @@ static int cam_ife_csid_ver2_ppp_bottom_half(
 
 	payload = evt_payload_priv;
 	csid_hw = handler_priv;
+	soc_info = &csid_hw->hw_info->soc_info;
+	base  = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
 
 	irq_status_ppp = payload->irq_reg_val[CAM_IFE_CSID_IRQ_REG_PPP];
 
@@ -1018,6 +1093,38 @@ static int cam_ife_csid_ver2_ppp_bottom_half(
 		csid_hw, CAM_IFE_CSID_IRQ_REG_PPP,
 		err_mask, irq_status_ppp);
 
+	if (irq_status_ppp & (IFE_CSID_VER2_PATH_ERROR_PIX_COUNT |
+		IFE_CSID_VER2_PATH_ERROR_LINE_COUNT)) {
+		soc_info = &csid_hw->hw_info->soc_info;
+
+		expected_frame = cam_io_r_mb(base +
+				csid_reg->ppp_reg->format_measure0_addr);
+		actual_frame = cam_io_r_mb(base +
+				csid_reg->ppp_reg->format_measure_cfg1_addr);
+
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%d] PPP Frame Size Error Expected[h: %u w: %u] Actual[h: %u w: %u]",
+			csid_hw->hw_intf->hw_idx,
+			((expected_frame >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			expected_frame &
+			csid_reg->cmn_reg->format_measure_width_mask_val,
+			((actual_frame >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			actual_frame &
+			csid_reg->cmn_reg->format_measure_width_mask_val);
+		err_type |= CAM_ISP_HW_ERROR_CSID_FRAME_SIZE;
+	}
+
+	if (irq_status_ppp & IFE_CSID_VER2_PATH_RECOVERY_OVERFLOW)
+		err_type |= CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW;
+
+	if (err_type)
+		cam_ife_csid_ver2_handle_event_err(csid_hw,
+			irq_status_ppp,
+			err_type);
+
 	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
 			&csid_hw->path_free_payload_list,
 			&csid_hw->path_payload_lock);
@@ -1034,9 +1141,14 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
 	struct cam_ife_csid_ver2_reg_info           *csid_reg;
 	struct cam_ife_csid_ver2_path_cfg           *path_cfg;
 	const struct cam_ife_csid_ver2_rdi_reg_info *rdi_reg;
+	struct cam_hw_soc_info                      *soc_info;
 	struct cam_isp_resource_node                *res;
+	void    __iomem                             *base;
 	uint32_t                                     irq_status_rdi, i;
 	uint32_t                                     err_mask, rdi_idx;
+	uint32_t                                     err_type = 0;
+	uint32_t                                     expected_frame = 0;
+	uint32_t                                     actual_frame = 0;
 	struct cam_isp_hw_event_info                 evt_info;
 
 	if (!handler_priv || !evt_payload_priv) {
@@ -1052,6 +1164,8 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
 
 	csid_reg = (struct cam_ife_csid_ver2_reg_info *)
 			csid_hw->core_info->csid_reg;
+	soc_info = &csid_hw->hw_info->soc_info;
+	base  = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
 
 	for (i = CAM_IFE_CSID_IRQ_REG_RDI_0;
 		i <= CAM_IFE_CSID_IRQ_REG_RDI_4; i++) {
@@ -1077,14 +1191,49 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
 
 		path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv;
 
-		if (!path_cfg->handle_camif_irq) {
-			err_mask = rdi_reg->non_fatal_err_mask |
-					rdi_reg->fatal_err_mask;
-			cam_ife_csid_ver2_parse_path_irq_status(csid_hw, i,
-				err_mask, irq_status_rdi);
-			continue;
+		err_mask = rdi_reg->non_fatal_err_mask |
+				rdi_reg->fatal_err_mask;
+		cam_ife_csid_ver2_parse_path_irq_status(csid_hw, i,
+			err_mask, irq_status_rdi);
+
+		if (irq_status_rdi & IFE_CSID_VER2_PATH_RECOVERY_OVERFLOW)
+			err_type |= CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW;
+
+		if (irq_status_rdi & (IFE_CSID_VER2_PATH_ERROR_PIX_COUNT |
+			IFE_CSID_VER2_PATH_ERROR_LINE_COUNT)) {
+			soc_info = &csid_hw->hw_info->soc_info;
+
+			expected_frame = cam_io_r_mb(base +
+					csid_reg->ppp_reg->format_measure0_addr);
+			actual_frame = cam_io_r_mb(base +
+					csid_reg->ppp_reg->format_measure_cfg1_addr);
+
+			CAM_ERR_RATE_LIMIT(CAM_ISP,
+				"CSID[%d] RDI%d Frame Size Error Expected[h: %u w: %u] Actual[h: %u w: %u]",
+				csid_hw->hw_intf->hw_idx, i,
+				((expected_frame >>
+				csid_reg->cmn_reg->format_measure_height_shift_val) &
+				csid_reg->cmn_reg->format_measure_height_mask_val),
+				expected_frame &
+				csid_reg->cmn_reg->format_measure_width_mask_val,
+				((actual_frame >>
+				csid_reg->cmn_reg->format_measure_height_shift_val) &
+				csid_reg->cmn_reg->format_measure_height_mask_val),
+				actual_frame &
+				csid_reg->cmn_reg->format_measure_width_mask_val);
+			err_type |= CAM_ISP_HW_ERROR_CSID_FRAME_SIZE;
+		}
+
+		if (err_type) {
+			cam_ife_csid_ver2_handle_event_err(csid_hw,
+				irq_status_rdi,
+				err_type);
+			break;
 		}
 
+		if (!path_cfg->handle_camif_irq)
+			continue;
+
 		evt_info.res_id = rdi_idx;
 		evt_info.reg_val = irq_status_rdi;
 
@@ -1095,26 +1244,26 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
 					(void *)&evt_info);
 		}
 
-		if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_SOF) {
-			if (csid_hw->event_cb)
-				csid_hw->event_cb(csid_hw->token,
-					CAM_ISP_HW_EVENT_SOF,
-					(void *)&evt_info);
+		if (!csid_hw->event_cb) {
+			CAM_DBG(CAM_ISP, "CSID[%u] no cb registered",
+				csid_hw->hw_intf->hw_idx);
+			break;
 		}
 
-		if (irq_status_rdi & IFE_CSID_VER2_PATH_RUP_DONE) {
-			if (csid_hw->event_cb)
-				csid_hw->event_cb(csid_hw->token,
-					CAM_ISP_HW_EVENT_REG_UPDATE,
-					(void *)&evt_info);
-		}
+		if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_SOF)
+			csid_hw->event_cb(csid_hw->token,
+				CAM_ISP_HW_EVENT_SOF,
+				(void *)&evt_info);
 
-		if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_EPOCH0) {
-			if (csid_hw->event_cb)
-				csid_hw->event_cb(csid_hw->token,
-					CAM_ISP_HW_EVENT_EPOCH,
-					(void *)&evt_info);
-		}
+		if (irq_status_rdi & IFE_CSID_VER2_PATH_RUP_DONE)
+			csid_hw->event_cb(csid_hw->token,
+				CAM_ISP_HW_EVENT_REG_UPDATE,
+				(void *)&evt_info);
+
+		if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_EPOCH0)
+			csid_hw->event_cb(csid_hw->token,
+				CAM_ISP_HW_EVENT_EPOCH,
+				(void *)&evt_info);
 
 	}
 
@@ -2473,9 +2622,11 @@ static int cam_ife_csid_ver2_start_ipp_path(
 
 	if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
 		 path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) {
-		val = cam_io_r_mb(mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr);
+		val = cam_io_r_mb(mem_base +
+			csid_reg->cmn_reg->rup_aup_cmd_addr);
 		val |= path_reg->rup_aup_mask;
-		cam_io_w_mb(val, mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr);
+		cam_io_w_mb(val, mem_base +
+			csid_reg->cmn_reg->rup_aup_cmd_addr);
 	}
 
 	res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h

@@ -57,7 +57,7 @@
 #define IFE_CSID_VER2_PATH_VCDT_GRP1_SEL                         BIT(16)
 #define IFE_CSID_VER2_PATH_VCDT_GRP_CHANGE                       BIT(17)
 #define IFE_CSID_VER2_PATH_FRAME_DROP                            BIT(18)
-#define IFE_CSID_VER2_PATH_OVERFLOW_RECOVERY                     BIT(19)
+#define IFE_CSID_VER2_PATH_RECOVERY_OVERFLOW                     BIT(19)
 #define IFE_CSID_VER2_PATH_ERROR_REC_CCIF_VIOLATION              BIT(20)
 #define IFE_CSID_VER2_PATH_CAMIF_EPOCH0                          BIT(21)
 #define IFE_CSID_VER2_PATH_CAMIF_EPOCH1                          BIT(22)
@@ -533,6 +533,10 @@ struct cam_ife_csid_ver2_common_reg_info {
 	uint32_t crop_pix_end_mask;
 	uint32_t crop_line_start_mask;
 	uint32_t crop_line_end_mask;
+	uint32_t format_measure_height_mask_val;
+	uint32_t format_measure_height_shift_val;
+	uint32_t format_measure_width_mask_val;
+	uint32_t format_measure_width_shift_val;
 	uint32_t measure_en_hbi_vbi_cnt_mask;
 	uint32_t measure_pixel_line_en_mask;
 	uint32_t ipp_irq_mask_all;

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -146,7 +146,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_CMD_CSID_MUP_UPDATE,
 	CAM_ISP_HW_CMD_BUF_UPDATE,
 	CAM_ISP_HW_CMD_BUF_UPDATE_RM,
-	CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE,
+	CAM_ISP_HW_NOTIFY_OVERFLOW,
 	CAM_ISP_HW_CMD_MAX,
 };
 
@@ -225,6 +225,7 @@ struct cam_isp_blanking_config {
  * @hw_idx:         IFE hw index
  * @err_type:       Error type if any
  * @reg_val:        Any critical register value captured during irq handling
+ * @hw_type:        Hw Type sending the event
  *
  */
 struct cam_isp_hw_event_info {
@@ -233,6 +234,7 @@ struct cam_isp_hw_event_info {
 	uint32_t                       hw_idx;
 	uint32_t                       err_type;
 	uint32_t                       reg_val;
+	uint32_t                       hw_type;
 };
 
 /*

+ 58 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe680.h

@@ -109,6 +109,60 @@ static struct cam_sfe_top_module_desc sfe_mod_desc[] = {
 	},
 };
 
+static struct cam_sfe_wr_client_desc sfe_wr_client_desc[] = {
+	{
+		.wm_id = 0,
+		.desc = "REMOSAIC",
+	},
+	{
+		.wm_id = 1,
+		.desc = "LCR",
+	},
+	{
+		.wm_id = 2,
+		.desc = "STATS_BE0",
+	},
+	{
+		.wm_id = 3,
+		.desc = "STATS_BHIST0",
+	},
+	{
+		.wm_id = 4,
+		.desc = "STATS_BE1",
+	},
+	{ .wm_id = 5,
+		.desc = "STATS_BHIST1",
+	},
+	{
+		.wm_id = 6,
+		.desc = "STATS_BE2",
+	},
+	{
+		.wm_id = 7,
+		.desc = "STATS_BHIST2",
+	},
+	{
+		.wm_id = 8,
+		.desc = "RDI_0",
+	},
+	{
+		.wm_id = 9,
+		.desc = "RDI_1",
+	},
+	{
+		.wm_id = 10,
+		.desc = "RDI_2",
+	},
+	{
+		.wm_id = 11,
+		.desc = "RDI_3",
+	},
+	{
+		.wm_id = 12,
+		.desc = "RDI_4",
+	},
+};
+
 static struct cam_sfe_top_common_reg_offset  sfe680_top_commong_reg  = {
 	.hw_version                    = 0x00000000,
 	.hw_capability                 = 0x00000004,
@@ -141,6 +195,7 @@ static struct cam_sfe_top_common_reg_offset  sfe680_top_commong_reg  = {
 	.lcr_throttle_cfg              = 0x000000BC,
 	.hdr_throttle_cfg              = 0x000000C0,
 	.sfe_op_throttle_cfg           = 0x000000C4,
+	.bus_overflow_status           = 0x00000868,
 };
 
 static struct cam_sfe_modules_common_reg_offset sfe680_modules_common_reg = {
@@ -200,8 +255,9 @@ static struct cam_sfe_top_hw_info sfe680_top_hw_info = {
 	.common_reg = &sfe680_top_commong_reg,
 	.modules_hw_info = &sfe680_modules_common_reg,
 	.common_reg_data = &sfe_680_top_common_reg_data,
-	.module_desc = sfe_mod_desc,
-	.pix_reg_data = &sfe_680_pix_reg_data,
+	.module_desc     =  sfe_mod_desc,
+	.wr_client_desc  =  sfe_wr_client_desc,
+	.pix_reg_data    = &sfe_680_pix_reg_data,
 	.rdi_reg_data[0] = &sfe_680_rdi0_reg_data,
 	.rdi_reg_data[1] = &sfe_680_rdi1_reg_data,
 	.rdi_reg_data[2] = &sfe_680_rdi2_reg_data,

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_core.c

@@ -322,6 +322,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_BW_UPDATE_V2:
 	case CAM_ISP_HW_CMD_BW_CONTROL:
 	case CAM_ISP_HW_CMD_CORE_CONFIG:
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
 		rc = core_info->sfe_top->hw_ops.process_cmd(
 			core_info->sfe_top->top_priv, cmd_type,
 			cmd_args, arg_size);

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

@@ -49,6 +49,7 @@ struct cam_sfe_top_priv {
 	uint32_t                        sensor_sel_diag_cfg;
 	spinlock_t                      spin_lock;
 	struct cam_sfe_top_module_desc *module_desc;
+	struct cam_sfe_wr_client_desc  *wr_client_desc;
 };
 
 struct cam_sfe_path_data {
@@ -90,6 +91,49 @@ static const char *cam_sfe_top_res_id_to_string(
 	}
 }
 
+static void cam_sfe_top_print_debug_reg_info(
+	struct cam_sfe_top_priv *top_priv)
+{
+	void __iomem                    *mem_base;
+	struct cam_sfe_top_common_data  *common_data;
+	struct cam_hw_soc_info          *soc_info;
+
+	common_data = &top_priv->common_data;
+	soc_info = common_data->soc_info;
+	mem_base = soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base;
+
+	CAM_INFO(CAM_SFE,
+		"Debug0: 0x%x Debug1: 0x%x Debug2: 0x%x Debug3: 0x%x",
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_0),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_1),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_2),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_3));
+	CAM_INFO(CAM_SFE,
+		"Debug4: 0x%x Debug5: 0x%x Debug6: 0x%x Debug7: 0x%x",
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_4),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_5),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_6),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_7));
+	CAM_INFO(CAM_SFE,
+		"Debug8: 0x%x Debug9: 0x%x Debug10: 0x%x Debug11: 0x%x",
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_8),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_9),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_10),
+		cam_io_r_mb(mem_base +
+			common_data->common_reg->top_debug_11));
+}
+
 static struct cam_axi_vote *cam_sfe_top_delay_bw_reduction(
 	struct cam_sfe_top_priv *top_priv,
 	uint64_t *to_be_applied_bw)
@@ -568,6 +612,38 @@ static int cam_sfe_set_top_debug(
 	return 0;
 }
 
+static int cam_sfe_top_handle_overflow(
+	struct cam_sfe_top_priv *top_priv, uint32_t cmd_type)
+{
+	struct cam_sfe_top_common_data      *common_data;
+	struct cam_hw_soc_info              *soc_info;
+	uint32_t                             status = 0;
+	uint32_t                             i = 0;
+
+	common_data = &top_priv->common_data;
+	soc_info = common_data->soc_info;
+
+	status  = cam_io_r(soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base +
+		    top_priv->common_data.common_reg->bus_overflow_status);
+
+	CAM_INFO_RATE_LIMIT(CAM_ISP,
+		"SFE%d src_clk_rate:%luHz overflow_status 0x%x",
+		soc_info->index, soc_info->applied_src_clk_rate,
+		status);
+
+	while (status) {
+		if (status & 0x1)
+			CAM_INFO_RATE_LIMIT(CAM_ISP, "SFE Overflow %s ",
+				top_priv->wr_client_desc[i].desc);
+		status = status >> 1;
+		i++;
+	}
+
+	cam_sfe_top_print_debug_reg_info(top_priv);
+
+	return 0;
+}
+
 int cam_sfe_top_process_cmd(void *priv, uint32_t cmd_type,
 	void *cmd_args, uint32_t arg_size)
 {
@@ -612,6 +688,9 @@ int cam_sfe_top_process_cmd(void *priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG:
 		rc = cam_sfe_set_top_debug(top_priv, cmd_args);
 		break;
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
+		rc = cam_sfe_top_handle_overflow(top_priv, cmd_type);
+		break;
 	default:
 		CAM_ERR(CAM_SFE, "Invalid cmd type: %d", cmd_type);
 		rc = -EINVAL;
@@ -751,48 +830,6 @@ static int cam_sfe_top_put_evt_payload(
 	return 0;
 }
 
-static void cam_sfe_top_print_debug_reg_info(
-	struct cam_sfe_top_priv *top_priv)
-{
-	void __iomem                    *mem_base;
-	struct cam_sfe_top_common_data  *common_data;
-	struct cam_hw_soc_info          *soc_info;
-
-	common_data = &top_priv->common_data;
-	soc_info = common_data->soc_info;
-	mem_base = soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base;
-
-	CAM_INFO(CAM_SFE,
-		"Debug0: 0x%x Debug1: 0x%x Debug2: 0x%x Debug3: 0x%x",
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_0),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_1),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_2),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_3));
-	CAM_INFO(CAM_SFE,
-		"Debug4: 0x%x Debug5: 0x%x Debug6: 0x%x Debug7: 0x%x",
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_4),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_5),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_6),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_7));
-	CAM_INFO(CAM_SFE,
-		"Debug8: 0x%x Debug9: 0x%x Debug10: 0x%x Debug11: 0x%x",
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_8),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_9),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_10),
-		cam_io_r_mb(mem_base +
-			common_data->common_reg->top_debug_11));
-}
 
 static int cam_sfe_top_handle_err_irq_top_half(
 	uint32_t evt_id,
@@ -1356,6 +1393,7 @@ int cam_sfe_top_init(
 	top_priv->common_data.common_reg =
 		sfe_top_hw_info->common_reg;
 	top_priv->module_desc = sfe_top_hw_info->module_desc;
+	top_priv->wr_client_desc = sfe_top_hw_info->wr_client_desc;
 	top_priv->sfe_debug_cfg = 0;
 
 	/* Remove after driver stabilizes */

+ 7 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.h

@@ -30,6 +30,11 @@ struct cam_sfe_top {
 	struct cam_hw_ops       hw_ops;
 };
 
+struct cam_sfe_wr_client_desc {
+	uint32_t  wm_id;
+	uint8_t  *desc;
+};
+
 struct cam_sfe_top_common_reg_offset {
 	uint32_t hw_version;
 	uint32_t hw_capability;
@@ -62,6 +67,7 @@ struct cam_sfe_top_common_reg_offset {
 	uint32_t lcr_throttle_cfg;
 	uint32_t hdr_throttle_cfg;
 	uint32_t sfe_op_throttle_cfg;
+	uint32_t bus_overflow_status;
 };
 
 struct cam_sfe_modules_common_reg_offset {
@@ -92,6 +98,7 @@ struct cam_sfe_top_hw_info {
 	struct cam_sfe_modules_common_reg_offset *modules_hw_info;
 	struct cam_sfe_top_common_reg_data       *common_reg_data;
 	struct cam_sfe_top_module_desc           *module_desc;
+	struct cam_sfe_wr_client_desc            *wr_client_desc;
 	struct cam_sfe_path_common_reg_data      *pix_reg_data;
 	struct cam_sfe_path_common_reg_data      *rdi_reg_data[CAM_SFE_RDI_MAX];
 	uint32_t                                  num_inputs;

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c

@@ -511,7 +511,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_ADD_WAIT:
 	case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER:
 	case CAM_ISP_HW_CMD_CAMIF_DATA:
-	case CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE:
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
 	case CAM_ISP_HW_CMD_BLANKING_UPDATE:
 		rc = core_info->vfe_top->hw_ops.process_cmd(
 			core_info->vfe_top->top_priv, cmd_type, cmd_args,

+ 153 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h

@@ -270,6 +270,156 @@ static struct cam_vfe_top_ver4_module_desc vfe680_pp_mod_desc[] = {
 	},
 };
 
+static struct cam_vfe_top_ver4_wr_client_desc vfe680_wr_client_desc[] = {
+	{
+		.wm_id = 0,
+		.desc = "VIDEO_FULL_Y",
+	},
+	{
+		.wm_id = 1,
+		.desc = "VIDEO_FULL_C",
+	},
+	{
+		.wm_id = 2,
+		.desc = "VIDEO_DS_4:1",
+	},
+	{
+		.wm_id = 3,
+		.desc = "VIDEO_DS_16:1",
+	},
+	{
+		.wm_id = 4,
+		.desc = "DISPLAY_FULL_Y",
+	},
+	{
+		.wm_id = 5,
+		.desc = "DISPLAY_FULL_C",
+	},
+	{
+		.wm_id = 6,
+		.desc = "DISPLAY_DS_4:1",
+	},
+	{
+		.wm_id = 7,
+		.desc = "DISPLAY_DS_16:1",
+	},
+	{
+		.wm_id = 8,
+		.desc = "FD_Y",
+	},
+	{
+		.wm_id = 9,
+		.desc = "FD_C",
+	},
+	{
+		.wm_id = 10,
+		.desc = "PIXEL_RAW",
+	},
+	{
+		.wm_id = 11,
+		.desc = "STATS_BE0",
+	},
+	{
+		.wm_id = 12,
+		.desc = "STATS_BHIST0",
+	},
+	{
+		.wm_id = 13,
+		.desc = "STATS_TINTLESS_BG",
+	},
+	{
+		.wm_id = 14,
+		.desc = "STATS_AWB_BG",
+	},
+	{
+		.wm_id = 15,
+		.desc = "STATS_AWB_BFW",
+	},
+	{
+		.wm_id = 16,
+		.desc = "STATS_BAF",
+	},
+	{
+		.wm_id = 17,
+		.desc = "STATS_BHIST",
+	},
+	{
+		.wm_id = 18,
+		.desc = "STATS_RS",
+	},
+	{
+		.wm_id = 19,
+		.desc = "STATS_IHIST",
+	},
+	{
+		.wm_id = 20,
+		.desc = "SPARSE_PD",
+	},
+	{
+		.wm_id = 21,
+		.desc = "PDAF_V2.0_PD_DATA",
+	},
+	{
+		.wm_id = 22,
+		.desc = "PDAF_V2.0_SAD",
+	},
+	{
+		.wm_id = 23,
+		.desc = "LCR",
+	},
+	{
+		.wm_id = 24,
+		.desc = "RDI0",
+	},
+	{
+		.wm_id = 25,
+		.desc = "RDI1",
+	},
+	{
+		.wm_id = 26,
+		.desc = "RDI2",
+	},
+	{
+		.wm_id = 27,
+		.desc = "LTM_STATS",
+	},
+};
+
+static struct cam_vfe_top_camnoc_reg_data vfe680_camnoc_reg_data[] = {
+	{
+		.desc = "linear_stats",
+		.offset = 0x4020,
+	},
+	{
+		.desc = "lite",
+		.offset = 0x4620,
+	},
+	{
+		.desc = "pdaf",
+		.offset = 0x4c20,
+	},
+	{
+		.desc = "rdi",
+		.offset = 0x5220,
+	},
+	{
+		.desc = "ubwc",
+		.offset = 0x5820,
+	},
+	{
+		.desc = "linear_stats_1",
+		.offset = 0x8220,
+	},
+};
+
+struct cam_vfe_top_camnoc_debug_data vfe680_camnoc_debug_data = {
+	.pending_mask      = 0x7f0000,
+	.pending_shift     = 16,
+	.queued_mask       = 0x7ff,
+	.num_reg           = 6,
+	.camnoc_reg        = vfe680_camnoc_reg_data,
+};
+
 static struct cam_irq_register_set vfe680_top_irq_reg_set[3] = {
 	{
 		.mask_reg_offset   = 0x00000034,
@@ -415,7 +565,6 @@ static struct cam_vfe_top_ver4_hw_info vfe680_top_hw_info = {
 	.vfe_full_hw_info = {
 		.common_reg     = &vfe680_top_common_reg,
 		.reg_data       = &vfe_common_reg_data,
-		.module_desc    = vfe680_pp_mod_desc,
 	},
 	.pdlib_hw_info = {
 		.common_reg     = &vfe680_top_common_reg,
@@ -428,6 +577,9 @@ static struct cam_vfe_top_ver4_hw_info vfe680_top_hw_info = {
 		.common_reg     = &vfe680_top_common_reg,
 		.reg_data       = &vfe680_lcr_reg_data,
 	},
+	.wr_client_desc         = vfe680_wr_client_desc,
+	.module_desc            = vfe680_pp_mod_desc,
+	.camnoc_debug_data      = &vfe680_camnoc_debug_data,
 	.num_mux = 6,
 	.mux_type = {
 		CAM_VFE_CAMIF_VER_4_0,
@@ -437,7 +589,6 @@ static struct cam_vfe_top_ver4_hw_info vfe680_top_hw_info = {
 		CAM_VFE_PDLIB_VER_1_0,
 		CAM_VFE_LCR_VER_1_0,
 	},
-
 };
 
 static struct cam_irq_register_set vfe680_bus_irq_reg[2] = {

+ 65 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h

@@ -27,6 +27,68 @@ static struct cam_vfe_top_ver4_module_desc vfe68x_pp_mod_desc[] = {
 	},
 };
 
+static struct cam_vfe_top_ver4_wr_client_desc vfe680x_wr_client_desc[] = {
+	{
+		.wm_id = 0,
+		.desc = "RDI_0",
+	},
+	{
+		.wm_id = 1,
+		.desc = "RDI_1",
+	},
+	{
+		.wm_id = 2,
+		.desc = "RDI_2",
+	},
+	{
+		.wm_id = 3,
+		.desc = "RDI_3",
+	},
+	{
+		.wm_id = 4,
+		.desc = "GAMMA",
+	},
+	{
+		.wm_id = 5,
+		.desc = "BE",
+	},
+};
+
+static struct cam_vfe_top_camnoc_reg_data vfe680x_camnoc_reg_data[] = {
+	{
+		.desc = "linear_stats",
+		.offset = 0x4020,
+	},
+	{
+		.desc = "lite",
+		.offset = 0x4620,
+	},
+	{
+		.desc = "pdaf",
+		.offset = 0x4c20,
+	},
+	{
+		.desc = "rdi",
+		.offset = 0x5220,
+	},
+	{
+		.desc = "ubwc",
+		.offset = 0x5820,
+	},
+	{
+		.desc = "linear_stats_1",
+		.offset = 0x8220,
+	},
+};
+
+struct cam_vfe_top_camnoc_debug_data vfe680x_camnoc_debug_data = {
+	.pending_mask      = 0x7f0000,
+	.pending_shift     = 16,
+	.queued_mask       = 0x7ff,
+	.num_reg           = 6,
+	.camnoc_reg        = vfe680x_camnoc_reg_data,
+};
+
 static struct cam_irq_register_set vfe68x_top_irq_reg_set[3] = {
 	{
 		.mask_reg_offset   = 0x00001024,
@@ -142,8 +204,10 @@ static struct cam_vfe_top_ver4_hw_info vfe68x_top_hw_info = {
 	.vfe_full_hw_info = {
 		.common_reg     = &vfe68x_top_common_reg,
 		.reg_data       = &vfe68x_ipp_reg_data,
-		.module_desc    = vfe68x_pp_mod_desc,
 	},
+	.module_desc            = vfe68x_pp_mod_desc,
+	.wr_client_desc         = vfe680x_wr_client_desc,
+	.camnoc_debug_data      = &vfe680x_camnoc_debug_data,
 	.num_mux = 5,
 	.mux_type = {
 		CAM_VFE_CAMIF_VER_4_0,

+ 15 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE_TOP_COMMON_H_
@@ -31,6 +31,20 @@ struct cam_vfe_top_priv_common {
 	enum cam_vfe_bw_control_action  axi_vote_control[CAM_VFE_TOP_MUX_MAX];
 };
 
+
+struct cam_vfe_top_camnoc_reg_data {
+	uint8_t                              *desc;
+	uint32_t                              offset;
+};
+
+struct cam_vfe_top_camnoc_debug_data {
+	uint32_t                               pending_mask;
+	uint32_t                               pending_shift;
+	uint32_t                               queued_mask;
+	uint32_t                               num_reg;
+	struct cam_vfe_top_camnoc_reg_data    *camnoc_reg;
+};
+
 struct cam_vfe_top_reg_dump_entry {
 	uint32_t reg_dump_start;
 	uint32_t reg_dump_end;

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

@@ -180,7 +180,7 @@ static int cam_vfe_top_dump_info(
 	}
 
 	switch (cmd_type) {
-	case CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE:
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
 		CAM_INFO_RATE_LIMIT(CAM_ISP, "VFE%d src_clk_rate:%luHz",
 			soc_info->index, soc_info->applied_src_clk_rate);
 		break;
@@ -817,7 +817,7 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_vfe_top_clock_update(top_priv, cmd_args,
 			arg_size);
 		break;
-	case CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE:
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
 		rc = cam_vfe_top_dump_info(top_priv, cmd_type);
 		break;
 	case CAM_ISP_HW_CMD_FE_UPDATE_IN_RD:

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

@@ -201,7 +201,7 @@ static int cam_vfe_top_ver3_dump_info(
 	}
 
 	switch (cmd_type) {
-	case CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE:
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
 		CAM_INFO_RATE_LIMIT(CAM_ISP, "VFE%d src_clk_rate:%luHz",
 			soc_info->index, soc_info->applied_src_clk_rate);
 		break;
@@ -755,7 +755,7 @@ int cam_vfe_top_ver3_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_vfe_top_ver3_clock_update(top_priv, cmd_args,
 			arg_size);
 		break;
-	case CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE:
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
 		rc = cam_vfe_top_ver3_dump_info(top_priv, cmd_type);
 		break;
 	case CAM_ISP_HW_CMD_FE_UPDATE_IN_RD:

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

@@ -26,6 +26,23 @@
 #define CAM_VFE_CAMIF_IRQ_SOF_DEBUG_CNT_MAX   2
 #define CAM_VFE_LEN_LOG_BUF                   256
 
+struct cam_vfe_top_ver4_common_data {
+	struct cam_hw_soc_info                     *soc_info;
+	struct cam_hw_intf                         *hw_intf;
+	struct cam_vfe_top_ver4_reg_offset_common  *common_reg;
+	struct cam_vfe_top_ver4_hw_info            *hw_info;
+};
+
+struct cam_vfe_top_ver4_priv {
+	struct cam_vfe_top_ver4_common_data common_data;
+	unsigned long                       hw_clk_rate;
+	unsigned long                       req_clk_rate[
+						CAM_VFE_TOP_MUX_MAX];
+	struct cam_vfe_top_priv_common      top_common;
+	atomic_t                            overflow_pending;
+	uint8_t                             log_buf[CAM_VFE_LEN_LOG_BUF];
+};
+
 struct cam_vfe_mux_ver4_data {
 	void __iomem                                *mem_base;
 	struct cam_hw_soc_info                      *soc_info;
@@ -33,8 +50,7 @@ struct cam_vfe_mux_ver4_data {
 	struct cam_vfe_top_ver4_reg_offset_common   *common_reg;
 	struct cam_vfe_top_common_cfg                cam_common_cfg;
 	struct cam_vfe_ver4_path_reg_data           *reg_data;
-	struct cam_vfe_top_ver4_module_desc         *module_desc;
-	uint8_t                                      log_buf[CAM_VFE_LEN_LOG_BUF];
+	struct cam_vfe_top_ver4_priv                *top_priv;
 
 	cam_hw_mgr_event_cb_func             event_cb;
 	void                                *priv;
@@ -74,20 +90,6 @@ struct cam_vfe_mux_ver4_data {
 	struct timespec64                     error_ts;
 };
 
-struct cam_vfe_top_ver4_common_data {
-	struct cam_hw_soc_info                     *soc_info;
-	struct cam_hw_intf                         *hw_intf;
-	struct cam_vfe_top_ver4_reg_offset_common  *common_reg;
-};
-
-struct cam_vfe_top_ver4_priv {
-	struct cam_vfe_top_ver4_common_data common_data;
-	unsigned long                       hw_clk_rate;
-	unsigned long                       req_clk_rate[
-						CAM_VFE_TOP_MUX_MAX];
-	struct cam_vfe_top_priv_common      top_common;
-};
-
 static int cam_vfe_top_ver4_mux_get_base(struct cam_vfe_top_ver4_priv *top_priv,
 	void *cmd_args, uint32_t arg_size)
 {
@@ -248,26 +250,185 @@ static int cam_vfe_top_ver4_clock_update(
 	return rc;
 }
 
-static int cam_vfe_top_ver4_dump_info(
-	struct cam_vfe_top_ver4_priv *top_priv, uint32_t cmd_type)
+static void cam_vfe_top_ver4_print_debug_reg_status(
+	struct cam_vfe_top_ver4_priv *top_priv)
 {
-	struct cam_hw_soc_info *soc_info = top_priv->common_data.soc_info;
+	struct cam_vfe_top_ver4_reg_offset_common  *common_reg;
+	uint32_t                                    val = 0;
+	uint32_t                                    num_reg =  0;
+	uint32_t                                    i = 0, j, len = 0;
+	uint8_t                                    *log_buf;
+	struct cam_hw_soc_info                     *soc_info;
+	void __iomem                               *base;
 
-	if (!soc_info) {
-		CAM_ERR(CAM_ISP, "Null soc_info");
-		return -EINVAL;
+	soc_info   =  top_priv->common_data.soc_info;
+	common_reg =  top_priv->common_data.common_reg;
+	num_reg    =  common_reg->num_top_debug_reg;
+	base       =  soc_info->reg_map[VFE_CORE_BASE_IDX].mem_base;
+	log_buf    =  top_priv->log_buf;
+
+	while (i < num_reg) {
+		len += scnprintf(log_buf + len, CAM_VFE_LEN_LOG_BUF - len,
+				"VFE[%u]: Top Debug Status",
+				soc_info->index);
+		for(j = 0; j < 4 && i < num_reg; j++, i++) {
+			val = cam_io_r(base +
+				common_reg->top_debug[i]);
+			len += scnprintf(log_buf + len, CAM_VFE_LEN_LOG_BUF -
+				len, "\nstatus %2d : 0x%08x", i, val);
+		}
+		CAM_INFO(CAM_ISP, "%s", log_buf);
+		len = 0;
+		memset(log_buf, 0, sizeof(uint8_t)*CAM_VFE_LEN_LOG_BUF);
 	}
 
-	switch (cmd_type) {
-	case CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE:
-		CAM_INFO_RATE_LIMIT(CAM_ISP, "VFE%d src_clk_rate:%luHz",
-			soc_info->index, soc_info->applied_src_clk_rate);
-		break;
-	default:
-		CAM_ERR(CAM_ISP, "cmd_type: %u not supported", cmd_type);
-		break;
+	CAM_ERR(CAM_ISP, "VFE[%u] Bus overflow status 0x%x",
+		soc_info->index,
+		cam_io_r(base + common_reg->bus_overflow_status));
+
+	CAM_ERR(CAM_ISP, "VFE[%u] Bus  Violation status 0x%x",
+		soc_info->index,
+		cam_io_r(base + common_reg->bus_violation_status));
+}
+
+int cam_vfe_top_ver4_dump_timestamps(
+	struct cam_vfe_top_ver4_priv *top_priv,
+	int  res_id)
+{
+	uint32_t                           i;
+	struct cam_vfe_mux_ver4_data      *vfe_priv = NULL;
+	struct cam_isp_resource_node      *res = NULL;
+	struct cam_isp_resource_node      *camif_res = NULL;
+	struct timespec64                  ts;
+
+	for (i = 0; i < top_priv->top_common.num_mux; i++) {
+
+		res = &top_priv->top_common.mux_rsrc[i];
+
+		if (!res || !res->res_priv) {
+			CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid Resource");
+			return -EINVAL;
+		}
+
+		vfe_priv  = res->res_priv;
+
+		if (vfe_priv->is_pixel_path) {
+			camif_res = res;
+			if (res->res_id == res_id)
+				break;
+		} else {
+			if (res->rdi_only_ctx && res->res_id == res_id) {
+				break;
+			} else if (!res->rdi_only_ctx && camif_res) {
+				vfe_priv  = camif_res->res_priv;
+				break;
+			}
+		}
 	}
 
+	if (i ==  top_priv->top_common.num_mux || !vfe_priv) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "VFE[%u] invalid res_id %d",
+			top_priv->common_data.hw_intf->hw_idx, res_id);
+		return 0;
+	}
+
+	ktime_get_boottime_ts64(&ts);
+
+	CAM_INFO(CAM_ISP,
+		"VFE[%u] current monotonic time stamp seconds %lld:%lld",
+		vfe_priv->hw_intf->hw_idx, ts.tv_sec, ts.tv_nsec);
+
+	CAM_INFO(CAM_ISP,
+		"CAMIF Error time %lld:%lld SOF %lld:%lld EPOCH %lld:%lld EOF %lld:%lld",
+		vfe_priv->error_ts.tv_sec,
+		vfe_priv->error_ts.tv_nsec,
+		vfe_priv->sof_ts.tv_sec,
+		vfe_priv->sof_ts.tv_nsec,
+		vfe_priv->epoch_ts.tv_sec,
+		vfe_priv->epoch_ts.tv_nsec,
+		vfe_priv->eof_ts.tv_sec,
+		vfe_priv->eof_ts.tv_nsec);
+
+	return 0;
+}
+
+static void cam_vfe_top_ver4_print_camnoc_debug_info(
+	struct cam_vfe_top_ver4_priv *top_priv)
+{
+	struct cam_vfe_top_camnoc_debug_data *camnoc_debug = NULL;
+	struct cam_vfe_soc_private           *soc_private = NULL;
+	uint32_t                              i;
+	uint32_t                              val = 0;
+
+	camnoc_debug = top_priv->common_data.hw_info->camnoc_debug_data;
+
+	if (!camnoc_debug || !camnoc_debug->camnoc_reg) {
+		CAM_DBG(CAM_ISP, "No CAMNOC Info");
+		return;
+	}
+
+	soc_private = top_priv->common_data.soc_info->soc_private;
+
+	for (i = 0; i < camnoc_debug->num_reg; i++) {
+		cam_cpas_reg_read(soc_private->cpas_handle,
+			CAM_CPAS_REG_CAMNOC,
+			camnoc_debug->camnoc_reg[i].offset,
+			true, &val);
+		CAM_ERR(CAM_ISP, "CAMNOC Fill level: %s  pending %u queued %u",
+			camnoc_debug->camnoc_reg[i].desc,
+			((val & camnoc_debug->pending_mask) >>
+				camnoc_debug->pending_shift),
+			val & camnoc_debug->queued_mask);
+	}
+}
+
+static int cam_vfe_top_ver4_print_overflow_debug_info(
+	struct cam_vfe_top_ver4_priv *top_priv, void *cmd_args)
+{
+	struct cam_vfe_top_ver4_common_data *common_data;
+	struct cam_hw_soc_info              *soc_info;
+	uint32_t                             status = 0;
+	uint32_t                             i = 0;
+	int                                  res_id;
+
+	common_data = &top_priv->common_data;
+	soc_info = common_data->soc_info;
+
+	status  = cam_io_r(soc_info->reg_map[VFE_CORE_BASE_IDX].mem_base +
+		    common_data->common_reg->bus_overflow_status);
+
+	res_id = *((int *)(cmd_args));
+	CAM_ERR_RATE_LIMIT(CAM_ISP, "VFE[%d] src_clk_rate:%luHz res: %u overflow_status 0x%x",
+		soc_info->index, soc_info->applied_src_clk_rate,
+		res_id, status);
+
+	while (status) {
+		if (status & 0x1)
+			CAM_ERR_RATE_LIMIT(CAM_ISP, "VFE Bus Overflow %s",
+				common_data->hw_info->wr_client_desc[i].desc);
+		status = status >> 1;
+		i++;
+	}
+
+	cam_vfe_top_ver4_dump_timestamps(top_priv, res_id);
+	cam_vfe_top_ver4_print_camnoc_debug_info(top_priv);
+
+	status  = cam_io_r(soc_info->reg_map[VFE_CORE_BASE_IDX].mem_base +
+		    common_data->common_reg->bus_violation_status);
+	CAM_ERR_RATE_LIMIT(CAM_ISP, "VFE[%d] Bus violation_status 0x%x",
+		soc_info->index,  status);
+
+	i = 0;
+	while (status) {
+		if (status & 0x1)
+			CAM_INFO_RATE_LIMIT(CAM_ISP, "VFE Bus Violation %s",
+				common_data->hw_info->wr_client_desc[i].desc);
+		status = status >> 1;
+		i++;
+	}
+
+	cam_vfe_top_ver4_print_debug_reg_status(top_priv);
+
 	return 0;
 }
 
@@ -508,54 +669,29 @@ int cam_vfe_top_ver4_release(void *device_priv,
 	return 0;
 }
 
-static void cam_vfe_top_ver4_print_debug_reg_status(
-	struct cam_vfe_mux_ver4_data            *mux_data,
-	uint32_t                                *irq_status)
+static void cam_vfe_top_ver4_print_violation_info(
+	struct cam_vfe_top_ver4_priv *top_priv)
 {
-	uint32_t val, num_reg = mux_data->common_reg->num_top_debug_reg;
-	int i = 0, j, len = 0;
-	uint8_t *log_buf = mux_data->log_buf;
+	struct cam_hw_soc_info              *soc_info;
+	struct cam_vfe_top_ver4_common_data *common_data;
+	void __iomem                        *base;
+	uint32_t                             val = 0;
+
+	common_data = &top_priv->common_data;
+	soc_info    =  common_data->soc_info;
+	base        =  soc_info->reg_map[VFE_CORE_BASE_IDX].mem_base;
+	val         =  cam_io_r(base +
+			    common_data->common_reg->violation_status),
+
+	CAM_ERR(CAM_ISP, "VFE[%u] PP Violation status 0x%x",
+	     soc_info->index, val);
+
+	if (common_data->hw_info->module_desc)
+		CAM_ERR(CAM_ISP, "VFE[%u] PP Violation Module id: %u %s]",
+			soc_info->index,
+			common_data->hw_info->module_desc[val].id,
+			common_data->hw_info->module_desc[val].desc);
 
-	while (i < num_reg) {
-		len += scnprintf(log_buf + len, CAM_VFE_LEN_LOG_BUF - len,
-				"VFE[%u]: Top Debug Status",
-				mux_data->hw_intf->hw_idx);
-		for(j = 0; j < 4 && i < num_reg; j++, i++) {
-			val = cam_io_r(mux_data->mem_base +
-				mux_data->common_reg->top_debug[i]);
-			len += scnprintf(log_buf + len, CAM_VFE_LEN_LOG_BUF -
-				len, "\nstatus %2d : 0x%08x", i, val);
-		}
-		CAM_INFO(CAM_ISP, "%s", log_buf);
-		len = 0;
-		memset(log_buf, 0, sizeof(uint8_t)*CAM_VFE_LEN_LOG_BUF);
-	}
-
-	if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS0] &&
-		mux_data->reg_data->pp_violation_mask) {
-
-		val =  cam_io_r(mux_data->mem_base +
-				mux_data->common_reg->violation_status),
-
-		CAM_ERR(CAM_ISP, "VFE[%u] PP Violation status 0x%x",
-		     mux_data->hw_intf->hw_idx, val);
-
-		if (mux_data->module_desc)
-			CAM_ERR(CAM_ISP, "VFE[%u] PP Violation Module[%u] %s",
-				mux_data->hw_intf->hw_idx,
-				mux_data->module_desc[val].id,
-				mux_data->module_desc[val].desc);
-	}
-
-	CAM_ERR(CAM_ISP, "VFE[%u] Bus overflow status 0x%x",
-		mux_data->hw_intf->hw_idx,
-		cam_io_r(mux_data->mem_base +
-			mux_data->common_reg->bus_overflow_status));
-
-	CAM_ERR(CAM_ISP, "VFE[%u] Bus  Violation status 0x%x",
-		mux_data->hw_intf->hw_idx,
-		cam_io_r(mux_data->mem_base +
-			mux_data->common_reg->bus_violation_status));
 }
 
 int cam_vfe_top_ver4_start(void *device_priv,
@@ -612,6 +748,7 @@ int cam_vfe_top_ver4_start(void *device_priv,
 		rc = -EPERM;
 	}
 
+	atomic_set(&top_priv->overflow_pending, 0);
 	return rc;
 }
 
@@ -653,6 +790,7 @@ int cam_vfe_top_ver4_stop(void *device_priv,
 		}
 	}
 
+	atomic_set(&top_priv->overflow_pending, 0);
 	return rc;
 }
 
@@ -706,8 +844,10 @@ int cam_vfe_top_ver4_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_vfe_top_ver4_clock_update(top_priv, cmd_args,
 			arg_size);
 		break;
-	case CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE:
-		rc = cam_vfe_top_ver4_dump_info(top_priv, cmd_type);
+	case CAM_ISP_HW_NOTIFY_OVERFLOW:
+		atomic_set(&top_priv->overflow_pending, 1);
+		rc = cam_vfe_top_ver4_print_overflow_debug_info(top_priv,
+			cmd_args);
 		break;
 	case CAM_ISP_HW_CMD_FE_UPDATE_IN_RD:
 		rc = cam_vfe_top_fs_update(top_priv, cmd_args,
@@ -865,6 +1005,14 @@ static int cam_vfe_handle_irq_bottom_half(void *handler_priv,
 	vfe_priv = vfe_res->res_priv;
 	payload = evt_payload_priv;
 
+	if (atomic_read(&vfe_priv->top_priv->overflow_pending)) {
+		CAM_INFO(CAM_ISP,
+			"VFE:%d Handling overflow, Ignore bottom half",
+			vfe_res->hw_intf->hw_idx);
+		cam_vfe_top_put_evt_payload(vfe_priv, &payload);
+		return IRQ_HANDLED;
+	}
+
 	for (i = 0; i < CAM_IFE_IRQ_REGISTERS_MAX; i++)
 		irq_status[i] = payload->irq_reg_val[i];
 
@@ -945,8 +1093,13 @@ static int cam_vfe_handle_irq_bottom_half(void *handler_priv,
 		if (vfe_priv->event_cb)
 			vfe_priv->event_cb(vfe_priv->priv,
 				CAM_ISP_HW_EVENT_ERROR, (void *)&evt_info);
-		cam_vfe_top_ver4_print_debug_reg_status(vfe_priv,
-			irq_status);
+
+		cam_vfe_top_ver4_print_debug_reg_status(vfe_priv->top_priv);
+
+		if (irq_status[CAM_IFE_IRQ_CAMIF_REG_STATUS0] &
+			vfe_priv->reg_data->pp_violation_mask)
+			cam_vfe_top_ver4_print_violation_info(
+				vfe_priv->top_priv);
 
 		ret = CAM_VFE_IRQ_STATUS_ERR;
 	}
@@ -1326,6 +1479,7 @@ static int cam_vfe_resource_deinit(
 }
 
 int cam_vfe_res_mux_init(
+	struct cam_vfe_top_ver4_priv  *top_priv,
 	struct cam_hw_intf            *hw_intf,
 	struct cam_hw_soc_info        *soc_info,
 	void                          *vfe_hw_info,
@@ -1351,7 +1505,7 @@ int cam_vfe_res_mux_init(
 	vfe_priv->soc_info    = soc_info;
 	vfe_priv->vfe_irq_controller = vfe_irq_controller;
 	vfe_priv->is_pixel_path = (vfe_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF);
-	vfe_priv->module_desc   = hw_info->module_desc;
+	vfe_priv->top_priv     = top_priv;
 
 	vfe_res->init                = cam_vfe_resource_init;
 	vfe_res->deinit              = cam_vfe_resource_deinit;
@@ -1457,7 +1611,8 @@ int cam_vfe_top_ver4_init(
 			top_priv->top_common.mux_rsrc[i].res_id =
 				CAM_ISP_HW_VFE_IN_CAMIF;
 
-			rc = cam_vfe_res_mux_init(hw_intf, soc_info,
+			rc = cam_vfe_res_mux_init(top_priv,
+				hw_intf, soc_info,
 				&hw_info->vfe_full_hw_info,
 				&top_priv->top_common.mux_rsrc[i],
 				vfe_irq_controller);
@@ -1467,7 +1622,8 @@ int cam_vfe_top_ver4_init(
 			top_priv->top_common.mux_rsrc[i].res_id =
 				CAM_ISP_HW_VFE_IN_PDLIB;
 
-			rc = cam_vfe_res_mux_init(hw_intf, soc_info,
+			rc = cam_vfe_res_mux_init(top_priv,
+				hw_intf, soc_info,
 				&hw_info->pdlib_hw_info,
 				&top_priv->top_common.mux_rsrc[i],
 				vfe_irq_controller);
@@ -1486,7 +1642,8 @@ int cam_vfe_top_ver4_init(
 			top_priv->top_common.mux_rsrc[i].res_id =
 				CAM_ISP_HW_VFE_IN_RDI0 + j;
 
-			rc = cam_vfe_res_mux_init(hw_intf, soc_info,
+			rc = cam_vfe_res_mux_init(top_priv,
+				hw_intf, soc_info,
 				hw_info->rdi_hw_info[j++],
 				&top_priv->top_common.mux_rsrc[i],
 				vfe_irq_controller);
@@ -1496,7 +1653,8 @@ int cam_vfe_top_ver4_init(
 			top_priv->top_common.mux_rsrc[i].res_id =
 				CAM_ISP_HW_VFE_IN_LCR;
 
-			rc = cam_vfe_res_mux_init(hw_intf, soc_info,
+			rc = cam_vfe_res_mux_init(top_priv,
+				hw_intf, soc_info,
 				&hw_info->lcr_hw_info,
 				&top_priv->top_common.mux_rsrc[i],
 				vfe_irq_controller);
@@ -1521,6 +1679,7 @@ int cam_vfe_top_ver4_init(
 	vfe_top->hw_ops.process_cmd = cam_vfe_top_ver4_process_cmd;
 	*vfe_top_ptr = vfe_top;
 
+	top_priv->common_data.hw_info      = hw_info;
 	top_priv->common_data.soc_info     = soc_info;
 	top_priv->common_data.hw_intf      = hw_intf;
 	top_priv->top_common.hw_idx        = hw_intf->hw_idx;

+ 10 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.h

@@ -88,10 +88,14 @@ struct cam_vfe_top_ver4_module_desc {
 	uint8_t *desc;
 };
 
+struct cam_vfe_top_ver4_wr_client_desc {
+	uint32_t  wm_id;
+	uint8_t  *desc;
+};
+
 struct cam_vfe_ver4_path_hw_info {
 	struct cam_vfe_top_ver4_reg_offset_common  *common_reg;
 	struct cam_vfe_ver4_path_reg_data          *reg_data;
-	struct cam_vfe_top_ver4_module_desc        *module_desc;
 };
 
 struct cam_vfe_top_ver4_hw_info {
@@ -104,7 +108,11 @@ struct cam_vfe_top_ver4_hw_info {
 	struct cam_vfe_fe_ver1_hw_info      fe_hw_info;
 
 	struct cam_vfe_ver4_path_reg_data               *reg_data;
-	uint32_t                                    num_mux;
+	struct cam_vfe_top_ver4_wr_client_desc          *wr_client_desc;
+	struct cam_vfe_top_ver4_module_desc             *module_desc;
+	struct cam_vfe_top_camnoc_debug_data            *camnoc_debug_data;
+	uint32_t                                         num_reg;
+	uint32_t                                         num_mux;
 	uint32_t mux_type[CAM_VFE_TOP_MUX_MAX];
 };