Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09e33793 authored by Harsh Shah's avatar Harsh Shah
Browse files

msm: camera: csid: Disable CSI Rx upon fatal errors



When we encounter fatal errors, this change will reset the
Rx Cfg registers. This will stop the error IRQs from being
triggered continuously.

Change-Id: Idc7a68d37a3c91c9bccf5962d168c3529f41723f
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
parent 2a2caaf0
Loading
Loading
Loading
Loading
+42 −9
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@
#define CAM_IFE_CSID_QTIMER_DIV_FACTOR                 192

/* Max number of sof irq's triggered in case of SOF freeze */
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 6
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12

/* Max CSI Rx irq error count threshold value */
#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT               100
@@ -1349,11 +1349,39 @@ static int cam_ife_csid_disable_csi2(
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);

	/* Reset the Rx CFG registers */
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);

	res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;

	return 0;
}

static void cam_ife_csid_halt_csi2(
	struct cam_ife_csid_hw          *csid_hw)
{
	const struct cam_ife_csid_reg_offset      *csid_reg;
	struct cam_hw_soc_info                    *soc_info;

	csid_reg = csid_hw->csid_info->csid_reg;
	soc_info = &csid_hw->hw_info->soc_info;
	CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx",
		csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);

	/* Disable the CSI2 rx inerrupts */
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);

	/* Reset the Rx CFG registers */
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
}

static int cam_ife_csid_init_config_ipp_path(
	struct cam_ife_csid_hw          *csid_hw,
	struct cam_isp_resource_node    *res)
@@ -2755,6 +2783,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
	uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
	uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
	uint32_t val, sof_irq_disable = 0;
	bool fatal_err_detected = false;

	csid_hw = (struct cam_ife_csid_hw *)data;

@@ -2814,26 +2843,27 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
	if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
			 csid_hw->hw_intf->hw_idx);
		csid_hw->error_irq_count++;
		fatal_err_detected = true;
	}
	if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
			 csid_hw->hw_intf->hw_idx);
		csid_hw->error_irq_count++;
		fatal_err_detected = true;
	}
	if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
			 csid_hw->hw_intf->hw_idx);
		csid_hw->error_irq_count++;
		fatal_err_detected = true;
	}
	if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
			 csid_hw->hw_intf->hw_idx);
		csid_hw->error_irq_count++;
		fatal_err_detected = true;
	}
	if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
			 csid_hw->hw_intf->hw_idx);
		fatal_err_detected = true;
	}
	if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_EOT_RECEPTION",
@@ -2871,6 +2901,9 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
		csid_hw->error_irq_count++;
	}

	if (fatal_err_detected)
		cam_ife_csid_halt_csi2(csid_hw);

	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
		if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
			CAM_INFO_RATE_LIMIT(CAM_ISP,