]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: tegra194: Disable LTSSM after transition to Detect on surprise link down
authorManikanta Maddireddy <mmaddireddy@nvidia.com>
Tue, 24 Mar 2026 19:07:44 +0000 (00:37 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 8 Apr 2026 21:56:34 +0000 (16:56 -0500)
After the link reaches a Detect-related LTSSM state, disable LTSSM so it
does not keep toggling between Polling and Detect. Do this by polling for
the Detect state first, then clearing APPL_CTRL_LTSSM_EN in both
tegra_pcie_dw_pme_turnoff() and pex_ep_event_pex_rst_assert().

Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://patch.msgid.link/20260324190755.1094879-4-mmaddireddy@nvidia.com
drivers/pci/controller/dwc/pcie-tegra194.c

index 94113b2e33080fe80d67a1d3eb31ad9030b71c64..b38dbd02214b903c1a4a45c9703d57ff838b5416 100644 (file)
@@ -1594,14 +1594,6 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)
                data &= ~APPL_PINMUX_PEX_RST;
                appl_writel(pcie, data, APPL_PINMUX);
 
-               /*
-                * Some cards do not go to detect state even after de-asserting
-                * PERST#. So, de-assert LTSSM to bring link to detect state.
-                */
-               data = readl(pcie->appl_base + APPL_CTRL);
-               data &= ~APPL_CTRL_LTSSM_EN;
-               writel(data, pcie->appl_base + APPL_CTRL);
-
                err = readl_poll_timeout(pcie->appl_base + APPL_DEBUG, data,
                        ((data & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_QUIET) ||
                        ((data & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_ACT) ||
@@ -1610,6 +1602,14 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)
                        LTSSM_DELAY_US, LTSSM_TIMEOUT_US);
                if (err)
                        dev_info(pcie->dev, "LTSSM state: 0x%x detect timeout: %d\n", data, err);
+
+               /*
+                * Deassert LTSSM state to stop the state toggling between
+                * Polling and Detect.
+                */
+               data = readl(pcie->appl_base + APPL_CTRL);
+               data &= ~APPL_CTRL_LTSSM_EN;
+               writel(data, pcie->appl_base + APPL_CTRL);
        }
        /*
         * DBI registers may not be accessible after this as PLL-E would be
@@ -1683,11 +1683,6 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie)
        if (pcie->ep_state == EP_STATE_DISABLED)
                return;
 
-       /* Disable LTSSM */
-       val = appl_readl(pcie, APPL_CTRL);
-       val &= ~APPL_CTRL_LTSSM_EN;
-       appl_writel(pcie, val, APPL_CTRL);
-
        ret = readl_poll_timeout(pcie->appl_base + APPL_DEBUG, val,
                ((val & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_QUIET) ||
                ((val & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_ACT) ||
@@ -1698,6 +1693,14 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie)
        if (ret)
                dev_info(pcie->dev, "LTSSM state: 0x%x detect timeout: %d\n", val, ret);
 
+       /*
+        * Deassert LTSSM state to stop the state toggling between
+        * Polling and Detect.
+        */
+       val = appl_readl(pcie, APPL_CTRL);
+       val &= ~APPL_CTRL_LTSSM_EN;
+       appl_writel(pcie, val, APPL_CTRL);
+
        reset_control_assert(pcie->core_rst);
 
        tegra_pcie_disable_phy(pcie);