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
父節點 d557934178
當前提交 1df78bed63
共有 8 個文件被更改,包括 78 次插入34 次删除

查看文件

@@ -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

查看文件

@@ -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 <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;
}
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;
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,6 +168,7 @@ 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;
if (dump_queue_data)
hfi_queue_dump(dwords, num_dwords);
}

查看文件

@@ -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 <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);
break;
}
case CAM_ICP_CMD_HW_REG_DUMP: {
/* reg dump not supported */
break;
}
default:
break;
}

查看文件

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

查看文件

@@ -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;
};
/**

查看文件

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

查看文件

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

查看文件

@@ -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