Skip to content

Commit f0f3044

Browse files
Hans Zhangkwilczynski
authored andcommitted
PCI: dwc: Add debugfs property to provide LTSSM status of the PCIe link
Add the debugfs property to provide a view of the current link's LTSSM status from the Root Port device. Signed-off-by: Hans Zhang <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Tested-by: Niklas Cassel <[email protected]> Tested-by: Hrishikesh Deleep <[email protected]> Link: https://lore.kernel.org/r/[email protected] [kwilczynski: commit log, refactor dw_ltssm_sts_string() to avoid compilation errors on platforms that do not set CONFIG_PCIE_DW_HOST] Signed-off-by: Krzysztof Wilczyński <[email protected]>
1 parent 27491ac commit f0f3044

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

Documentation/ABI/testing/debugfs-dwc-pcie

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,9 @@ Description: (RW) Some lanes in the event list are lane specific events.
149149
the lane number for which you wish the counter to be enabled,
150150
disabled, or value dumped. Read will return the current
151151
selected lane number. Lane0 is selected by default.
152+
153+
What: /sys/kernel/debug/dwc_pcie_<dev>/ltssm_status
154+
Date: February 2025
155+
Contact: Hans Zhang <[email protected]>
156+
Description: (RO) Read will return the current PCIe LTSSM state in both
157+
string and raw value.

drivers/pci/controller/dwc/pcie-designware-debugfs.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,72 @@ static ssize_t counter_value_read(struct file *file, char __user *buf,
443443
return simple_read_from_buffer(buf, count, ppos, debugfs_buf, pos);
444444
}
445445

446+
static const char *ltssm_status_string(enum dw_pcie_ltssm ltssm)
447+
{
448+
const char *str;
449+
450+
switch (ltssm) {
451+
#define DW_PCIE_LTSSM_NAME(n) case n: str = #n; break
452+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_QUIET);
453+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_ACT);
454+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_ACTIVE);
455+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_COMPLIANCE);
456+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_POLL_CONFIG);
457+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_PRE_DETECT_QUIET);
458+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DETECT_WAIT);
459+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LINKWD_START);
460+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LINKWD_ACEPT);
461+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LANENUM_WAI);
462+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_LANENUM_ACEPT);
463+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_COMPLETE);
464+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_CFG_IDLE);
465+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_LOCK);
466+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_SPEED);
467+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_RCVRCFG);
468+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_IDLE);
469+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L0);
470+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L0S);
471+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L123_SEND_EIDLE);
472+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_IDLE);
473+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L2_IDLE);
474+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L2_WAKE);
475+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED_ENTRY);
476+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED_IDLE);
477+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_DISABLED);
478+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_ENTRY);
479+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_ACTIVE);
480+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_EXIT);
481+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_LPBK_EXIT_TIMEOUT);
482+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_HOT_RESET_ENTRY);
483+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_HOT_RESET);
484+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ0);
485+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ1);
486+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ2);
487+
DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ3);
488+
default:
489+
str = "DW_PCIE_LTSSM_UNKNOWN";
490+
break;
491+
}
492+
493+
return str + strlen("DW_PCIE_LTSSM_");
494+
}
495+
496+
static int ltssm_status_show(struct seq_file *s, void *v)
497+
{
498+
struct dw_pcie *pci = s->private;
499+
enum dw_pcie_ltssm val;
500+
501+
val = dw_pcie_get_ltssm(pci);
502+
seq_printf(s, "%s (0x%02x)\n", ltssm_status_string(val), val);
503+
504+
return 0;
505+
}
506+
507+
static int ltssm_status_open(struct inode *inode, struct file *file)
508+
{
509+
return single_open(file, ltssm_status_show, inode->i_private);
510+
}
511+
446512
#define dwc_debugfs_create(name) \
447513
debugfs_create_file(#name, 0644, rasdes_debug, pci, \
448514
&dbg_ ## name ## _fops)
@@ -479,6 +545,11 @@ static const struct file_operations dwc_pcie_counter_value_ops = {
479545
.read = counter_value_read,
480546
};
481547

548+
static const struct file_operations dwc_pcie_ltssm_status_ops = {
549+
.open = ltssm_status_open,
550+
.read = seq_read,
551+
};
552+
482553
static void dwc_pcie_rasdes_debugfs_deinit(struct dw_pcie *pci)
483554
{
484555
struct dwc_pcie_rasdes_info *rinfo = pci->debugfs->rasdes_info;
@@ -565,6 +636,12 @@ static int dwc_pcie_rasdes_debugfs_init(struct dw_pcie *pci, struct dentry *dir)
565636
return ret;
566637
}
567638

639+
static void dwc_pcie_ltssm_debugfs_init(struct dw_pcie *pci, struct dentry *dir)
640+
{
641+
debugfs_create_file("ltssm_status", 0444, dir, pci,
642+
&dwc_pcie_ltssm_status_ops);
643+
}
644+
568645
void dwc_pcie_debugfs_deinit(struct dw_pcie *pci)
569646
{
570647
if (!pci->debugfs)
@@ -595,4 +672,6 @@ void dwc_pcie_debugfs_init(struct dw_pcie *pci)
595672
if (err)
596673
dev_err(dev, "failed to initialize RAS DES debugfs, err=%d\n",
597674
err);
675+
676+
dwc_pcie_ltssm_debugfs_init(pci, dir);
598677
}

drivers/pci/controller/dwc/pcie-designware.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,40 @@ enum dw_pcie_ltssm {
330330
/* Need to align with PCIE_PORT_DEBUG0 bits 0:5 */
331331
DW_PCIE_LTSSM_DETECT_QUIET = 0x0,
332332
DW_PCIE_LTSSM_DETECT_ACT = 0x1,
333+
DW_PCIE_LTSSM_POLL_ACTIVE = 0x2,
334+
DW_PCIE_LTSSM_POLL_COMPLIANCE = 0x3,
335+
DW_PCIE_LTSSM_POLL_CONFIG = 0x4,
336+
DW_PCIE_LTSSM_PRE_DETECT_QUIET = 0x5,
333337
DW_PCIE_LTSSM_DETECT_WAIT = 0x6,
338+
DW_PCIE_LTSSM_CFG_LINKWD_START = 0x7,
339+
DW_PCIE_LTSSM_CFG_LINKWD_ACEPT = 0x8,
340+
DW_PCIE_LTSSM_CFG_LANENUM_WAI = 0x9,
341+
DW_PCIE_LTSSM_CFG_LANENUM_ACEPT = 0xa,
342+
DW_PCIE_LTSSM_CFG_COMPLETE = 0xb,
343+
DW_PCIE_LTSSM_CFG_IDLE = 0xc,
344+
DW_PCIE_LTSSM_RCVRY_LOCK = 0xd,
345+
DW_PCIE_LTSSM_RCVRY_SPEED = 0xe,
346+
DW_PCIE_LTSSM_RCVRY_RCVRCFG = 0xf,
347+
DW_PCIE_LTSSM_RCVRY_IDLE = 0x10,
334348
DW_PCIE_LTSSM_L0 = 0x11,
349+
DW_PCIE_LTSSM_L0S = 0x12,
350+
DW_PCIE_LTSSM_L123_SEND_EIDLE = 0x13,
351+
DW_PCIE_LTSSM_L1_IDLE = 0x14,
335352
DW_PCIE_LTSSM_L2_IDLE = 0x15,
353+
DW_PCIE_LTSSM_L2_WAKE = 0x16,
354+
DW_PCIE_LTSSM_DISABLED_ENTRY = 0x17,
355+
DW_PCIE_LTSSM_DISABLED_IDLE = 0x18,
356+
DW_PCIE_LTSSM_DISABLED = 0x19,
357+
DW_PCIE_LTSSM_LPBK_ENTRY = 0x1a,
358+
DW_PCIE_LTSSM_LPBK_ACTIVE = 0x1b,
359+
DW_PCIE_LTSSM_LPBK_EXIT = 0x1c,
360+
DW_PCIE_LTSSM_LPBK_EXIT_TIMEOUT = 0x1d,
361+
DW_PCIE_LTSSM_HOT_RESET_ENTRY = 0x1e,
362+
DW_PCIE_LTSSM_HOT_RESET = 0x1f,
363+
DW_PCIE_LTSSM_RCVRY_EQ0 = 0x20,
364+
DW_PCIE_LTSSM_RCVRY_EQ1 = 0x21,
365+
DW_PCIE_LTSSM_RCVRY_EQ2 = 0x22,
366+
DW_PCIE_LTSSM_RCVRY_EQ3 = 0x23,
336367

337368
DW_PCIE_LTSSM_UNKNOWN = 0xFFFFFFFF,
338369
};

0 commit comments

Comments
 (0)