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

Commit 1996f82b authored by Jigar Agrawal's avatar Jigar Agrawal
Browse files

msm: camera: common: Improve the CSID logging



Improve CSID irq logging for better debugging.
Add support to dump the hw source clock.

CRs-Fixed: 2808577
Change-Id: I06608588ef7a6e0ebc174a1ba138f6e16a9094f2
Signed-off-by: default avatarJigar Agrawal <jigar@codeaurora.org>
parent 168408b4
Loading
Loading
Loading
Loading
+51 −11
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/slab.h>
@@ -323,6 +323,41 @@ 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)
{

	struct cam_isp_hw_intf_data               *hw_intf_data = NULL;
	struct cam_hw_intf                        *hw_intf = NULL;
	uint8_t                                    dummy_args;

	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;
		}

		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");
			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);
	}

	return 0;
}

static int cam_ife_hw_mgr_reset_csid_res(
	struct cam_isp_hw_mgr_res   *isp_hw_res)
{
@@ -7671,8 +7706,7 @@ static int cam_ife_hw_mgr_handle_csid_event(
	 * received from CSID
	 */
	switch (event_info->err_type) {
	case CAM_ISP_HW_ERROR_CSID_FATAL: {

	case CAM_ISP_HW_ERROR_CSID_FATAL:
		if (!g_ife_hw_mgr.debug_cfg.enable_csid_recovery)
			break;

@@ -7681,7 +7715,12 @@ static int cam_ife_hw_mgr_handle_csid_event(
			event_info->hw_idx,
			&recovery_data);
		break;
	}
	case 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");
		break;
	default:
		break;
	}
@@ -7707,7 +7746,8 @@ static int cam_ife_hw_mgr_handle_hw_err(
		error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW;

	spin_lock(&g_ife_hw_mgr.ctx_lock);
	if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) {
	if ((event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) ||
		(event_info->err_type == CAM_ISP_HW_ERROR_CSID_OVERFLOW)) {
		rc = cam_ife_hw_mgr_handle_csid_event(event_info);
		spin_unlock(&g_ife_hw_mgr.ctx_lock);
		return rc;
+8 −8
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_ISP_HW_MGR_INTF_H_
@@ -53,13 +53,13 @@ enum cam_isp_hw_event_type {
 *                         ISP hardware event CAM_ISP_HW_EVENT_ERROR
 */
enum cam_isp_hw_err_type {
	CAM_ISP_HW_ERROR_NONE,
	CAM_ISP_HW_ERROR_OVERFLOW,
	CAM_ISP_HW_ERROR_P2I_ERROR,
	CAM_ISP_HW_ERROR_VIOLATION,
	CAM_ISP_HW_ERROR_BUSIF_OVERFLOW,
	CAM_ISP_HW_ERROR_CSID_FATAL,
	CAM_ISP_HW_ERROR_MAX,
	CAM_ISP_HW_ERROR_NONE = 0x0001,
	CAM_ISP_HW_ERROR_OVERFLOW = 0x0002,
	CAM_ISP_HW_ERROR_P2I_ERROR = 0x0004,
	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,
};

/**
+106 −77
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/iopoll.h>
@@ -4663,7 +4663,6 @@ static int cam_csid_evt_bottom_half_handler(
	struct cam_ife_csid_hw *csid_hw;
	struct cam_csid_evt_payload *evt_payload;
	int i;
	int rc = 0;
	struct cam_isp_hw_event_info event_info;
	const struct cam_ife_csid_reg_offset    *csid_reg;
	int udi_start_idx = CAM_IFE_CSID_IRQ_REG_UDI_0;
@@ -4697,7 +4696,10 @@ static int cam_csid_evt_bottom_half_handler(
		goto end;
	}

	if (csid_hw->sof_irq_triggered && (evt_payload->evt_type ==
	CAM_DBG(CAM_ISP, "CSID[%d] error type 0x%x", csid_hw->hw_intf->hw_idx,
		evt_payload->evt_type);

	if (csid_hw->sof_irq_triggered && (evt_payload->evt_type &
		CAM_ISP_HW_ERROR_NONE)) {
		if (evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_IPP] &
			CSID_PATH_INFO_INPUT_SOF) {
@@ -4728,9 +4730,12 @@ static int cam_csid_evt_bottom_half_handler(
					"CSID:%d UDI:%d SOF received",
					csid_hw->hw_intf->hw_idx, i);
		}
	} else {
	}

	if ((evt_payload->evt_type & CAM_ISP_HW_ERROR_CSID_FATAL) ||
		(evt_payload->evt_type & CAM_ISP_HW_ERROR_CSID_OVERFLOW)) {
		CAM_ERR_RATE_LIMIT(CAM_ISP,
			"CSID %d err %d phy %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x PPP: 0x%x RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x RDI3: 0x%x UDI0:  0x%x  UDI1:  0x%x  UDI2:  0x%x",
			"CSID %d err 0x%x phy %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x PPP: 0x%x RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x RDI3: 0x%x UDI0:  0x%x  UDI1:  0x%x  UDI2:  0x%x",
			csid_hw->hw_intf->hw_idx,
			evt_payload->evt_type,
			csid_hw->csi2_rx_cfg.phy_sel,
@@ -4747,32 +4752,28 @@ static int cam_csid_evt_bottom_half_handler(
			evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_UDI_2]);
	}

	if (evt_payload->evt_type == CAM_ISP_HW_ERROR_CSID_FATAL)
		cam_subdev_notify_message(CAM_CSIPHY_DEVICE_TYPE,
				CAM_SUBDEV_MESSAGE_IRQ_ERR,
				csid_hw->csi2_rx_cfg.phy_sel);

	/* this hunk can be extended to handle more cases
	 * which we want to offload to bottom half from
	 * irq handlers
	 */
	event_info.err_type = evt_payload->evt_type;
	event_info.hw_idx = evt_payload->hw_idx;

	switch (evt_payload->evt_type) {
	case CAM_ISP_HW_ERROR_CSID_FATAL:
	if (evt_payload->evt_type & CAM_ISP_HW_ERROR_CSID_FATAL) {
		cam_subdev_notify_message(CAM_CSIPHY_DEVICE_TYPE,
				CAM_SUBDEV_MESSAGE_IRQ_ERR,
				csid_hw->csi2_rx_cfg.phy_sel);
		if (csid_hw->fatal_err_detected)
			break;
			goto end;
		csid_hw->fatal_err_detected = true;
		rc = csid_hw->event_cb(NULL,
		event_info.err_type = CAM_ISP_HW_ERROR_CSID_FATAL;
		csid_hw->event_cb(NULL,
			CAM_ISP_HW_EVENT_ERROR, (void *)&event_info);
		break;
	}

	default:
		CAM_DBG(CAM_ISP, "CSID[%d] error type %d",
			csid_hw->hw_intf->hw_idx,
			evt_payload->evt_type);
		break;
	if (evt_payload->evt_type & CAM_ISP_HW_ERROR_CSID_OVERFLOW) {
		event_info.err_type = CAM_ISP_HW_ERROR_CSID_OVERFLOW;
		csid_hw->event_cb(NULL,
			CAM_ISP_HW_EVENT_ERROR, (void *)&event_info);
	}
end:
	cam_csid_put_evt_payload(csid_hw, &evt_payload);
@@ -4781,7 +4782,7 @@ static int cam_csid_evt_bottom_half_handler(

static int cam_csid_handle_hw_err_irq(
	struct cam_ife_csid_hw *csid_hw,
	int                     evt_type,
	uint32_t                evt_type,
	uint32_t               *irq_status)
{
	int      rc = 0;
@@ -4789,7 +4790,7 @@ static int cam_csid_handle_hw_err_irq(
	void    *bh_cmd = NULL;
	struct cam_csid_evt_payload *evt_payload;

	CAM_DBG(CAM_ISP, "CSID[%d] error %d",
	CAM_DBG(CAM_ISP, "CSID[%d] error 0x%x",
		csid_hw->hw_intf->hw_idx, evt_type);

	rc = cam_csid_get_evt_payload(csid_hw, &evt_payload);
@@ -4803,7 +4804,7 @@ static int cam_csid_handle_hw_err_irq(
	rc = tasklet_bh_api.get_bh_payload_func(csid_hw->tasklet, &bh_cmd);
	if (rc || !bh_cmd) {
		CAM_ERR_RATE_LIMIT(CAM_ISP,
			"CSID[%d] Can not get cmd for tasklet, evt_type %d",
			"CSID[%d] Can not get cmd for tasklet, evt_type 0x%x",
			csid_hw->hw_intf->hw_idx,
			evt_type);
		cam_csid_put_evt_payload(csid_hw, &evt_payload);
@@ -4835,7 +4836,8 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
	uint32_t                                        irq_status[CAM_IFE_CSID_IRQ_REG_MAX] = {0};
	uint32_t                                        i, val, val2;
	bool                                            fatal_err_detected = false;
	uint32_t sof_irq_debug_en = 0, log_en = 0;
	uint32_t                                        sof_irq_debug_en = 0;
	uint32_t                                        event_type = 0;
	unsigned long                                   flags;

	csid_hw = (struct cam_ife_csid_hw *)data;
@@ -4966,76 +4968,94 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
	if (csid_hw->device_enabled == 1) {
		if (irq_status[CAM_IFE_CSID_IRQ_REG_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);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RX_ERROR_LANE0_FIFO_OVERFLOW: Skew/Less Data on lanes/ Slow csid clock:%luHz",
				csid_hw->hw_intf->hw_idx,
				soc_info->applied_src_clk_rate);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_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);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RX_ERROR_LANE1_FIFO_OVERFLOW: Skew/Less Data on lanes/ Slow csid clock:%luHz",
				csid_hw->hw_intf->hw_idx,
				soc_info->applied_src_clk_rate);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_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);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RX_ERROR_LANE2_FIFO_OVERFLOW: Skew/Less Data on lanes/ Slow csid clock:%luHz",
				csid_hw->hw_intf->hw_idx,
				soc_info->applied_src_clk_rate);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_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);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RX_ERROR_LANE3_FIFO_OVERFLOW: Skew/Less Data on lanes/ Slow csid clock:%luHz",
				csid_hw->hw_intf->hw_idx,
				soc_info->applied_src_clk_rate);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RX_ERROR_TPG_FIFO_OVERFLOW: Backpressure from IFE",
				csid_hw->hw_intf->hw_idx);
			fatal_err_detected = true;
			event_type |= CAM_ISP_HW_ERROR_CSID_OVERFLOW;
			goto handle_fatal_error;
		}
		if ((irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) &&
			(!csid_hw->epd_supported)) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d CPHY_EOT_RECEPTION",
				"CSID:%d CPHY_EOT_RECEPTION: No EOT on lane/s",
				csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d CPHY_SOT_RECEPTION",
				"CSID:%d CPHY_SOT_RECEPTION: Less SOTs on lane/s",
				csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC",
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d CPHY_PH_CRC CPHY: Pkt Hdr CRC mismatch",
				csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_CRC) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC",
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d ERROR_CRC CPHY: Long pkt payload CRC mismatch",
				csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_ECC) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC",
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d ERROR_ECC: Dphy pkt hdr errors unrecoverable",
				csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT",
				csid_hw->hw_intf->hw_idx);
			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
			csi2_reg->csid_csi2_rx_captured_long_pkt_0_addr);

			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d MMAPPED_VC_DT: VC:%d DT:%d mapped to more than 1 csid paths",
				csid_hw->hw_intf->hw_idx, (val >> 22),
				((val >> 16) & 0x3F), (val & 0xFFFF));
		}
		if ((irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT) &&
@@ -5046,21 +5066,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
			csi2_reg->csid_csi2_rx_captured_long_pkt_0_addr);

			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d UNMAPPED_VC_DT. VC: %d DT: %d WC: %d",
				"CSID:%d UNMAPPED_VC_DT: VC:%d DT:%d WC:%d not mapped to any csid paths",
				csid_hw->hw_intf->hw_idx, (val >> 22),
				((val >> 16) & 0x3F), (val & 0xFFFF));
			csid_hw->error_irq_count++;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
			csi2_reg->csid_csi2_rx_captured_long_pkt_0_addr);

			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d ERROR_STREAM_UNDERFLOW",
				csid_hw->hw_intf->hw_idx);
				"CSID:%d ERROR_STREAM_UNDERFLOW: Fewer bytes rcvd than WC:%d in pkt hdr",
				csid_hw->hw_intf->hw_idx, (val & 0xFFFF));
			csid_hw->error_irq_count++;
		}
		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
			CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME",
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d UNBOUNDED_FRAME: Frame started with EOF or No EOF",
				csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
@@ -5078,7 +5102,8 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
	if (fatal_err_detected) {
		cam_ife_csid_halt_csi2(csid_hw);
		cam_csid_handle_hw_err_irq(csid_hw,
			CAM_ISP_HW_ERROR_CSID_FATAL, irq_status);
			(event_type | CAM_ISP_HW_ERROR_CSID_FATAL), irq_status);
		event_type = 0;
	}

	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
@@ -5206,7 +5231,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
				"CSID:%d IPP SOF received",
					csid_hw->hw_intf->hw_idx);
			else
				log_en = 1;
				event_type |= CAM_ISP_HW_ERROR_NONE;

			if (csid_hw->sof_irq_triggered)
				csid_hw->irq_debug_cnt++;
@@ -5221,24 +5246,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
		if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] &
			CSID_PATH_ERROR_CCIF_VIOLATION))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d IPP CCIF violation",
				"CSID:%d IPP_PATH_ERROR_CCIF_VIOLATION: Bad frame timings",
				csid_hw->hw_intf->hw_idx);

		if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] &
			CSID_PATH_OVERFLOW_RECOVERY))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d IPP Overflow due to back pressure",
				"CSID:%d IPP_PATH_OVERFLOW_RECOVERY: Back pressure/output fifo ovrfl",
				csid_hw->hw_intf->hw_idx);

		if (irq_status[CAM_IFE_CSID_IRQ_REG_IPP] &
			CSID_PATH_ERROR_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d IPP fifo over flow",
				csid_hw->hw_intf->hw_idx);
			/* Stop IPP path immediately */
			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
				soc_info->reg_map[0].mem_base +
				csid_reg->ipp_reg->csid_pxl_ctrl_addr);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d IPP_PATH_ERROR_O/P_FIFO_OVERFLOW: Slow IFE read",
				csid_hw->hw_intf->hw_idx);
			event_type |= CAM_ISP_HW_ERROR_CSID_OVERFLOW;
		}

		if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] &
@@ -5289,7 +5315,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
				"CSID:%d IPP SOF received",
					csid_hw->hw_intf->hw_idx);
			else
				log_en = 1;
				event_type |= CAM_ISP_HW_ERROR_NONE;

			if (csid_hw->sof_irq_triggered)
				csid_hw->irq_debug_cnt++;
@@ -5304,24 +5330,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
		if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] &
			CSID_PATH_ERROR_CCIF_VIOLATION))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d PPP CCIF violation",
				"CSID:%d PPP_PATH_ERROR_CCIF_VIOLATION: Bad frame timings",
				csid_hw->hw_intf->hw_idx);

		if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] &
			CSID_PATH_OVERFLOW_RECOVERY))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d IPP Overflow due to back pressure",
				"CSID:%d PPP_PATH_OVERFLOW_RECOVERY: Back pressure/output fifo ovrfl",
				csid_hw->hw_intf->hw_idx);

		if (irq_status[CAM_IFE_CSID_IRQ_REG_PPP] &
			CSID_PATH_ERROR_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d PPP fifo over flow",
				csid_hw->hw_intf->hw_idx);
			/* Stop PPP path immediately */
			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
				soc_info->reg_map[0].mem_base +
				csid_reg->ppp_reg->csid_pxl_ctrl_addr);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d PPP_PATH_ERROR_O/P_FIFO_OVERFLOW: Slow IFE read",
				csid_hw->hw_intf->hw_idx);
			event_type |= CAM_ISP_HW_ERROR_CSID_OVERFLOW;
		}

		if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] &
@@ -5369,7 +5396,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
				"CSID:%d RDI:%d SOF received",
					csid_hw->hw_intf->hw_idx, i);
			else
				log_en = 1;
				event_type |= CAM_ISP_HW_ERROR_NONE;

			if (csid_hw->sof_irq_triggered)
				csid_hw->irq_debug_cnt++;
@@ -5383,22 +5410,24 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)

		if ((irq_status[i] & CSID_PATH_ERROR_CCIF_VIOLATION))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d RDI :%d CCIF violation",
				"CSID:%d RDI :%d PATH_ERROR_CCIF_VIOLATION: Bad frame timings",
				csid_hw->hw_intf->hw_idx, i);

		if ((irq_status[i] & CSID_PATH_OVERFLOW_RECOVERY))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d RDI :%d Overflow due to back pressure",
				"CSID:%d RDI :%d PATH_OVERFLOW_RECOVERY: Back pressure/output fifo ovrfl",
				csid_hw->hw_intf->hw_idx, i);

		if (irq_status[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RDI fifo over flow",
				csid_hw->hw_intf->hw_idx);
			/* Stop RDI path immediately */
			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
				soc_info->reg_map[0].mem_base +
				csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RDI_PATH_ERROR_O/P_FIFO_OVERFLOW: Slow IFE read",
				csid_hw->hw_intf->hw_idx);

			event_type |= CAM_ISP_HW_ERROR_CSID_OVERFLOW;
		}

		if ((irq_status[i] & CSID_PATH_ERROR_PIX_COUNT) ||
@@ -5443,7 +5472,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
				"CSID:%d UDI:%d SOF received",
					csid_hw->hw_intf->hw_idx, i);
			else
				log_en = 1;
				event_type |= CAM_ISP_HW_ERROR_NONE;

			if (csid_hw->sof_irq_triggered)
				csid_hw->irq_debug_cnt++;
@@ -5459,30 +5488,30 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
		if ((irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] &
			CSID_PATH_ERROR_CCIF_VIOLATION))
			CAM_WARN_RATE_LIMIT(CAM_ISP,
				"CSID:%d UDI :%d CCIF violation",
				"CSID:%d UDI :%d PATH_ERROR_CCIF_VIOLATION: Bad frame timings",
				csid_hw->hw_intf->hw_idx, i);

		if ((irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] &
			CSID_PATH_OVERFLOW_RECOVERY))
			CAM_WARN_RATE_LIMIT(CAM_ISP,
				"CSID:%d UDI :%d Overflow due to back pressure",
				"CSID:%d UDI :%d PATH_OVERFLOW_RECOVERY: Back pressure/output fifo ovrfl",
				csid_hw->hw_intf->hw_idx, i);

		if (irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] &
			CSID_PATH_ERROR_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d UDI fifo over flow",
				csid_hw->hw_intf->hw_idx);
			/* Stop UDI path immediately */
			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
				soc_info->reg_map[0].mem_base +
				csid_reg->udi_reg[i]->csid_udi_ctrl_addr);
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d UDI_PATH_ERROR_O/P_FIFO_OVERFLOW: Slow ife read",
				csid_hw->hw_intf->hw_idx);
			event_type |= CAM_ISP_HW_ERROR_CSID_OVERFLOW;
		}
	}

	if (log_en)
		cam_csid_handle_hw_err_irq(csid_hw,
			CAM_ISP_HW_ERROR_NONE, irq_status);
	if (event_type)
		cam_csid_handle_hw_err_irq(csid_hw, event_type, irq_status);

	if (csid_hw->irq_debug_cnt >= CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
		cam_ife_csid_sof_irq_debug(csid_hw, &sof_irq_debug_en);
+2 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_IFE_CSID_HW_H_
@@ -599,7 +599,7 @@ struct cam_csid_evt_payload {
 * @csid_udin_reset_complete: udi n completion
 * @csid_debug:               csid debug information to enable the SOT, EOT,
 *                            SOF, EOF, measure etc in the csid hw
 * @clk_rate                  Clock rate
 * @clk_rate                  Current clock rate
 * @sof_irq_triggered:        Flag is set on receiving event to enable sof irq
 *                            incase of SOF freeze.
 * @is_resetting:             informs whether reset is started or not.
+2 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_ISP_HW_H_
@@ -137,6 +137,7 @@ enum cam_isp_hw_cmd_type {
	CAM_ISP_HW_CMD_QUERY_BUS_CAP,
	CAM_ISP_HW_CMD_GET_CLOCK_RATE,
	CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
	CAM_ISP_HW_DUMP_HW_SRC_CLK_RATE,
	CAM_ISP_HW_CMD_MAX,
};

Loading