RE: [PATCH v6 3/3] PCI: cadence: Add LGA IP debugfs for LTSSM status

From: Manikandan Karunakaran Pillai

Date: Tue May 19 2026 - 22:37:25 EST


>EXTERNAL MAIL
>
>
>Extend debugfs support to LGA-based Cadence PCIe controllers. The
>'ltssm_status' file now works for both HPA and LGA IP by selecting the
>appropriate register access based on the 'is_hpa' flag.
>
>Signed-off-by: Hans Zhang <18255117159@xxxxxxx>
>---
> .../controller/cadence/pcie-cadence-debugfs.c | 61 ++++++++++++++++++-
> .../pci/controller/cadence/pcie-cadence-ep.c | 3 +
> .../controller/cadence/pcie-cadence-host.c | 9 ++-
> drivers/pci/controller/cadence/pcie-cadence.h | 43 +++++++++++++
> 4 files changed, 112 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/pci/controller/cadence/pcie-cadence-debugfs.c
>b/drivers/pci/controller/cadence/pcie-cadence-debugfs.c
>index 97c5deef2b1a..0a308f95e9f6 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence-debugfs.c
>+++ b/drivers/pci/controller/cadence/pcie-cadence-debugfs.c
>@@ -13,6 +13,58 @@
>
> #define CDNS_DEBUGFS_BUF_MAX 128

Where is CDNS_DEBUGFS_BUF_MAX used for ?

>
>+static const char *cdns_pcie_lga_ltssm_status_string(enum
>cdns_pcie_lga_ltssm ltssm)
>+{
>+ const char *str;
>+
>+ switch (ltssm) {
>+#define CDNS_PCIE_LGA_LTSSM_NAME(n) case n: str = #n; break
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_DETECT_QUI
>ET);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_DETECT_ACTI
>VE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_POLLING_AC
>TIVE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_POLLING_CO
>MPLIANCE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_POLLING_CO
>NFIGURATION);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_CONFIGURAT
>ION_LINKWIDTH_START);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_CONFIGURAT
>ION_LINKWIDTH_ACCEPT);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_CONFIGURAT
>ION_LANENUM_ACCEPT);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_CONFIGURAT
>ION_LANENUM_WAIT);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_CONFIGURAT
>ION_COMPLETE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_CONFIGURAT
>ION_IDLE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_R
>CVRLOCK);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_S
>PEED);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_R
>CVRCFG);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_I
>DLE);
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_L0);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RX_L0S_ENTR
>Y);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RX_L0S_IDLE)
>;
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RX_L0S_FTS);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_TX_L0S_ENTR
>Y);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_TX_L0S_IDLE)
>;
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_TX_L0S_FTS);
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_L1_ENTRY);
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_L1_IDLE);
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_L2_IDLE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_L2_TRANSMI
>TWAKE);
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_DISABLED);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_LOOPBACK_E
>NTRY_MASTER);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_LOOPBACK_A
>CTIVE_MASTER);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_LOOPBACK_E
>XIT_MASTER);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_LOOPBACK_E
>NTRY_SLAVE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_LOOPBACK_A
>CTIVE_SLAVE);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_LOOPBACK_E
>XIT_SLAVE);
>+ CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_HOT_RESET);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_E
>QUALIZATION_PHASE_0);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_E
>QUALIZATION_PHASE_1);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_E
>QUALIZATION_PHASE_2);
>+
> CDNS_PCIE_LGA_LTSSM_NAME(CDNS_PCIE_LGA_LTSSM_RECOVERY_E
>QUALIZATION_PHASE_3);
>+ default:
>+ str = "CDNS_PCIE_LGA_LTSSM_UNKNOWN";
>+ break;
>+ }
>+
>+ return str + strlen("CDNS_PCIE_LGA_LTSSM_");
>+}
>+
> static const char *cdns_pcie_hpa_ltssm_status_string(enum
>cdns_pcie_hpa_ltssm ltssm)
> {
> const char *str;
>@@ -158,6 +210,7 @@ static const char
>*cdns_pcie_hpa_ltssm_status_string(enum cdns_pcie_hpa_ltssm lt
> static int ltssm_status_show(struct seq_file *s, void *v)
> {
> struct cdns_pcie *pci = s->private;
>+ enum cdns_pcie_lga_ltssm lga_ltssm;
> enum cdns_pcie_hpa_ltssm hpa_ltssm;
> const char *str_ltssm;
> u32 val;
>@@ -168,11 +221,13 @@ static int ltssm_status_show(struct seq_file *s, void
>*v)
> hpa_ltssm =
>FIELD_GET(CDNS_PCIE_HPA_LTSSM_STATUS_MASK, val);
> str_ltssm = cdns_pcie_hpa_ltssm_status_string(hpa_ltssm);
> } else {
>- /* TODO: LGA IP*/
>- return 0;
>+ val = cdns_pcie_readl(pci, CDNS_PCIE_LM_BASE);
>+ lga_ltssm =
>FIELD_GET(CDNS_PCIE_LGA_LTSSM_STATUS_MASK, val);
>+ str_ltssm = cdns_pcie_lga_ltssm_status_string(lga_ltssm);
> }
>
>- seq_printf(s, "%s (0x%02x)\n", str_ltssm, hpa_ltssm);
>+ seq_printf(s, "%s (0x%02x)\n", str_ltssm,
>+ pci->is_hpa ? hpa_ltssm : lga_ltssm);
>
> return 0;
> }
>diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c
>b/drivers/pci/controller/cadence/pcie-cadence-ep.c
>index c0e1194a936b..370b19f4d38f 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
>+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
>@@ -655,6 +655,7 @@ void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep)
> struct device *dev = ep->pcie.dev;
> struct pci_epc *epc = to_pci_epc(dev);
>
>+ cdns_pcie_debugfs_deinit(&ep->pcie);
> pci_epc_deinit_notify(epc);
> pci_epc_mem_free_addr(epc, ep->irq_phys_addr, ep->irq_cpu_addr,
> SZ_128K);
>@@ -761,6 +762,8 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>
> pci_epc_init_notify(epc);
>
>+ cdns_pcie_debugfs_init(pcie);
>+
> return 0;
>
> free_epc_mem:
>diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c
>b/drivers/pci/controller/cadence/pcie-cadence-host.c
>index 0bc9e6e90e0e..8105bb625eb7 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
>+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
>@@ -364,6 +364,7 @@ void cdns_pcie_host_disable(struct cdns_pcie_rc *rc)
> {
> struct pci_host_bridge *bridge;
>
>+ cdns_pcie_debugfs_deinit(&rc->pcie);
> bridge = pci_host_bridge_from_priv(rc);
> pci_stop_root_bus(bridge->bus);
> pci_remove_root_bus(bridge->bus);
>@@ -423,7 +424,13 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
> if (!bridge->ops)
> bridge->ops = &cdns_pcie_host_ops;
>
>- return pci_host_probe(bridge);
>+ ret = pci_host_probe(bridge);
>+ if (ret)
>+ return ret;
>+
>+ cdns_pcie_debugfs_init(pcie);
>+
>+ return 0;
> }
> EXPORT_SYMBOL_GPL(cdns_pcie_host_setup);
>
>diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
>b/drivers/pci/controller/cadence/pcie-cadence.h
>index 2320319af83b..8bc6564c65b9 100644
>--- a/drivers/pci/controller/cadence/pcie-cadence.h
>+++ b/drivers/pci/controller/cadence/pcie-cadence.h
>@@ -14,6 +14,7 @@
> #include "pcie-cadence-lga-regs.h"
> #include "pcie-cadence-hpa-regs.h"
>
>+#define CDNS_PCIE_LGA_LTSSM_STATUS_MASK GENMASK(29, 24)
> #define CDNS_PCIE_HPA_LTSSM_STATUS_MASK GENMASK(27, 20)
>
> enum cdns_pcie_rp_bar {
>@@ -44,6 +45,48 @@ enum cdns_pcie_reg_bank {
> REG_BANKS_MAX,
> };
>
>+enum cdns_pcie_lga_ltssm {
>+ CDNS_PCIE_LGA_LTSSM_DETECT_QUIET = 0x00,
>+ CDNS_PCIE_LGA_LTSSM_DETECT_ACTIVE = 0x01,
>+ CDNS_PCIE_LGA_LTSSM_POLLING_ACTIVE = 0x02,
>+ CDNS_PCIE_LGA_LTSSM_POLLING_COMPLIANCE
> = 0x03,
>+ CDNS_PCIE_LGA_LTSSM_POLLING_CONFIGURATION = 0x04,
>+ CDNS_PCIE_LGA_LTSSM_CONFIGURATION_LINKWIDTH_START = 0x05,
>+ CDNS_PCIE_LGA_LTSSM_CONFIGURATION_LINKWIDTH_ACCEPT
> = 0x06,
>+ CDNS_PCIE_LGA_LTSSM_CONFIGURATION_LANENUM_ACCEPT = 0x07,
>+ CDNS_PCIE_LGA_LTSSM_CONFIGURATION_LANENUM_WAIT
> = 0x08,
>+ CDNS_PCIE_LGA_LTSSM_CONFIGURATION_COMPLETE = 0x09,
>+ CDNS_PCIE_LGA_LTSSM_CONFIGURATION_IDLE
> = 0x0A,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_RCVRLOCK = 0x0B,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_SPEED = 0x0C,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_RCVRCFG = 0x0D,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_IDLE = 0x0E,
>+ CDNS_PCIE_LGA_LTSSM_L0 = 0x10,
>+ CDNS_PCIE_LGA_LTSSM_RX_L0S_ENTRY = 0x11,
>+ CDNS_PCIE_LGA_LTSSM_RX_L0S_IDLE = 0x12,
>+ CDNS_PCIE_LGA_LTSSM_RX_L0S_FTS = 0x13,
>+ CDNS_PCIE_LGA_LTSSM_TX_L0S_ENTRY = 0x14,
>+ CDNS_PCIE_LGA_LTSSM_TX_L0S_IDLE = 0x15,
>+ CDNS_PCIE_LGA_LTSSM_TX_L0S_FTS = 0x16,
>+ CDNS_PCIE_LGA_LTSSM_L1_ENTRY = 0x17,
>+ CDNS_PCIE_LGA_LTSSM_L1_IDLE = 0x18,
>+ CDNS_PCIE_LGA_LTSSM_L2_IDLE = 0x19,
>+ CDNS_PCIE_LGA_LTSSM_L2_TRANSMITWAKE = 0x1A,
>+ CDNS_PCIE_LGA_LTSSM_DISABLED = 0x20,
>+ CDNS_PCIE_LGA_LTSSM_LOOPBACK_ENTRY_MASTER = 0x21,
>+ CDNS_PCIE_LGA_LTSSM_LOOPBACK_ACTIVE_MASTER = 0x22,
>+ CDNS_PCIE_LGA_LTSSM_LOOPBACK_EXIT_MASTER = 0x23,
>+ CDNS_PCIE_LGA_LTSSM_LOOPBACK_ENTRY_SLAVE = 0x24,
>+ CDNS_PCIE_LGA_LTSSM_LOOPBACK_ACTIVE_SLAVE = 0x25,
>+ CDNS_PCIE_LGA_LTSSM_LOOPBACK_EXIT_SLAVE
> = 0x26,
>+ CDNS_PCIE_LGA_LTSSM_HOT_RESET = 0x27,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_EQUALIZATION_PHASE_0 = 0x28,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_EQUALIZATION_PHASE_1 = 0x29,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_EQUALIZATION_PHASE_2 = 0x2A,
>+ CDNS_PCIE_LGA_LTSSM_RECOVERY_EQUALIZATION_PHASE_3 = 0x2B,
>+ CDNS_PCIE_LGA_LTSSM_UNKNOWN =
>0xFFFFFFFF,
>+};
>+
> enum cdns_pcie_hpa_ltssm {
> CDNS_PCIE_HPA_LTSSM_DETECT_QUIET = 0,
> CDNS_PCIE_HPA_LTSSM_DETECT_QUIET_ENTRY = 1,
>--
>2.43.0