[PATCH 07/11] PCI: tegra194: Always disable Tegra234 Endpoint L1.2

From: Manikanta Maddireddy

Date: Wed Sep 23 2026 - 03:32:30 EST


Tegra234 Endpoint mode must not advertise L1.2 because exiting L1.2 can
bring the link down. That hardware workaround is required regardless of
whether the endpoint kernel is built with CONFIG_PCIEASPM.

Move the L1.2 capability masking out of init_host_aspm(), which is compiled
out when CONFIG_PCIEASPM is disabled, and apply it from the common
initialization paths.

Fixes: f59df1d9e6bd ("PCI: tegra194: Disable L1.2 capability of Tegra234 EP")
Signed-off-by: Manikanta Maddireddy <mmaddireddy@xxxxxxxxxx>
---
drivers/pci/controller/dwc/pcie-tegra194.c | 47 +++++++++++++---------
1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index b35d9456e9de..f8e39459db41 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -611,6 +611,33 @@ static struct pci_ops tegra_pci_ops = {
.write = tegra_pcie_dw_wr_own_conf,
};

+/*
+ * Disable L1.2 capability advertisement for Tegra234 Endpoint mode.
+ * Tegra234 has a hardware bug where during L1.2 exit, the UPHY PLL is
+ * powered up immediately without waiting for REFCLK to stabilize. This causes
+ * the PLL to fail to lock to the correct frequency, resulting in PCIe link
+ * loss. Since there is no hardware fix available, prevent the Endpoint from
+ * advertising L1.2 support so the host will not attempt to enter L1.2 with
+ * this Endpoint.
+ */
+static void tegra_pcie_disable_ep_l1_2(struct tegra_pcie_dw *pcie)
+{
+ struct dw_pcie *pci = &pcie->pci;
+ u32 l1ss, val;
+
+ if (!pcie->of_data->disable_l1_2 ||
+ pcie->of_data->mode != DW_PCIE_EP_TYPE)
+ return;
+
+ l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
+ if (!l1ss)
+ return;
+
+ val = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
+ val &= ~(PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2);
+ dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, val);
+}
+
#if defined(CONFIG_PCIEASPM)
static inline u32 event_counter_prog(struct tegra_pcie_dw *pcie, u32 event)
{
@@ -694,25 +721,6 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)

if (pcie->supports_clkreq)
pci->l1ss_support = true;
-
- /*
- * Disable L1.2 capability advertisement for Tegra234 Endpoint
- * mode. Tegra234 has a hardware bug where during L1.2 exit,
- * the UPHY PLL is powered up immediately without waiting for
- * REFCLK to stabilize. This causes the PLL to fail to lock to
- * the correct frequency, resulting in PCIe link loss. Since
- * there is no hardware fix available, prevent the Endpoint
- * from advertising L1.2 support by clearing the L1.2 bits in
- * the L1 PM Substates Capabilities register. This ensures the
- * host will not attempt to enter L1.2 with this Endpoint.
- */
- if (pcie->of_data->disable_l1_2 &&
- pcie->of_data->mode == DW_PCIE_EP_TYPE) {
- val = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
- val &= ~(PCI_L1SS_CAP_PCIPM_L1_2 |
- PCI_L1SS_CAP_ASPM_L1_2);
- dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, val);
- }
}

/* Program L0s and L1 entrance latencies */
@@ -1903,6 +1911,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
config_gen3_gen4_eq_presets(pcie);

init_host_aspm(pcie);
+ tegra_pcie_disable_ep_l1_2(pcie);

if (!pcie->of_data->has_l1ss_exit_fix) {
val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
--
2.34.1