summaryrefslogtreecommitdiff
path: root/drivers/pci/host/pci-imx6.c
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2016-01-20 16:13:28 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit1e85ad0f7f7864e6694d1cb8fdf51254f9add883 (patch)
treeb5f640452ab2f0d5a5e7e9081e39ebece733f642 /drivers/pci/host/pci-imx6.c
parent62b743221c0fbf3bd5999d0abcc6cd0c94c5a687 (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/pci/host/pci-imx6.c')
-rw-r--r--drivers/pci/host/pci-imx6.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index fcd9b6532c23..4f91ea413d04 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -603,10 +603,12 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
* 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 = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
- tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
- tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
- dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
+ if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
+ tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
+ tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
+ tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
+ dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
+ }
/* Start LTSSM. */
if (imx6_pcie->variant == IMX7D)
@@ -649,6 +651,16 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
ret = imx6_pcie_wait_for_link(imx6_pcie);
if (ret) {
dev_err(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);
+ }
goto err_reset_phy;
}