diff options
author | Richard Zhu <hongxing.zhu@nxp.com> | 2016-01-20 16:13:28 +0800 |
---|---|---|
committer | Richard Zhu <hongxing.zhu@nxp.com> | 2016-01-29 11:45:24 +0800 |
commit | 01944d7aba6916061b39b6b67c8fa8004c1bf25c (patch) | |
tree | 149cae93cdfe8dbdb58f1aca5479c29dab47e98a /drivers | |
parent | c942d1d5bafb6c1d5d001e08583166fe7db6a5f2 (diff) |
MLK-12278 pci: imx: turn off pcie clks when link is down
In order to save power assumption, turn off the pcie clks
when there is no pcie link up at all.
add the option CONFIG_PCI_IMX6_COMPLIANCE_TEST, enable it
when the image is used to do the pcie compliance tests
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/host/Kconfig | 9 | ||||
-rw-r--r-- | drivers/pci/host/pci-imx6.c | 22 |
2 files changed, 26 insertions, 5 deletions
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index d19adfca7217..cac9472c3ebb 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -30,6 +30,15 @@ config PCI_IMX6 select PCIEPORTBUS select PCIE_DW +config PCI_IMX6_COMPLIANCE_TEST + bool "Enable pcie compliance tests on imx6" + depends on PCI_IMX6 + default n + help + Say Y here if you want do the compliance tests on imx6 pcie rc found + on FSL iMX SoCs. The pcie clks wouldn't be turned off, and the link + speed wouldn't be limited to gen1 when the Y is set here. + config EP_MODE_IN_EP_RC_SYS bool "PCI Express EP mode in the IMX6 RC/EP interconnection system" depends on PCI_IMX6 diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index ae47b6f06b9a..58707e935986 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -530,16 +530,18 @@ static int imx6_pcie_start_link(struct pcie_port *pp) struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); uint32_t tmp; int ret, count; - /* * Force Gen1 operation when starting the link. In case the link is * started in Gen2 mode, there is a possibility the devices on the * bus will not be detected at all. This happens with PCIe switches. */ - tmp = readl(pp->dbi_base + PCIE_RC_LCR); - tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; - tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; - writel(tmp, pp->dbi_base + PCIE_RC_LCR); + + if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) { + tmp = readl(pp->dbi_base + PCIE_RC_LCR); + tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; + tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; + writel(tmp, pp->dbi_base + PCIE_RC_LCR); + } /* Start LTSSM. */ if (is_imx7d_pcie(imx6_pcie)) @@ -583,6 +585,16 @@ static int imx6_pcie_start_link(struct pcie_port *pp) if (ret) { dev_err(pp->dev, "Failed to bring link up!\n"); + if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) { + clk_disable_unprepare(imx6_pcie->pcie); + clk_disable_unprepare(imx6_pcie->pcie_bus); + clk_disable_unprepare(imx6_pcie->pcie_phy); + if (is_imx6sx_pcie(imx6_pcie)) + clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); + release_bus_freq(BUS_FREQ_HIGH); + if (imx6_pcie->pcie_phy_regulator != NULL) + regulator_disable(imx6_pcie->pcie_phy_regulator); + } } else { tmp = readl(pp->dbi_base + 0x80); dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf); |