diff --git a/drivers/cam_icp/fw_inc/hfi_intf.h b/drivers/cam_icp/fw_inc/hfi_intf.h index 37d9b681b3..88db226e67 100644 --- a/drivers/cam_icp/fw_inc/hfi_intf.h +++ b/drivers/cam_icp/fw_inc/hfi_intf.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _HFI_INTF_H_ @@ -182,8 +183,10 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem); /** * cam_hfi_queue_dump() - utility function to dump hfi queues + * @dump_queue_data: if set dumps queue contents + * */ -void cam_hfi_queue_dump(void); +void cam_hfi_queue_dump(bool dump_queue_data); /** * cam_hfi_mini_dump() - utility function for mini dump diff --git a/drivers/cam_icp/hfi.c b/drivers/cam_icp/hfi.c index 5abba72b24..de0c2a77fe 100644 --- a/drivers/cam_icp/hfi.c +++ b/drivers/cam_icp/hfi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -121,7 +122,7 @@ void cam_hfi_mini_dump(struct hfi_mini_dump_info *dst) dst->cmd_q_state = g_hfi->cmd_q_state; } -void cam_hfi_queue_dump(void) +void cam_hfi_queue_dump(bool dump_queue_data) { struct hfi_mem_info *hfi_mem = &g_hfi->map; struct hfi_qtbl *qtbl; @@ -135,7 +136,7 @@ void cam_hfi_queue_dump(void) } qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva; - CAM_DBG(CAM_HFI, + CAM_INFO(CAM_HFI, "qtbl header: version=0x%08x tbl_size=%u numq=%u qhdr_size=%u", qtbl->q_tbl_hdr.qtbl_version, qtbl->q_tbl_hdr.qtbl_size, @@ -143,7 +144,7 @@ void cam_hfi_queue_dump(void) qtbl->q_tbl_hdr.qtbl_qhdr_size); q_hdr = &qtbl->q_hdr[Q_CMD]; - CAM_DBG(CAM_HFI, + CAM_INFO(CAM_HFI, "cmd_q: addr=0x%08x size=%u read_idx=%u write_idx=%u", hfi_mem->cmd_q.iova, q_hdr->qhdr_q_size, @@ -153,10 +154,11 @@ void cam_hfi_queue_dump(void) dwords = (uint32_t *)hfi_mem->cmd_q.kva; num_dwords = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; - hfi_queue_dump(dwords, num_dwords); + if (dump_queue_data) + hfi_queue_dump(dwords, num_dwords); q_hdr = &qtbl->q_hdr[Q_MSG]; - CAM_DBG(CAM_HFI, + CAM_INFO(CAM_HFI, "msg_q: addr=0x%08x size=%u read_idx=%u write_idx=%u", hfi_mem->msg_q.iova, q_hdr->qhdr_q_size, @@ -166,7 +168,8 @@ void cam_hfi_queue_dump(void) dwords = (uint32_t *)hfi_mem->msg_q.kva; num_dwords = ICP_MSG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; - hfi_queue_dump(dwords, num_dwords); + if (dump_queue_data) + hfi_queue_dump(dwords, num_dwords); } #ifndef CONFIG_CAM_PRESIL diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_core.c b/drivers/cam_icp/icp_hw/a5_hw/a5_core.c index 33b39dabde..ac39b6e6e7 100644 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_core.c +++ b/drivers/cam_icp/icp_hw/a5_hw/a5_core.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -746,6 +747,10 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, rc = cam_a5_fw_mini_dump(dump_args, core_info); break; } + case CAM_ICP_CMD_HW_REG_DUMP: { + /* reg dump not supported */ + break; + } default: break; } diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 9c088e781d..2bbf96f58b 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -126,6 +126,19 @@ static const char *cam_icp_dev_type_to_name( } } +static inline void cam_icp_dump_debug_info(bool skip_dump) +{ + struct cam_hw_intf *icp_dev_intf = icp_hw_mgr.icp_dev_intf; + + if (skip_dump) + return; + + cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); + cam_hfi_queue_dump(false); + icp_dev_intf->hw_ops.process_cmd( + icp_dev_intf->hw_priv, CAM_ICP_CMD_HW_REG_DUMP, NULL, 0x0); +} + static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr) { struct cam_hw_intf *icp_dev_intf = hw_mgr->icp_dev_intf; @@ -2122,6 +2135,7 @@ static int cam_icp_mgr_cleanup_ctx(struct cam_icp_hw_ctx_data *ctx_data) ctx_data->hfi_frame_process.in_free_resource[i] = 0; } + ctx_data->abort_timed_out = false; return 0; } @@ -2605,6 +2619,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr) sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva; CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg); + cam_icp_dump_debug_info(false); cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr); cam_icp_ipebps_reset(hw_mgr); @@ -2639,7 +2654,6 @@ static int cam_icp_mgr_process_fatal_error( BUG(); } rc = cam_icp_mgr_trigger_recovery(hw_mgr); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); } return rc; @@ -3743,8 +3757,8 @@ static int cam_icp_mgr_abort_handle( CAM_ERR(CAM_ICP, "FW timeout/err in abort handle command ctx: %u", ctx_data->ctx_id); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(false); + ctx_data->abort_timed_out = true; } } @@ -3800,8 +3814,7 @@ static int cam_icp_mgr_destroy_handle( rc = -ETIMEDOUT; CAM_ERR(CAM_ICP, "FW response timeout: %d for %u", rc, ctx_data->ctx_id); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(ctx_data->abort_timed_out); } kfree(destroy_cmd); return rc; @@ -4206,8 +4219,7 @@ static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr) if (!rem_jiffies) { rc = -ETIMEDOUT; CAM_ERR(CAM_ICP, "FW response timed out %d", rc); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(false); } CAM_DBG(CAM_ICP, "Done Waiting for INIT DONE Message"); @@ -4512,8 +4524,7 @@ static int cam_icp_mgr_send_config_io(struct cam_icp_hw_ctx_data *ctx_data, ctx_data->ctx_id, ctx_data->acquire_dev_cmd.dev_handle, ctx_data->acquire_dev_cmd.session_handle, ctx_data->icp_dev_acquire_info->dev_type); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(false); } return rc; @@ -4977,7 +4988,7 @@ static int cam_icp_process_stream_settings( if (!rem_jiffies) { rc = -ETIMEDOUT; CAM_ERR(CAM_ICP, "FW response timed out %d", rc); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(false); } end: @@ -5750,8 +5761,8 @@ static int cam_icp_mgr_enqueue_abort( CAM_ERR(CAM_ICP, "FW timeout/err in abort handle command ctx: %u", ctx_data->ctx_id); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(false); + ctx_data->abort_timed_out = true; return rc; } } @@ -6078,8 +6089,7 @@ static int cam_icp_mgr_create_handle(uint32_t dev_type, if (!rem_jiffies) { rc = -ETIMEDOUT; CAM_ERR(CAM_ICP, "FW response timed out %d", rc); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(false); } if (ctx_data->fw_handle == 0) { @@ -6126,8 +6136,7 @@ static int cam_icp_mgr_send_ping(struct cam_icp_hw_ctx_data *ctx_data) if (!rem_jiffies) { rc = -ETIMEDOUT; CAM_ERR(CAM_ICP, "FW response timed out %d", rc); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); - cam_hfi_queue_dump(); + cam_icp_dump_debug_info(false); } return rc; diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h index 3792241e92..a52f368c3a 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef CAM_ICP_HW_MGR_H @@ -270,6 +271,7 @@ struct cam_ctx_clk_info { * @watch_dog_reset_counter: Counter for watch dog reset * @icp_dev_io_info: io config resource * @last_flush_req: last flush req for this ctx + * @abort_timed_out: Indicates if abort timed out */ struct cam_icp_hw_ctx_data { void *context_priv; @@ -293,6 +295,7 @@ struct cam_icp_hw_ctx_data { struct cam_icp_acquire_dev_info icp_dev_io_info; uint64_t last_flush_req; char ctx_id_string[128]; + bool abort_timed_out; }; /** diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h b/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h index 2a38d3a153..98d7d460a5 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef CAM_ICP_HW_INTF_H @@ -43,6 +44,7 @@ enum cam_icp_cmd_type { CAM_ICP_CMD_CLK_UPDATE, CAM_ICP_CMD_HW_DUMP, CAM_ICP_CMD_HW_MINI_DUMP, + CAM_ICP_CMD_HW_REG_DUMP, CAM_ICP_CMD_MAX, }; diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c b/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c index 68fecc4840..ceef9bfaf0 100644 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c +++ b/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c @@ -27,8 +27,6 @@ #define TZ_STATE_SUSPEND 0 #define TZ_STATE_RESUME 1 -#define LX7_GEN_PURPOSE_REG_OFFSET 0x20 - #define ICP_FW_NAME_MAX_SIZE 32 #define PC_POLL_DELAY_US 100 @@ -702,6 +700,21 @@ static int cam_lx7_shutdown(struct cam_hw_info *lx7_info) return rc; } +static inline void __cam_lx7_core_reg_dump( + struct cam_hw_info *lx7_info) +{ + void __iomem *cirq_base = lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base; + void __iomem *csr_base = lx7_info->soc_info.reg_map[LX7_CSR_BASE].mem_base; + + CAM_INFO(CAM_ICP, + "CIRQ IB_status0:0x%x IB_Status1:0x%x PFault:0x%x CSR debug_status:0x%x debug_ctrl:0x%x", + cam_io_r_mb(cirq_base + ICP_LX7_CIRQ_IB_STATUS0), + cam_io_r_mb(cirq_base + ICP_LX7_CIRQ_IB_STATUS1), + cam_io_r_mb(cirq_base + ICP_LX7_CIRQ_PFAULT_INFO), + cam_io_r_mb(csr_base + LX7_CSR_DBG_STATUS_REG_OFFSET), + cam_io_r_mb(csr_base + LX7_CSR_DBG_CTRL_REG_OFFSET)); +} + /* API controls collapse/resume of ICP */ static int cam_lx7_core_control( struct cam_hw_info *lx7_info, @@ -713,16 +726,12 @@ static int cam_lx7_core_control( if (core_info->use_sec_pil) { rc = qcom_scm_set_remote_state(state, CAM_FW_PAS_ID); - if (rc) + if (rc) { CAM_ERR(CAM_ICP, - "remote state set to %s failed rc=%d IB_status0=0x%x IB_Status1=0x%x PFault=0x%x", - state == TZ_STATE_RESUME ? "resume" : "suspend", rc, - cam_io_r_mb(lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base + - ICP_LX7_CIRQ_IB_STATUS0), - cam_io_r_mb(lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base + - ICP_LX7_CIRQ_IB_STATUS1), - cam_io_r_mb(lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base + - ICP_LX7_CIRQ_PFAULT_INFO)); + "remote state set to %s failed rc=%d", + (state == TZ_STATE_RESUME ? "resume" : "suspend"), rc); + __cam_lx7_core_reg_dump(lx7_info); + } } else { if (state == TZ_STATE_RESUME) { rc = __cam_lx7_power_resume(lx7_info); @@ -886,6 +895,11 @@ int cam_lx7_process_cmd(void *priv, uint32_t cmd_type, rc = __cam_lx7_fw_mini_dump(lx7_info->core_info, args); break; } + case CAM_ICP_CMD_HW_REG_DUMP: { + __cam_lx7_core_reg_dump(lx7_info); + rc = 0; + break; + } default: CAM_ERR(CAM_ICP, "invalid command type=%u", cmd_type); break; diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_reg.h b/drivers/cam_icp/icp_hw/lx7_hw/lx7_reg.h index 05a69541b4..3129705e27 100644 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_reg.h +++ b/drivers/cam_icp/icp_hw/lx7_hw/lx7_reg.h @@ -7,6 +7,11 @@ #ifndef _CAM_LX7_REG_H_ #define _CAM_LX7_REG_H_ +/* ICP CSR info */ +#define LX7_GEN_PURPOSE_REG_OFFSET 0x20 +#define LX7_CSR_DBG_STATUS_REG_OFFSET 0xC0 +#define LX7_CSR_DBG_CTRL_REG_OFFSET 0xC4 + /* ICP_SYS - Protected reg space defined in AC policy */ #define ICP_LX7_SYS_RESET 0x0 #define ICP_LX7_SYS_CONTROL 0x4