]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: tegra194: Don't force the device into the D0 state before L2
authorVidya Sagar <vidyas@nvidia.com>
Tue, 24 Mar 2026 19:07:45 +0000 (00:37 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 8 Apr 2026 21:56:44 +0000 (16:56 -0500)
As per PCIe CEM r6.0, sec 2.3, the PCIe Endpoint device should be in D3cold
to assert WAKE# pin. The previous workaround that forced downstream devices
to D0 before taking the link to L2 cited PCIe r4.0, sec 5.2, "Link State
Power Management"; however, that spec does not explicitly require putting
the device into D0 and only indicates that power removal may be initiated
without transitioning to D3hot.

Remove the D0 workaround so that Endpoint devices can use wake
functionality (WAKE# from D3). With some Endpoints the link may not enter
L2 when they remain in D3, but the Root Port continues with the usual flow
after PME timeout, so there is no functional issue.

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: Vidya Sagar <vidyas@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://patch.msgid.link/20260324190755.1094879-5-mmaddireddy@nvidia.com
drivers/pci/controller/dwc/pcie-tegra194.c

index b38dbd02214b903c1a4a45c9703d57ff838b5416..c84eb1ba3a11c43bb740956b01cc3feea67f2331 100644 (file)
@@ -1258,44 +1258,6 @@ static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie,
        return 0;
 }
 
-static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)
-{
-       struct dw_pcie_rp *pp = &pcie->pci.pp;
-       struct pci_bus *child, *root_port_bus = NULL;
-       struct pci_dev *pdev;
-
-       /*
-        * link doesn't go into L2 state with some of the endpoints with Tegra
-        * if they are not in D0 state. So, need to make sure that immediate
-        * downstream devices are in D0 state before sending PME_TurnOff to put
-        * link into L2 state.
-        * This is as per PCI Express Base r4.0 v1.0 September 27-2017,
-        * 5.2 Link State Power Management (Page #428).
-        */
-
-       list_for_each_entry(child, &pp->bridge->bus->children, node) {
-               if (child->parent == pp->bridge->bus) {
-                       root_port_bus = child;
-                       break;
-               }
-       }
-
-       if (!root_port_bus) {
-               dev_err(pcie->dev, "Failed to find downstream bus of Root Port\n");
-               return;
-       }
-
-       /* Bring downstream devices to D0 if they are not already in */
-       list_for_each_entry(pdev, &root_port_bus->devices, bus_list) {
-               if (PCI_SLOT(pdev->devfn) == 0) {
-                       if (pci_set_power_state(pdev, PCI_D0))
-                               dev_err(pcie->dev,
-                                       "Failed to transition %s to D0 state\n",
-                                       dev_name(&pdev->dev));
-               }
-       }
-}
-
 static int tegra_pcie_get_slot_regulators(struct tegra_pcie_dw *pcie)
 {
        pcie->slot_ctl_3v3 = devm_regulator_get_optional(pcie->dev, "vpcie3v3");
@@ -1625,7 +1587,6 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)
 
 static void tegra_pcie_deinit_controller(struct tegra_pcie_dw *pcie)
 {
-       tegra_pcie_downstream_dev_to_D0(pcie);
        dw_pcie_host_deinit(&pcie->pci.pp);
        tegra_pcie_dw_pme_turnoff(pcie);
        tegra_pcie_unconfig_controller(pcie);
@@ -2336,7 +2297,6 @@ static int tegra_pcie_dw_suspend_noirq(struct device *dev)
        if (!pcie->link_state)
                return 0;
 
-       tegra_pcie_downstream_dev_to_D0(pcie);
        tegra_pcie_dw_pme_turnoff(pcie);
        tegra_pcie_unconfig_controller(pcie);
 
@@ -2410,7 +2370,6 @@ static void tegra_pcie_dw_shutdown(struct platform_device *pdev)
                        return;
 
                debugfs_remove_recursive(pcie->debugfs);
-               tegra_pcie_downstream_dev_to_D0(pcie);
 
                disable_irq(pcie->pci.pp.irq);
                if (IS_ENABLED(CONFIG_PCI_MSI))