PCI: tegra: Rearrange Tegra PCIe driver functions [Linux 5.3]

This Linux kernel change "PCI: tegra: Rearrange Tegra PCIe driver functions" is included in the Linux 5.3 release. This change is authored by Manikanta Maddireddy <mmaddireddy [at] nvidia.com> on Tue Jun 18 23:31:42 2019 +0530. The commit for this change in Linux stable tree is 973d749 (patch).

PCI: tegra: Rearrange Tegra PCIe driver functions

Tegra PCIe has register specifications for:

 - AXI to FPCI(AFI) bridge
 - Multiple PCIe root ports
 - PCIe PHY
 - PCIe pad control

Rearrange Tegra PCIe driver functions so that each function programs
the required module only.

- tegra_pcie_enable_controller(): Program AFI module and enable PCIe
  controller
- tegra_pcie_phy_power_on(): Bring up PCIe PHY
- tegra_pcie_apply_pad_settings(): Program PCIe REFCLK pad settings
- tegra_pcie_enable_ports(): Program each root port and bring up PCIe
  link

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Thierry Reding <treding@nvidia.com>

There are 70 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/pci/controller/pci-tegra.c | 70 ++++++++++++++++----------------------
 1 file changed, 30 insertions(+), 40 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 85c5e6a..5d93bb3 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -852,7 +852,6 @@ static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port)
 static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
 {
    struct device *dev = pcie->dev;
-   const struct tegra_pcie_soc *soc = pcie->soc;
    struct tegra_pcie_port *port;
    int err;

@@ -878,12 +877,6 @@ static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
        }
    }

-   /* Configure the reference clock driver */
-   pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
-
-   if (soc->num_ports > 2)
-       pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
-
    return 0;
 }

@@ -918,13 +911,11 @@ static int tegra_pcie_phy_power_off(struct tegra_pcie *pcie)
    return 0;
 }

-static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
+static void tegra_pcie_enable_controller(struct tegra_pcie *pcie)
 {
-   struct device *dev = pcie->dev;
    const struct tegra_pcie_soc *soc = pcie->soc;
    struct tegra_pcie_port *port;
    unsigned long value;
-   int err;

    /* enable PLL power down */
    if (pcie->phy) {
@@ -958,14 +949,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
        afi_writel(pcie, value, AFI_FUSE);
    }

-   if (soc->program_uphy) {
-       err = tegra_pcie_phy_power_on(pcie);
-       if (err < 0) {
-           dev_err(dev, "failed to power on PHY(s): %d\n", err);
-           return err;
-       }
-   }
-
    /* take the PCIe interface module out of reset */
    reset_control_deassert(pcie->pcie_xrst);

@@ -989,22 +972,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)

    /* disable all exceptions */
    afi_writel(pcie, 0, AFI_FPCI_ERROR_MASKS);
-
-   return 0;
-}
-
-static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
-{
-   int err;
-
-   reset_control_assert(pcie->pcie_xrst);
-
-   if (pcie->soc->program_uphy) {
-       err = tegra_pcie_phy_power_off(pcie);
-       if (err < 0)
-           dev_err(pcie->dev, "failed to power off PHY(s): %d\n",
-               err);
-   }
 }

 static void tegra_pcie_power_off(struct tegra_pcie *pcie)
@@ -1106,6 +1073,17 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
    return err;
 }

+static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
+{
+   const struct tegra_pcie_soc *soc = pcie->soc;
+
+   /* Configure the reference clock driver */
+   pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
+
+   if (soc->num_ports > 2)
+       pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
+}
+
 static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
 {
    struct device *dev = pcie->dev;
@@ -2501,16 +2479,23 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
 {
    struct tegra_pcie *pcie = dev_get_drvdata(dev);
    struct tegra_pcie_port *port;
+   int err;

    list_for_each_entry(port, &pcie->ports, list)
        tegra_pcie_pme_turnoff(port);

    tegra_pcie_disable_ports(pcie);

+   if (pcie->soc->program_uphy) {
+       err = tegra_pcie_phy_power_off(pcie);
+       if (err < 0)
+           dev_err(dev, "failed to power off PHY(s): %d\n", err);
+   }
+
    if (IS_ENABLED(CONFIG_PCI_MSI))
        tegra_pcie_disable_msi(pcie);

-   tegra_pcie_disable_controller(pcie);
+   reset_control_assert(pcie->pcie_xrst);
    tegra_pcie_power_off(pcie);

    return 0;
@@ -2526,16 +2511,21 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
        dev_err(dev, "tegra pcie power on fail: %d\n", err);
        return err;
    }
-   err = tegra_pcie_enable_controller(pcie);
-   if (err) {
-       dev_err(dev, "tegra pcie controller enable fail: %d\n", err);
-       goto poweroff;
-   }
+   tegra_pcie_enable_controller(pcie);
    tegra_pcie_setup_translations(pcie);

    if (IS_ENABLED(CONFIG_PCI_MSI))
        tegra_pcie_enable_msi(pcie);

+   if (pcie->soc->program_uphy) {
+       err = tegra_pcie_phy_power_on(pcie);
+       if (err < 0) {
+           dev_err(dev, "failed to power on PHY(s): %d\n", err);
+           goto poweroff;
+       }
+   }
+
+   tegra_pcie_apply_pad_settings(pcie);
    tegra_pcie_enable_ports(pcie);

    return 0;

Leave a Reply

Your email address will not be published. Required fields are marked *