Commit a2fa6f64 authored by Richard Zhu's avatar Richard Zhu Committed by Bjorn Helgaas

PCI: imx6: Wait for clocks to stabilize after ref_en

For boards without a reset GPIO we skip the delay between enabling the
pcie_ref_clk and touching the RC registers for configuration.  This hangs
the system if there isn't a proper delay to ensure the clocks are settled
in the DW PCIe core.

Also iMX6Q always needs an additional 10us delay to make sure the reset is
propagated through the core, as we don't have an explicitly controlled
reset input on this SoC.

This fixes a problem with 3fce0e88 ("PCI: imx6: Delay enabling
reference clock for SS until it stabilizes"): the kernel doesn't boot on
systems that don't pass the PCI GPIO reset in the DTB.  This regression
affects mx6 nitrogen boards.

[bhelgaas: add regression info in changelog]
Fixes: 3fce0e88 ("PCI: imx6: Delay enabling reference clock for SS until it stabilizes")
Reported-by: default avatarFabio Estevam <fabio.estevam@freescale.com>
Tested-by: default avatarFabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: default avatarRichard Zhu <richard.zhu@freescale.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarLucas Stach <l.stach@pengutronix.de>
parent c302d35e
...@@ -275,15 +275,22 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) ...@@ -275,15 +275,22 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
goto err_pcie; goto err_pcie;
} }
/* allow the clocks to stabilize */
usleep_range(200, 500);
/* power up core phy and enable ref clock */ /* power up core phy and enable ref clock */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
/*
* the async reset input need ref clock to sync internally,
* when the ref clock comes after reset, internal synced
* reset time is too short, cannot meet the requirement.
* add one ~10us delay here.
*/
udelay(10);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
/* allow the clocks to stabilize */
usleep_range(200, 500);
/* Some boards don't have PCIe reset GPIO. */ /* Some boards don't have PCIe reset GPIO. */
if (gpio_is_valid(imx6_pcie->reset_gpio)) { if (gpio_is_valid(imx6_pcie->reset_gpio)) {
gpio_set_value(imx6_pcie->reset_gpio, 0); gpio_set_value(imx6_pcie->reset_gpio, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment