summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2016-01-20 16:13:28 +0800
committerRichard Zhu <hongxing.zhu@nxp.com>2016-01-29 11:45:24 +0800
commit01944d7aba6916061b39b6b67c8fa8004c1bf25c (patch)
tree149cae93cdfe8dbdb58f1aca5479c29dab47e98a /drivers
parentc942d1d5bafb6c1d5d001e08583166fe7db6a5f2 (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/Kconfig9
-rw-r--r--drivers/pci/host/pci-imx6.c22
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);