Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +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> Loading Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +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_ Loading Loading @@ -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, }; /** Loading drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +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> Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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, Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) && Loading @@ -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++; } Loading @@ -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) { Loading Loading @@ -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++; Loading @@ -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] & Loading Loading @@ -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++; Loading @@ -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] & Loading Loading @@ -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++; Loading @@ -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) || Loading Loading @@ -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++; Loading @@ -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); Loading drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +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_ Loading Loading @@ -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. Loading drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +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_ Loading Loading @@ -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 Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +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> Loading Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +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_ Loading Loading @@ -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, }; /** Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +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> Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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, Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) && Loading @@ -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++; } Loading @@ -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) { Loading Loading @@ -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++; Loading @@ -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] & Loading Loading @@ -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++; Loading @@ -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] & Loading Loading @@ -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++; Loading @@ -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) || Loading Loading @@ -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++; Loading @@ -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); Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +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_ Loading Loading @@ -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. Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +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_ Loading Loading @@ -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