]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: tegra194: Increase LTSSM poll time on surprise link down
authorManikanta Maddireddy <mmaddireddy@nvidia.com>
Tue, 24 Mar 2026 19:07:43 +0000 (00:37 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 8 Apr 2026 20:33:52 +0000 (15:33 -0500)
On surprise link down, LTSSM state transits from L0 -> Recovery.RcvrLock ->
Recovery.RcvrSpeed -> Gen1 Recovery.RcvrLock -> Detect. Recovery.RcvrLock
and Recovery.RcvrSpeed transit times are 24 ms and 48 ms respectively, so
the total time from L0 to Detect is ~96 ms. Increase the poll timeout to
120 ms to account for this.

While at it, add LTSSM state defines for Detect-related states and use them
in the poll condition. Use readl_poll_timeout() instead of
readl_poll_timeout_atomic() in tegra_pcie_dw_pme_turnoff() since that path
runs in non-atomic context.

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-3-mmaddireddy@nvidia.com
drivers/pci/controller/dwc/pcie-tegra194.c

index 13949f6f7d5be866f4f51e16e8caf61148663df1..94113b2e33080fe80d67a1d3eb31ad9030b71c64 100644 (file)
 #define APPL_DEBUG_PM_LINKST_IN_L0             0x11
 #define APPL_DEBUG_LTSSM_STATE_MASK            GENMASK(8, 3)
 #define APPL_DEBUG_LTSSM_STATE_SHIFT           3
-#define LTSSM_STATE_PRE_DETECT                 5
+#define LTSSM_STATE_DETECT_QUIET               0x00
+#define LTSSM_STATE_DETECT_ACT                 0x08
+#define LTSSM_STATE_PRE_DETECT_QUIET           0x28
+#define LTSSM_STATE_DETECT_WAIT                        0x30
+#define LTSSM_STATE_L2_IDLE                    0xa8
 
 #define APPL_RADM_STATUS                       0xE4
 #define APPL_PM_XMT_TURNOFF_STATE              BIT(0)
 #define CAP_SPCIE_CAP_OFF_USP_TX_PRESET0_MASK  GENMASK(11, 8)
 #define CAP_SPCIE_CAP_OFF_USP_TX_PRESET0_SHIFT 8
 
-#define LTSSM_TIMEOUT 50000    /* 50ms */
+#define LTSSM_DELAY_US         10000   /* 10 ms */
+#define LTSSM_TIMEOUT_US       120000  /* 120 ms */
 
 #define GEN3_GEN4_EQ_PRESET_INIT       5
 
@@ -1597,15 +1602,14 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)
                data &= ~APPL_CTRL_LTSSM_EN;
                writel(data, pcie->appl_base + APPL_CTRL);
 
-               err = readl_poll_timeout_atomic(pcie->appl_base + APPL_DEBUG,
-                                               data,
-                                               ((data &
-                                               APPL_DEBUG_LTSSM_STATE_MASK) >>
-                                               APPL_DEBUG_LTSSM_STATE_SHIFT) ==
-                                               LTSSM_STATE_PRE_DETECT,
-                                               1, LTSSM_TIMEOUT);
+               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) ||
+                       ((data & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_PRE_DETECT_QUIET) ||
+                       ((data & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_WAIT),
+                       LTSSM_DELAY_US, LTSSM_TIMEOUT_US);
                if (err)
-                       dev_info(pcie->dev, "Link didn't go to detect state\n");
+                       dev_info(pcie->dev, "LTSSM state: 0x%x detect timeout: %d\n", data, err);
        }
        /*
         * DBI registers may not be accessible after this as PLL-E would be
@@ -1685,12 +1689,14 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie)
        appl_writel(pcie, val, APPL_CTRL);
 
        ret = readl_poll_timeout(pcie->appl_base + APPL_DEBUG, val,
-                                ((val & APPL_DEBUG_LTSSM_STATE_MASK) >>
-                                APPL_DEBUG_LTSSM_STATE_SHIFT) ==
-                                LTSSM_STATE_PRE_DETECT,
-                                1, LTSSM_TIMEOUT);
+               ((val & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_QUIET) ||
+               ((val & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_ACT) ||
+               ((val & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_PRE_DETECT_QUIET) ||
+               ((val & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_DETECT_WAIT) ||
+               ((val & APPL_DEBUG_LTSSM_STATE_MASK) == LTSSM_STATE_L2_IDLE),
+               LTSSM_DELAY_US, LTSSM_TIMEOUT_US);
        if (ret)
-               dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret);
+               dev_info(pcie->dev, "LTSSM state: 0x%x detect timeout: %d\n", val, ret);
 
        reset_control_assert(pcie->core_rst);