pcie: rockchip: dw: Add debugfs support

Add dump fifo and RASDES Error event count;
Enable all event by default;

Usage:
1. enter /d/fxxx0000.pcie
2. cmd
  cat dumpfifo
  cat err_event
  echo disable > err_event // disable all err event
  echo enable > err_event // enable all err event
  echo clear > err_event // clear all counter

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Change-Id: I3705812bf2bf2c71fb55bf3281854e4619070922
This commit is contained in:
Kever Yang
2022-05-20 18:02:45 +08:00
committed by Tao Huang
parent d9cbb03ca5
commit 648e467e07

View File

@@ -181,6 +181,7 @@ struct rk_pcie {
raw_spinlock_t intx_lock;
u16 aspm;
u32 l1ss_ctl1;
struct dentry *debugfs;
};
struct rk_pcie_of_data {
@@ -708,7 +709,8 @@ static int rk_pcie_link_up(struct dw_pcie *pci)
static void rk_pcie_enable_debug(struct rk_pcie *rk_pcie)
{
#if RK_PCIE_DBG
if (!IS_ENABLED(CONFIG_DEBUG_FS))
return;
if (rk_pcie->is_rk1808 == true)
return;
@@ -722,7 +724,6 @@ static void rk_pcie_enable_debug(struct rk_pcie *rk_pcie)
PCIE_CLIENT_DBG_TRANSITION_DATA);
rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_MODE_CON,
PCIE_CLIENT_DBF_EN);
#endif
}
static void rk_pcie_debug_dump(struct rk_pcie *rk_pcie)
@@ -1765,6 +1766,145 @@ static int rk_pcie_disable_power(struct rk_pcie *rk_pcie)
return ret;
}
#define RAS_DES_EVENT(ss, v) \
do { \
dw_pcie_writel_dbi(pcie->pci, cap_base + 8, v); \
seq_printf(s, ss "0x%x\n", dw_pcie_readl_dbi(pcie->pci, cap_base + 0xc)); \
} while (0)
static int rockchip_pcie_rasdes_show(struct seq_file *s, void *unused)
{
struct rk_pcie *pcie = s->private;
int cap_base;
cap_base = dw_pcie_find_ext_capability(pcie->pci, PCI_EXT_CAP_ID_VNDR);
if (!cap_base) {
dev_err(pcie->pci->dev, "Not able to find RASDES CAP!\n");
return 0;
}
RAS_DES_EVENT("EBUF Overflow: ", 0);
RAS_DES_EVENT("EBUF Under-run: ", 0x0010000);
RAS_DES_EVENT("Decode Error: ", 0x0020000);
RAS_DES_EVENT("Running Disparity Error: ", 0x0030000);
RAS_DES_EVENT("SKP OS Parity Error: ", 0x0040000);
RAS_DES_EVENT("SYNC Header Error: ", 0x0050000);
RAS_DES_EVENT("CTL SKP OS Parity Error: ", 0x0060000);
RAS_DES_EVENT("Detect EI Infer: ", 0x1050000);
RAS_DES_EVENT("Receiver Error: ", 0x1060000);
RAS_DES_EVENT("Rx Recovery Request: ", 0x1070000);
RAS_DES_EVENT("N_FTS Timeout: ", 0x1080000);
RAS_DES_EVENT("Framing Error: ", 0x1090000);
RAS_DES_EVENT("Deskew Error: ", 0x10a0000);
RAS_DES_EVENT("BAD TLP: ", 0x2000000);
RAS_DES_EVENT("LCRC Error: ", 0x2010000);
RAS_DES_EVENT("BAD DLLP: ", 0x2020000);
RAS_DES_EVENT("Replay Number Rollover: ", 0x2030000);
RAS_DES_EVENT("Replay Timeout: ", 0x2040000);
RAS_DES_EVENT("Rx Nak DLLP: ", 0x2050000);
RAS_DES_EVENT("Tx Nak DLLP: ", 0x2060000);
RAS_DES_EVENT("Retry TLP: ", 0x2070000);
RAS_DES_EVENT("FC Timeout: ", 0x3000000);
RAS_DES_EVENT("Poisoned TLP: ", 0x3010000);
RAS_DES_EVENT("ECRC Error: ", 0x3020000);
RAS_DES_EVENT("Unsupported Request: ", 0x3030000);
RAS_DES_EVENT("Completer Abort: ", 0x3040000);
RAS_DES_EVENT("Completion Timeout: ", 0x3050000);
return 0;
}
static int rockchip_pcie_rasdes_open(struct inode *inode, struct file *file)
{
return single_open(file, rockchip_pcie_rasdes_show,
inode->i_private);
}
static ssize_t rockchip_pcie_rasdes_write(struct file *file,
const char __user *ubuf,
size_t count, loff_t *ppos)
{
struct seq_file *s = file->private_data;
struct rk_pcie *pcie = s->private;
char buf[32];
int cap_base;
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;
cap_base = dw_pcie_find_ext_capability(pcie->pci, PCI_EXT_CAP_ID_VNDR);
if (!cap_base) {
dev_err(pcie->pci->dev, "Not able to find RASDES CAP!\n");
return 0;
}
if (!strncmp(buf, "enable", 6)) {
dev_info(pcie->pci->dev, "RAS DES Event: Enable ALL!\n");
dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x1c);
dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x3);
} else if (!strncmp(buf, "disable", 7)) {
dev_info(pcie->pci->dev, "RAS DES Event: disable ALL!\n");
dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x14);
} else if (!strncmp(buf, "clear", 5)) {
dev_info(pcie->pci->dev, "RAS DES Event: Clear ALL!\n");
dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x3);
} else {
dev_info(pcie->pci->dev, "Not support command!\n");
}
return count;
}
static const struct file_operations rockchip_pcie_rasdes_ops = {
.owner = THIS_MODULE,
.open = rockchip_pcie_rasdes_open,
.read = seq_read,
.write = rockchip_pcie_rasdes_write,
};
static int rockchip_pcie_fifo_show(struct seq_file *s, void *data)
{
struct rk_pcie *pcie = (struct rk_pcie *)dev_get_drvdata(s->private);
u32 loop;
seq_printf(s, "ltssm = 0x%x\n",
rk_pcie_readl_apb(pcie, PCIE_CLIENT_LTSSM_STATUS));
for (loop = 0; loop < 64; loop++)
seq_printf(s, "fifo_status = 0x%x\n",
rk_pcie_readl_apb(pcie, PCIE_CLIENT_DBG_FIFO_STATUS));
return 0;
}
static void rockchip_pcie_debugfs_exit(struct rk_pcie *pcie)
{
debugfs_remove_recursive(pcie->debugfs);
pcie->debugfs = NULL;
}
static int rockchip_pcie_debugfs_init(struct rk_pcie *pcie)
{
struct dentry *file;
pcie->debugfs = debugfs_create_dir(dev_name(pcie->pci->dev), NULL);
if (!pcie->debugfs)
return -ENOMEM;
debugfs_create_devm_seqfile(pcie->pci->dev, "dumpfifo",
pcie->debugfs,
rockchip_pcie_fifo_show);
file = debugfs_create_file("err_event", 0644, pcie->debugfs,
pcie, &rockchip_pcie_rasdes_ops);
if (!file)
goto remove;
return 0;
remove:
rockchip_pcie_debugfs_exit(pcie);
return -ENOMEM;
}
static int rk_pcie_really_probe(void *p)
{
struct platform_device *pdev = p;
@@ -1965,6 +2105,22 @@ retry_regulator:
/* Enable async system PM for multiports SoC */
device_enable_async_suspend(dev);
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
ret = rockchip_pcie_debugfs_init(rk_pcie);
if (ret < 0)
dev_err(dev, "failed to setup debugfs: %d\n", ret);
/* Enable RASDES Error event by default */
val = dw_pcie_find_ext_capability(rk_pcie->pci, PCI_EXT_CAP_ID_VNDR);
if (!val) {
dev_err(dev, "Not able to find RASDES CAP!\n");
return 0;
}
dw_pcie_writel_dbi(rk_pcie->pci, val + 8, 0x1c);
dw_pcie_writel_dbi(rk_pcie->pci, val + 8, 0x3);
}
return 0;
remove_irq_domain: