Re: [PATCH v4 2/2] PCI: cadence: Add debugfs property to provide LTSSM status of the PCIe link

From: Hans Zhang

Date: Wed May 13 2026 - 02:42:12 EST




On 5/13/26 14:11, Manikandan Karunakaran Pillai wrote:
On 08/05/26 09:11, Hans Zhang wrote:
Add the debugfs property to provide a view of the current link's LTSSM
status from the Root Port device.

Test example:
# cat /sys/kernel/debug/cdns_pcie_a0c0000.pcie/ltssm_status
L0_STATE (0x29)

Signed-off-by: Hans Zhang <18255117159@xxxxxxx>
---
Documentation/ABI/testing/debugfs-cdns-pcie | 5 +
drivers/pci/controller/cadence/Kconfig | 9 +
drivers/pci/controller/cadence/Makefile | 1 +
drivers/pci/controller/cadence/pci-sky1.c | 3 +
.../controller/cadence/pcie-cadence-debugfs.c | 208 ++++++++++++++++++
.../pci/controller/cadence/pcie-cadence-ep.c | 3 +
.../cadence/pcie-cadence-host-hpa.c | 20 +-
.../controller/cadence/pcie-cadence-host.c | 9 +-
drivers/pci/controller/cadence/pcie-cadence.h | 150 +++++++++++++
9 files changed, 406 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ABI/testing/debugfs-cdns-pcie
create mode 100644 drivers/pci/controller/cadence/pcie-cadence-debugfs.c

diff --git a/Documentation/ABI/testing/debugfs-cdns-pcie
b/Documentation/ABI/testing/debugfs-cdns-pcie
new file mode 100644
index 000000000000..659ad2ab70e4
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-cdns-pcie
@@ -0,0 +1,5 @@
+What: /sys/kernel/debug/cdns_pcie_<dev>/ltssm_status
+Date: March 2026
+Contact: Hans Zhang <18255117159@xxxxxxx>
+Description: (RO) Read will return the current PCIe LTSSM state in both
+ string and raw value.
diff --git a/drivers/pci/controller/cadence/Kconfig
b/drivers/pci/controller/cadence/Kconfig
index 9e651d545973..cb010bc97aad 100644
--- a/drivers/pci/controller/cadence/Kconfig
+++ b/drivers/pci/controller/cadence/Kconfig
@@ -6,6 +6,15 @@ menu "Cadence-based PCIe controllers"
config PCIE_CADENCE
tristate

+config PCIE_CADENCE_DEBUGFS
+ tristate "Cadence PCIe debugfs entries"
+ depends on DEBUG_FS
+ depends on PCIE_CADENCE_HOST || PCIE_CADENCE_EP
+ help
+ Say Y here to enable debugfs entries for the PCIe controller. These
+ entries provide various debug features related to the controller and
+ the LTSSM status of link can be displayed.
+
config PCIE_CADENCE_HOST
tristate
depends on OF

[...]


diff --git a/drivers/pci/controller/cadence/pcie-cadence.h
b/drivers/pci/controller/cadence/pcie-cadence.h
index 9a464cbaf073..a1c531fd2061 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -42,6 +42,137 @@ enum cdns_pcie_reg_bank {
REG_BANKS_MAX,
};

+enum cdns_pcie_ltssm {
+ CDNS_PCIE_LTSSM_DETECT_QUIET = 0,
+ CDNS_PCIE_LTSSM_DETECT_QUIET_ENTRY = 1,
+ CDNS_PCIE_LTSSM_DETECT_ACTIVE = 2,
+ CDNS_PCIE_LTSSM_DETECT_ACTIVE_1 = 3,
+ CDNS_PCIE_LTSSM_DETECT_ACTIVE_2 = 4,
+ CDNS_PCIE_LTSSM_DETECT_ACTIVE_3 = 5,
+ CDNS_PCIE_LTSSM_RCVR_DETECTED_ST = 6,
+ CDNS_PCIE_LTSSM_RCVR_DETECTED_1 = 7,
+ CDNS_PCIE_LTSSM_POLLING_ACTIVE = 8,
+ CDNS_PCIE_LTSSM_POLLING_ACTIVE_1 = 9,
+ CDNS_PCIE_LTSSM_POLLING_ACTIVE_2 = 10,
+ CDNS_PCIE_LTSSM_POLLING_ACTIVE_3 = 11,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE = 12,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_1 = 13,
+ CDNS_PCIE_LTSSM_POLLING_CONFIG = 14,
+ CDNS_PCIE_LTSSM_POLLING_CONFIG_1 = 15,
+ CDNS_PCIE_LTSSM_POLLING_CONFIG_2 = 16,
+ CDNS_PCIE_LTSSM_CONFIG_LW_START_RC = 17,
+ CDNS_PCIE_LTSSM_CONFIG_LW_START_RC_1 = 18,
+ CDNS_PCIE_LTSSM_CONFIG_LW_START_RC_2 = 19,
+ CDNS_PCIE_LTSSM_CONFIG_LW_ACC_RC = 20,
+ CDNS_PCIE_LTSSM_CONFIG_LANENUM_WAIT_RC = 21,
+ CDNS_PCIE_LTSSM_CONFIG_LANENUM_WAIT_RC_1 = 22,
+ CDNS_PCIE_LTSSM_CONFIG_LANENUM_ACC_RC = 23,
+ CDNS_PCIE_LTSSM_CONFIG_LW_START_EP = 24,
+ CDNS_PCIE_LTSSM_CONFIG_LW_START_EP_1 = 25,
+ CDNS_PCIE_LTSSM_CONFIG_LW_START_EP_2 = 26,
+ CDNS_PCIE_LTSSM_CONFIG_LW_ACC_EP = 27,
+ CDNS_PCIE_LTSSM_CONFIG_LANENUM_WAIT_EP = 28,
+ CDNS_PCIE_LTSSM_CONFIG_LANENUM_WAIT_EP_1 = 29,
+ CDNS_PCIE_LTSSM_CONFIG_LANENUM_ACC_EP = 30,
+ CDNS_PCIE_LTSSM_CONFIG_LANENUM_ACC_EP_1 = 31,
+ CDNS_PCIE_LTSSM_DUMMY_STATE_1 = 32,
+ CDNS_PCIE_LTSSM_CONFIG_COMPLETE = 33,
+ CDNS_PCIE_LTSSM_CONFIG_COMPLETE_1 = 34,
+ CDNS_PCIE_LTSSM_CONFIG_COMPLETE_2 = 35,
+ CDNS_PCIE_LTSSM_CONFIG_IDLE = 36,
+ CDNS_PCIE_LTSSM_CONFIG_IDLE_1 = 37,
+ CDNS_PCIE_LTSSM_DUMMY_STATE_2 = 38,
+ CDNS_PCIE_LTSSM_DUMMY_STATE_3 = 39,
+ CDNS_PCIE_LTSSM_DUMMY_STATE_4 = 40,
+ CDNS_PCIE_LTSSM_L0_STATE = 41,
+ CDNS_PCIE_LTSSM_RECOVERY_RCVR_LOCK = 42,
+ CDNS_PCIE_LTSSM_RECOVERY_RCVR_LOCK_1 = 43,
+ CDNS_PCIE_LTSSM_RECOVERY_RCVR_CFG = 44,
+ CDNS_PCIE_LTSSM_RECOVERY_RCVR_CFG_1 = 45,
+ CDNS_PCIE_LTSSM_RECOVERY_IDLE = 46,
+ CDNS_PCIE_LTSSM_RECOVERY_IDLE_1 = 47,
+ CDNS_PCIE_LTSSM_DISABLE_LINK = 48,
+ CDNS_PCIE_LTSSM_DISABLE_LINK_1 = 49,
+ CDNS_PCIE_LTSSM_DISABLE_LINK_2 = 50,
+ CDNS_PCIE_LTSSM_DISABLE_LINK_3 = 51,
+ CDNS_PCIE_LTSSM_DISABLE_LINK_4 = 52,
+ CDNS_PCIE_LTSSM_DISABLE_LINK_5 = 53,
+ CDNS_PCIE_LTSSM_DISABLE_LINK_6 = 54,
+ CDNS_PCIE_LTSSM_DISABLE_LINK_7 = 55,
+ CDNS_PCIE_LTSSM_HOT_RESET = 56,
+ CDNS_PCIE_LTSSM_HOT_RESET_1 = 57,
+ CDNS_PCIE_LTSSM_HOT_RESET_2 = 58,
+ CDNS_PCIE_LTSSM_HOT_RESET_3 = 59,
+ CDNS_PCIE_LTSSM_L0S_ENTRY = 60,
+ CDNS_PCIE_LTSSM_L0S_1 = 61,
+ CDNS_PCIE_LTSSM_L0S_2 = 62,
+ CDNS_PCIE_LTSSM_L0S_3 = 63,
+ CDNS_PCIE_LTSSM_L0S_4 = 64,
+ CDNS_PCIE_LTSSM_L0S_5 = 65,
+ CDNS_PCIE_LTSSM_WAIT_FOR_LINK_TX = 66,
+ CDNS_PCIE_LTSSM_TX_FTS_ENTRY = 67,
+ CDNS_PCIE_LTSSM_TX_FTS_1 = 68,
+ CDNS_PCIE_LTSSM_TX_FTS_2 = 69,
+ CDNS_PCIE_LTSSM_TX_ELEC_IDLE_ST = 70,
+ CDNS_PCIE_LTSSM_TX_ELEC_IDLE_1 = 71,
+ CDNS_PCIE_LTSSM_TX_ELEC_IDLE_2 = 72,
+ CDNS_PCIE_LTSSM_TX_ELEC_IDLE_3 = 73,
+ CDNS_PCIE_LTSSM_RECOVERY_SPEED = 74,
+ CDNS_PCIE_LTSSM_RECOVERY_SPEED_1 = 75,
+ CDNS_PCIE_LTSSM_RECOVERY_SPEED_2 = 76,
+ CDNS_PCIE_LTSSM_RECOVERY_SPEED_3 = 77,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23 = 78,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_1 = 79,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_2 = 80,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_3 = 81,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_4 = 82,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_5 = 83,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_6 = 84,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_7 = 85,
+ CDNS_PCIE_LTSSM_POLLING_COMPLIANCE_GEN23_8 = 86,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_ENTRY = 87,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_ENTRY_FROM_RECOVERY = 88,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_EXIT_1 = 89,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_EXIT = 90,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_GEN2_1 = 91,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_GEN2_2 = 92,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_GEN2_3 = 93,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_GEN2_4 = 94,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_GEN2_5 = 95,
+ CDNS_PCIE_LTSSM_LOOPBACK_SLAVE_ACTIVE = 96,
+ CDNS_PCIE_LTSSM_L1_ENTRY = 97,
+ CDNS_PCIE_LTSSM_L1_1 = 98,
+ CDNS_PCIE_LTSSM_L1_2 = 99,
+ CDNS_PCIE_LTSSM_L1_3 = 100,
+ CDNS_PCIE_LTSSM_L1_4 = 101,
+ CDNS_PCIE_LTSSM_L1_IDLE = 102,
+ CDNS_PCIE_LTSSM_L1_EXIT = 103,
+ CDNS_PCIE_LTSSM_L2_ENTRY = 104,
+ CDNS_PCIE_LTSSM_L2_1 = 105,
+ CDNS_PCIE_LTSSM_L2_2 = 106,
+ CDNS_PCIE_LTSSM_L2_3 = 107,
+ CDNS_PCIE_LTSSM_L2_4 = 108,
+ CDNS_PCIE_LTSSM_L2_5 = 109,
+ CDNS_PCIE_LTSSM_L2_IDLE = 110,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ENTRY = 111,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ENTRY_1 = 112,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ENTRY_2 = 113,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ENTRY_3 = 114,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ENTRY_4 = 115,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ENTRY_5 = 116,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ENTRY_FROM_RECOVERY =
117,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_ACTIVE = 118,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_EXIT = 119,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_EXIT_1 = 120,
+ CDNS_PCIE_LTSSM_LOOPBACK_MASTER_EXIT_2 = 121,
+ CDNS_PCIE_LTSSM_RECOVERY_EQUALIZATION_PHASE0 = 122,
+ CDNS_PCIE_LTSSM_RECOVERY_EQUALIZATION_PHASE1 = 123,
+ CDNS_PCIE_LTSSM_RECOVERY_EQUALIZATION_PHASE2_1 = 124,
+ CDNS_PCIE_LTSSM_RECOVERY_EQUALIZATION_PHASE2_2 = 125,
+ CDNS_PCIE_LTSSM_RECOVERY_EQUALIZATION_PHASE3_1 = 126,
+ CDNS_PCIE_LTSSM_RECOVERY_EQUALIZATION_PHASE3_2 = 127,
+};


The above LTSSM states are internal LTSSM encoding states and may not be available for software to use.
The LTSSM states in the document pointed by Aksh (TI Soc) are the states available in all cadence controllers.

Hi Manikandan,

For LGA IP, can't the registers be read out through the common registers of Cadence IP? Just like the approach of DWC. And the HPA IP is readable.


Best regards,
Hans


Hi Hans,

The LTSSM state encoding in your patches do not align with the state
encodings for LGA IP. TI SoCs have LGA IP of Cadence PCIe, and when I
applied your patches, the LTSSM value in the debugfs for the PCIe
subsystem (which have an EP connected to it) came out to be 0x10, which
points to the state "PCIE_L0". However, the debugfs prints the state as
"POLLING_CONFIG_2 (0x10)", which seems to be incorrect.

The LTSSM state encodings for TI SoCs using Cadence PCIe IP is provided
in the J7200 TRM section 12.2.3.4.14 at:
https://urldefense.com/v3/__https://www.ti.com/lit/pdf/spruiu1__;!!EHscmS1
ygiU1lA!AudWpZJoYT3_nfvc33jiZrUFh75KB4DU-
na_9SNZTib3etI9BNC3Jq8RlPxVouCPY2Rt7SyqrNI$

Regards,
Aksh Garg


+
struct cdns_pcie_ops {