msm: camera: icp: Improve ICP debug infrastructure

On FW timeouts, dump ICP status registers and HFI queue indices.

CRs-Fixed: 3110947
Change-Id: I74561ce943c027e51b6f8b61e7ebb68d2a89982d
Signed-off-by: Karthik Anantha Ram <quic_kartanan@quicinc.com>
This commit is contained in:
Karthik Anantha Ram
2022-01-31 12:08:01 -08:00
committed by Camera Software Integration
parent d557934178
commit 1df78bed63
8 changed files with 78 additions and 34 deletions

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _HFI_INTF_H_ #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 * 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 * cam_hfi_mini_dump() - utility function for mini dump

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/io.h> #include <linux/io.h>
@@ -121,7 +122,7 @@ void cam_hfi_mini_dump(struct hfi_mini_dump_info *dst)
dst->cmd_q_state = g_hfi->cmd_q_state; 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_mem_info *hfi_mem = &g_hfi->map;
struct hfi_qtbl *qtbl; struct hfi_qtbl *qtbl;
@@ -135,7 +136,7 @@ void cam_hfi_queue_dump(void)
} }
qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva; 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 header: version=0x%08x tbl_size=%u numq=%u qhdr_size=%u",
qtbl->q_tbl_hdr.qtbl_version, qtbl->q_tbl_hdr.qtbl_version,
qtbl->q_tbl_hdr.qtbl_size, qtbl->q_tbl_hdr.qtbl_size,
@@ -143,7 +144,7 @@ void cam_hfi_queue_dump(void)
qtbl->q_tbl_hdr.qtbl_qhdr_size); qtbl->q_tbl_hdr.qtbl_qhdr_size);
q_hdr = &qtbl->q_hdr[Q_CMD]; 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", "cmd_q: addr=0x%08x size=%u read_idx=%u write_idx=%u",
hfi_mem->cmd_q.iova, hfi_mem->cmd_q.iova,
q_hdr->qhdr_q_size, q_hdr->qhdr_q_size,
@@ -153,10 +154,11 @@ void cam_hfi_queue_dump(void)
dwords = (uint32_t *)hfi_mem->cmd_q.kva; dwords = (uint32_t *)hfi_mem->cmd_q.kva;
num_dwords = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; 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]; 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", "msg_q: addr=0x%08x size=%u read_idx=%u write_idx=%u",
hfi_mem->msg_q.iova, hfi_mem->msg_q.iova,
q_hdr->qhdr_q_size, q_hdr->qhdr_q_size,
@@ -166,7 +168,8 @@ void cam_hfi_queue_dump(void)
dwords = (uint32_t *)hfi_mem->msg_q.kva; dwords = (uint32_t *)hfi_mem->msg_q.kva;
num_dwords = ICP_MSG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; 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 #ifndef CONFIG_CAM_PRESIL

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/slab.h> #include <linux/slab.h>
@@ -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); rc = cam_a5_fw_mini_dump(dump_args, core_info);
break; break;
} }
case CAM_ICP_CMD_HW_REG_DUMP: {
/* reg dump not supported */
break;
}
default: default:
break; break;
} }

View File

@@ -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) 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; 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->hfi_frame_process.in_free_resource[i] = 0;
} }
ctx_data->abort_timed_out = false;
return 0; 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; sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva;
CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg); 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_mgr_ipe_bps_get_gdsc_control(hw_mgr);
cam_icp_ipebps_reset(hw_mgr); cam_icp_ipebps_reset(hw_mgr);
@@ -2639,7 +2654,6 @@ static int cam_icp_mgr_process_fatal_error(
BUG(); BUG();
} }
rc = cam_icp_mgr_trigger_recovery(hw_mgr); rc = cam_icp_mgr_trigger_recovery(hw_mgr);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl);
} }
return rc; return rc;
@@ -3743,8 +3757,8 @@ static int cam_icp_mgr_abort_handle(
CAM_ERR(CAM_ICP, CAM_ERR(CAM_ICP,
"FW timeout/err in abort handle command ctx: %u", "FW timeout/err in abort handle command ctx: %u",
ctx_data->ctx_id); ctx_data->ctx_id);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); cam_icp_dump_debug_info(false);
cam_hfi_queue_dump(); ctx_data->abort_timed_out = true;
} }
} }
@@ -3800,8 +3814,7 @@ static int cam_icp_mgr_destroy_handle(
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
CAM_ERR(CAM_ICP, "FW response timeout: %d for %u", CAM_ERR(CAM_ICP, "FW response timeout: %d for %u",
rc, ctx_data->ctx_id); rc, ctx_data->ctx_id);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); cam_icp_dump_debug_info(ctx_data->abort_timed_out);
cam_hfi_queue_dump();
} }
kfree(destroy_cmd); kfree(destroy_cmd);
return rc; return rc;
@@ -4206,8 +4219,7 @@ static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)
if (!rem_jiffies) { if (!rem_jiffies) {
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
CAM_ERR(CAM_ICP, "FW response timed out %d", rc); CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); cam_icp_dump_debug_info(false);
cam_hfi_queue_dump();
} }
CAM_DBG(CAM_ICP, "Done Waiting for INIT DONE Message"); 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->ctx_id, ctx_data->acquire_dev_cmd.dev_handle,
ctx_data->acquire_dev_cmd.session_handle, ctx_data->acquire_dev_cmd.session_handle,
ctx_data->icp_dev_acquire_info->dev_type); ctx_data->icp_dev_acquire_info->dev_type);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); cam_icp_dump_debug_info(false);
cam_hfi_queue_dump();
} }
return rc; return rc;
@@ -4977,7 +4988,7 @@ static int cam_icp_process_stream_settings(
if (!rem_jiffies) { if (!rem_jiffies) {
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
CAM_ERR(CAM_ICP, "FW response timed out %d", rc); CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
cam_hfi_queue_dump(); cam_icp_dump_debug_info(false);
} }
end: end:
@@ -5750,8 +5761,8 @@ static int cam_icp_mgr_enqueue_abort(
CAM_ERR(CAM_ICP, CAM_ERR(CAM_ICP,
"FW timeout/err in abort handle command ctx: %u", "FW timeout/err in abort handle command ctx: %u",
ctx_data->ctx_id); ctx_data->ctx_id);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); cam_icp_dump_debug_info(false);
cam_hfi_queue_dump(); ctx_data->abort_timed_out = true;
return rc; return rc;
} }
} }
@@ -6078,8 +6089,7 @@ static int cam_icp_mgr_create_handle(uint32_t dev_type,
if (!rem_jiffies) { if (!rem_jiffies) {
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
CAM_ERR(CAM_ICP, "FW response timed out %d", rc); CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); cam_icp_dump_debug_info(false);
cam_hfi_queue_dump();
} }
if (ctx_data->fw_handle == 0) { 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) { if (!rem_jiffies) {
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
CAM_ERR(CAM_ICP, "FW response timed out %d", rc); CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl); cam_icp_dump_debug_info(false);
cam_hfi_queue_dump();
} }
return rc; return rc;

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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 #ifndef CAM_ICP_HW_MGR_H
@@ -270,6 +271,7 @@ struct cam_ctx_clk_info {
* @watch_dog_reset_counter: Counter for watch dog reset * @watch_dog_reset_counter: Counter for watch dog reset
* @icp_dev_io_info: io config resource * @icp_dev_io_info: io config resource
* @last_flush_req: last flush req for this ctx * @last_flush_req: last flush req for this ctx
* @abort_timed_out: Indicates if abort timed out
*/ */
struct cam_icp_hw_ctx_data { struct cam_icp_hw_ctx_data {
void *context_priv; void *context_priv;
@@ -293,6 +295,7 @@ struct cam_icp_hw_ctx_data {
struct cam_icp_acquire_dev_info icp_dev_io_info; struct cam_icp_acquire_dev_info icp_dev_io_info;
uint64_t last_flush_req; uint64_t last_flush_req;
char ctx_id_string[128]; char ctx_id_string[128];
bool abort_timed_out;
}; };
/** /**

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * 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 #ifndef CAM_ICP_HW_INTF_H
@@ -43,6 +44,7 @@ enum cam_icp_cmd_type {
CAM_ICP_CMD_CLK_UPDATE, CAM_ICP_CMD_CLK_UPDATE,
CAM_ICP_CMD_HW_DUMP, CAM_ICP_CMD_HW_DUMP,
CAM_ICP_CMD_HW_MINI_DUMP, CAM_ICP_CMD_HW_MINI_DUMP,
CAM_ICP_CMD_HW_REG_DUMP,
CAM_ICP_CMD_MAX, CAM_ICP_CMD_MAX,
}; };

View File

@@ -27,8 +27,6 @@
#define TZ_STATE_SUSPEND 0 #define TZ_STATE_SUSPEND 0
#define TZ_STATE_RESUME 1 #define TZ_STATE_RESUME 1
#define LX7_GEN_PURPOSE_REG_OFFSET 0x20
#define ICP_FW_NAME_MAX_SIZE 32 #define ICP_FW_NAME_MAX_SIZE 32
#define PC_POLL_DELAY_US 100 #define PC_POLL_DELAY_US 100
@@ -702,6 +700,21 @@ static int cam_lx7_shutdown(struct cam_hw_info *lx7_info)
return rc; 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 */ /* API controls collapse/resume of ICP */
static int cam_lx7_core_control( static int cam_lx7_core_control(
struct cam_hw_info *lx7_info, struct cam_hw_info *lx7_info,
@@ -713,16 +726,12 @@ static int cam_lx7_core_control(
if (core_info->use_sec_pil) { if (core_info->use_sec_pil) {
rc = qcom_scm_set_remote_state(state, CAM_FW_PAS_ID); rc = qcom_scm_set_remote_state(state, CAM_FW_PAS_ID);
if (rc) if (rc) {
CAM_ERR(CAM_ICP, CAM_ERR(CAM_ICP,
"remote state set to %s failed rc=%d IB_status0=0x%x IB_Status1=0x%x PFault=0x%x", "remote state set to %s failed rc=%d",
state == TZ_STATE_RESUME ? "resume" : "suspend", rc, (state == TZ_STATE_RESUME ? "resume" : "suspend"), rc);
cam_io_r_mb(lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base + __cam_lx7_core_reg_dump(lx7_info);
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));
} else { } else {
if (state == TZ_STATE_RESUME) { if (state == TZ_STATE_RESUME) {
rc = __cam_lx7_power_resume(lx7_info); 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); rc = __cam_lx7_fw_mini_dump(lx7_info->core_info, args);
break; break;
} }
case CAM_ICP_CMD_HW_REG_DUMP: {
__cam_lx7_core_reg_dump(lx7_info);
rc = 0;
break;
}
default: default:
CAM_ERR(CAM_ICP, "invalid command type=%u", cmd_type); CAM_ERR(CAM_ICP, "invalid command type=%u", cmd_type);
break; break;

View File

@@ -7,6 +7,11 @@
#ifndef _CAM_LX7_REG_H_ #ifndef _CAM_LX7_REG_H_
#define _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 */ /* ICP_SYS - Protected reg space defined in AC policy */
#define ICP_LX7_SYS_RESET 0x0 #define ICP_LX7_SYS_RESET 0x0
#define ICP_LX7_SYS_CONTROL 0x4 #define ICP_LX7_SYS_CONTROL 0x4