Commit 42123e81 authored by Kai Ye's avatar Kai Ye Committed by Herbert Xu

crypto: hisilicon/hpre - support last word dumping

1. Add some debugging registers.
2. Add last word dumping function during hpre engine controller reset.
Signed-off-by: default avatarKai Ye <yekai13@huawei.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 8a88d091
...@@ -36,6 +36,12 @@ ...@@ -36,6 +36,12 @@
#define HPRE_DATA_WUSER_CFG 0x301040 #define HPRE_DATA_WUSER_CFG 0x301040
#define HPRE_INT_MASK 0x301400 #define HPRE_INT_MASK 0x301400
#define HPRE_INT_STATUS 0x301800 #define HPRE_INT_STATUS 0x301800
#define HPRE_HAC_INT_MSK 0x301400
#define HPRE_HAC_RAS_CE_ENB 0x301410
#define HPRE_HAC_RAS_NFE_ENB 0x301414
#define HPRE_HAC_RAS_FE_ENB 0x301418
#define HPRE_HAC_INT_SET 0x301500
#define HPRE_RNG_TIMEOUT_NUM 0x301A34
#define HPRE_CORE_INT_ENABLE 0 #define HPRE_CORE_INT_ENABLE 0
#define HPRE_CORE_INT_DISABLE GENMASK(21, 0) #define HPRE_CORE_INT_DISABLE GENMASK(21, 0)
#define HPRE_RDCHN_INI_ST 0x301a00 #define HPRE_RDCHN_INI_ST 0x301a00
...@@ -201,28 +207,32 @@ static const u64 hpre_cluster_offsets[] = { ...@@ -201,28 +207,32 @@ static const u64 hpre_cluster_offsets[] = {
}; };
static const struct debugfs_reg32 hpre_cluster_dfx_regs[] = { static const struct debugfs_reg32 hpre_cluster_dfx_regs[] = {
{"CORES_EN_STATUS ", HPRE_CORE_EN_OFFSET}, {"CORES_EN_STATUS ", HPRE_CORE_EN_OFFSET},
{"CORES_INI_CFG ", HPRE_CORE_INI_CFG_OFFSET}, {"CORES_INI_CFG ", HPRE_CORE_INI_CFG_OFFSET},
{"CORES_INI_STATUS ", HPRE_CORE_INI_STATUS_OFFSET}, {"CORES_INI_STATUS ", HPRE_CORE_INI_STATUS_OFFSET},
{"CORES_HTBT_WARN ", HPRE_CORE_HTBT_WARN_OFFSET}, {"CORES_HTBT_WARN ", HPRE_CORE_HTBT_WARN_OFFSET},
{"CORES_IS_SCHD ", HPRE_CORE_IS_SCHD_OFFSET}, {"CORES_IS_SCHD ", HPRE_CORE_IS_SCHD_OFFSET},
}; };
static const struct debugfs_reg32 hpre_com_dfx_regs[] = { static const struct debugfs_reg32 hpre_com_dfx_regs[] = {
{"READ_CLR_EN ", HPRE_CTRL_CNT_CLR_CE}, {"READ_CLR_EN ", HPRE_CTRL_CNT_CLR_CE},
{"AXQOS ", HPRE_VFG_AXQOS}, {"AXQOS ", HPRE_VFG_AXQOS},
{"AWUSR_CFG ", HPRE_AWUSR_FP_CFG}, {"AWUSR_CFG ", HPRE_AWUSR_FP_CFG},
{"QM_ARUSR_MCFG1 ", QM_ARUSER_M_CFG_1}, {"BD_ENDIAN ", HPRE_BD_ENDIAN},
{"QM_AWUSR_MCFG1 ", QM_AWUSER_M_CFG_1}, {"ECC_CHECK_CTRL ", HPRE_ECC_BYPASS},
{"BD_ENDIAN ", HPRE_BD_ENDIAN}, {"RAS_INT_WIDTH ", HPRE_RAS_WIDTH_CFG},
{"ECC_CHECK_CTRL ", HPRE_ECC_BYPASS}, {"POISON_BYPASS ", HPRE_POISON_BYPASS},
{"RAS_INT_WIDTH ", HPRE_RAS_WIDTH_CFG}, {"BD_ARUSER ", HPRE_BD_ARUSR_CFG},
{"POISON_BYPASS ", HPRE_POISON_BYPASS}, {"BD_AWUSER ", HPRE_BD_AWUSR_CFG},
{"BD_ARUSER ", HPRE_BD_ARUSR_CFG}, {"DATA_ARUSER ", HPRE_DATA_RUSER_CFG},
{"BD_AWUSER ", HPRE_BD_AWUSR_CFG}, {"DATA_AWUSER ", HPRE_DATA_WUSER_CFG},
{"DATA_ARUSER ", HPRE_DATA_RUSER_CFG}, {"INT_STATUS ", HPRE_INT_STATUS},
{"DATA_AWUSER ", HPRE_DATA_WUSER_CFG}, {"INT_MASK ", HPRE_HAC_INT_MSK},
{"INT_STATUS ", HPRE_INT_STATUS}, {"RAS_CE_ENB ", HPRE_HAC_RAS_CE_ENB},
{"RAS_NFE_ENB ", HPRE_HAC_RAS_NFE_ENB},
{"RAS_FE_ENB ", HPRE_HAC_RAS_FE_ENB},
{"INT_SET ", HPRE_HAC_INT_SET},
{"RNG_TIMEOUT_NUM ", HPRE_RNG_TIMEOUT_NUM},
}; };
static const char *hpre_dfx_files[HPRE_DFX_FILE_NUM] = { static const char *hpre_dfx_files[HPRE_DFX_FILE_NUM] = {
...@@ -1023,6 +1033,82 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) ...@@ -1023,6 +1033,82 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
return hisi_qm_init(qm); return hisi_qm_init(qm);
} }
static int hpre_show_last_regs_init(struct hisi_qm *qm)
{
int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs);
int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs);
u8 clusters_num = hpre_cluster_num(qm);
struct qm_debug *debug = &qm->debug;
void __iomem *io_base;
int i, j, idx;
debug->last_words = kcalloc(cluster_dfx_regs_num * clusters_num +
com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL);
if (!debug->last_words)
return -ENOMEM;
for (i = 0; i < com_dfx_regs_num; i++)
debug->last_words[i] = readl_relaxed(qm->io_base +
hpre_com_dfx_regs[i].offset);
for (i = 0; i < clusters_num; i++) {
io_base = qm->io_base + hpre_cluster_offsets[i];
for (j = 0; j < cluster_dfx_regs_num; j++) {
idx = com_dfx_regs_num + i * cluster_dfx_regs_num + j;
debug->last_words[idx] = readl_relaxed(
io_base + hpre_cluster_dfx_regs[j].offset);
}
}
return 0;
}
static void hpre_show_last_regs_uninit(struct hisi_qm *qm)
{
struct qm_debug *debug = &qm->debug;
if (qm->fun_type == QM_HW_VF || !debug->last_words)
return;
kfree(debug->last_words);
debug->last_words = NULL;
}
static void hpre_show_last_dfx_regs(struct hisi_qm *qm)
{
int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs);
int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs);
u8 clusters_num = hpre_cluster_num(qm);
struct qm_debug *debug = &qm->debug;
struct pci_dev *pdev = qm->pdev;
void __iomem *io_base;
int i, j, idx;
u32 val;
if (qm->fun_type == QM_HW_VF || !debug->last_words)
return;
/* dumps last word of the debugging registers during controller reset */
for (i = 0; i < com_dfx_regs_num; i++) {
val = readl_relaxed(qm->io_base + hpre_com_dfx_regs[i].offset);
if (debug->last_words[i] != val)
pci_info(pdev, "Common_core:%s \t= 0x%08x => 0x%08x\n",
hpre_com_dfx_regs[i].name, debug->last_words[i], val);
}
for (i = 0; i < clusters_num; i++) {
io_base = qm->io_base + hpre_cluster_offsets[i];
for (j = 0; j < cluster_dfx_regs_num; j++) {
val = readl_relaxed(io_base +
hpre_cluster_dfx_regs[j].offset);
idx = com_dfx_regs_num + i * cluster_dfx_regs_num + j;
if (debug->last_words[idx] != val)
pci_info(pdev, "cluster-%d:%s \t= 0x%08x => 0x%08x\n",
i, hpre_cluster_dfx_regs[j].name, debug->last_words[idx], val);
}
}
}
static void hpre_log_hw_error(struct hisi_qm *qm, u32 err_sts) static void hpre_log_hw_error(struct hisi_qm *qm, u32 err_sts)
{ {
const struct hpre_hw_error *err = hpre_hw_errors; const struct hpre_hw_error *err = hpre_hw_errors;
...@@ -1081,6 +1167,7 @@ static const struct hisi_qm_err_ini hpre_err_ini = { ...@@ -1081,6 +1167,7 @@ static const struct hisi_qm_err_ini hpre_err_ini = {
.open_axi_master_ooo = hpre_open_axi_master_ooo, .open_axi_master_ooo = hpre_open_axi_master_ooo,
.open_sva_prefetch = hpre_open_sva_prefetch, .open_sva_prefetch = hpre_open_sva_prefetch,
.close_sva_prefetch = hpre_close_sva_prefetch, .close_sva_prefetch = hpre_close_sva_prefetch,
.show_last_dfx_regs = hpre_show_last_dfx_regs,
.err_info_init = hpre_err_info_init, .err_info_init = hpre_err_info_init,
}; };
...@@ -1098,8 +1185,11 @@ static int hpre_pf_probe_init(struct hpre *hpre) ...@@ -1098,8 +1185,11 @@ static int hpre_pf_probe_init(struct hpre *hpre)
qm->err_ini = &hpre_err_ini; qm->err_ini = &hpre_err_ini;
qm->err_ini->err_info_init(qm); qm->err_ini->err_info_init(qm);
hisi_qm_dev_err_init(qm); hisi_qm_dev_err_init(qm);
ret = hpre_show_last_regs_init(qm);
if (ret)
pci_err(qm->pdev, "Failed to init last word regs!\n");
return 0; return ret;
} }
static int hpre_probe_init(struct hpre *hpre) static int hpre_probe_init(struct hpre *hpre)
...@@ -1185,6 +1275,7 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1185,6 +1275,7 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hisi_qm_stop(qm, QM_NORMAL); hisi_qm_stop(qm, QM_NORMAL);
err_with_err_init: err_with_err_init:
hpre_show_last_regs_uninit(qm);
hisi_qm_dev_err_uninit(qm); hisi_qm_dev_err_uninit(qm);
err_with_qm_init: err_with_qm_init:
...@@ -1215,6 +1306,7 @@ static void hpre_remove(struct pci_dev *pdev) ...@@ -1215,6 +1306,7 @@ static void hpre_remove(struct pci_dev *pdev)
if (qm->fun_type == QM_HW_PF) { if (qm->fun_type == QM_HW_PF) {
hpre_cnt_regs_clear(qm); hpre_cnt_regs_clear(qm);
qm->debug.curr_qm_qp_num = 0; qm->debug.curr_qm_qp_num = 0;
hpre_show_last_regs_uninit(qm);
hisi_qm_dev_err_uninit(qm); hisi_qm_dev_err_uninit(qm);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment