Browse Source

msm: camera: isp: Pause the CRM timer in case of hardware errors

In the Case of CSID RX fetal errors, We disable rx path. Whenever
we get sof freeze after some time, we enable the path SOF
to do a health check of the sensor.
But we don’t get the SOFs and it gives the wrong impression that
the sensor is not streaming.

Notify crm driver to pause the timer in case of fatal hardware error
to not missled sof freez issue.

CRs-Fixed: 2890861
Change-Id: I73e750cad0193ea5537a25c8440a9863343c4ef7
Signed-off-by: Chandan Kumar Jha <[email protected]>
Chandan Kumar Jha 4 years ago
parent
commit
90cd14c1de

+ 10 - 0
drivers/cam_isp/cam_isp_context.c

@@ -2385,6 +2385,7 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
 	struct cam_hw_fence_map_entry   *fence_map_out = NULL;
 	struct cam_hw_fence_map_entry   *fence_map_out = NULL;
 	struct cam_req_mgr_message       req_msg;
 	struct cam_req_mgr_message       req_msg;
 	uint32_t                         evt_param;
 	uint32_t                         evt_param;
+	struct cam_req_mgr_timer_notify  timer;
 
 
 	struct cam_context *ctx = ctx_isp->base;
 	struct cam_context *ctx = ctx_isp->base;
 	struct cam_isp_hw_error_event_data  *error_event_data =
 	struct cam_isp_hw_error_event_data  *error_event_data =
@@ -2394,6 +2395,15 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
 
 
 	CAM_DBG(CAM_ISP, "Enter error_type = %d", error_type);
 	CAM_DBG(CAM_ISP, "Enter error_type = %d", error_type);
 
 
+	if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_timer) {
+		timer.link_hdl = ctx->link_hdl;
+		timer.dev_hdl = ctx->dev_hdl;
+		timer.state = false;
+		ctx->ctx_crm_intf->notify_timer(&timer);
+		CAM_DBG(CAM_ISP, "Notify CRM to pause timer for ctx %u",
+				ctx->ctx_id);
+	}
+
 	if ((error_type == CAM_ISP_HW_ERROR_OVERFLOW) ||
 	if ((error_type == CAM_ISP_HW_ERROR_OVERFLOW) ||
 		(error_type == CAM_ISP_HW_ERROR_BUSIF_OVERFLOW) ||
 		(error_type == CAM_ISP_HW_ERROR_BUSIF_OVERFLOW) ||
 		(error_type == CAM_ISP_HW_ERROR_VIOLATION)) {
 		(error_type == CAM_ISP_HW_ERROR_VIOLATION)) {

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -11233,7 +11233,7 @@ static int cam_ife_hw_mgr_debug_register(void)
 			rc = PTR_ERR(dbgfileptr);
 			rc = PTR_ERR(dbgfileptr);
 	}
 	}
 end:
 end:
-	g_ife_hw_mgr.debug_cfg.enable_recovery = 0;
+	g_ife_hw_mgr.debug_cfg.enable_recovery = 1;
 	return rc;
 	return rc;
 }
 }
 
 

+ 36 - 26
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -723,6 +723,31 @@ static int cam_ife_csid_ver2_rx_top_half(
 	return 0;
 	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_rx_err_bottom_half(
 static int cam_ife_csid_ver2_rx_err_bottom_half(
 	void                                      *handler_priv,
 	void                                      *handler_priv,
 	void                                      *evt_payload_priv)
 	void                                      *evt_payload_priv)
@@ -734,8 +759,10 @@ static int cam_ife_csid_ver2_rx_err_bottom_half(
 	struct cam_hw_soc_info                     *soc_info = NULL;
 	struct cam_hw_soc_info                     *soc_info = NULL;
 	uint8_t                                    *log_buf = NULL;
 	uint8_t                                    *log_buf = NULL;
 	uint32_t                                    irq_status;
 	uint32_t                                    irq_status;
+	uint32_t                                    rx_irq_status = 0;
 	uint32_t                                    len = 0;
 	uint32_t                                    len = 0;
 	uint32_t                                    val = 0;
 	uint32_t                                    val = 0;
+	uint32_t                                    event_type = 0;
 	bool                                        fatal_err_detected = false;
 	bool                                        fatal_err_detected = false;
 
 
 	if (!handler_priv || !evt_payload_priv) {
 	if (!handler_priv || !evt_payload_priv) {
@@ -808,6 +835,7 @@ static int cam_ife_csid_ver2_rx_err_bottom_half(
 				CAM_IFE_CSID_LOG_BUF_LEN - len,
 				CAM_IFE_CSID_LOG_BUF_LEN - len,
 				"DPHY_ERROR_ECC: Pkt hdr errors unrecoverable\n");
 				"DPHY_ERROR_ECC: Pkt hdr errors unrecoverable\n");
 
 
+		rx_irq_status |= irq_status;
 		fatal_err_detected = true;
 		fatal_err_detected = true;
 	}
 	}
 
 
@@ -841,6 +869,7 @@ static int cam_ife_csid_ver2_rx_err_bottom_half(
 				CAM_IFE_CSID_LOG_BUF_LEN - len,
 				CAM_IFE_CSID_LOG_BUF_LEN - len,
 				"UNBOUNDED_FRAME: Frame started with EOF or No EOF\n");
 				"UNBOUNDED_FRAME: Frame started with EOF or No EOF\n");
 
 
+		rx_irq_status |= irq_status;
 		fatal_err_detected = true;
 		fatal_err_detected = true;
 	}
 	}
 
 
@@ -866,10 +895,16 @@ static int cam_ife_csid_ver2_rx_err_bottom_half(
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%u] %s",
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%u] %s",
 			csid_hw->hw_intf->hw_idx, log_buf);
 			csid_hw->hw_intf->hw_idx, log_buf);
 
 
-	if (fatal_err_detected)
+	if (csid_hw->flags.fatal_err_detected || fatal_err_detected) {
+		event_type |= CAM_ISP_HW_ERROR_CSID_FATAL;
 		cam_subdev_notify_message(CAM_CSIPHY_DEVICE_TYPE,
 		cam_subdev_notify_message(CAM_CSIPHY_DEVICE_TYPE,
 				CAM_SUBDEV_MESSAGE_IRQ_ERR,
 				CAM_SUBDEV_MESSAGE_IRQ_ERR,
 				(csid_hw->rx_cfg.phy_sel));
 				(csid_hw->rx_cfg.phy_sel));
+	}
+
+	if (event_type)
+		cam_ife_csid_ver2_handle_event_err(csid_hw,
+			rx_irq_status, event_type);
 
 
 	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
 	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
 			&csid_hw->rx_free_payload_list,
 			&csid_hw->rx_free_payload_list,
@@ -878,31 +913,6 @@ static int cam_ife_csid_ver2_rx_err_bottom_half(
 	return 0;
 	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 void cam_ife_csid_ver2_print_debug_reg_status(
 static void cam_ife_csid_ver2_print_debug_reg_status(
 	struct cam_ife_csid_ver2_hw *csid_hw,
 	struct cam_ife_csid_ver2_hw *csid_hw,
 	struct cam_isp_resource_node    *res)
 	struct cam_isp_resource_node    *res)