summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrejs Cainikovs <andrejs.cainikovs@toradex.com>2022-02-05 14:56:28 +0100
committerFrancesco Dolcini <francesco.dolcini@toradex.com>2022-02-15 12:08:00 +0000
commit75d336c1651af429f12f2a89fb030a209a994946 (patch)
tree912c1e0f1c2f877f05cba681cb80f51807fc8f32
parent6232d38adfd5c584d198bad83ab94ec5288b9303 (diff)
pci: pci-imx6: fix PERST# start-up sequence
According to the PCI-E standard the PERST# signal (reset-gpio in fsl,imx6* compatible dts) should be kept asserted for at least 100 usec before the PCI-E refclock is stable, should be kept asserted for at least 100ms after the power rails are stable and the host should wait at least 100 msec after it is de-asserted before accessing the configuration space of any attached device. From PCI Express Card Electromechanical Specification T-PVPERL: Power stable to PERST# inactive - 100 msec T-PERST-CLK: REFCLK stable before PERST# inactive 100 usec. From PCI Express Base Specification: To allow components to perform internal initialization, system software must wait for at least 100 ms from the end of a Conventional Reset of one or more devices before it is permitted to issue Configuration Requests to those devices Failure to do so could prevent PCI-E devices to be working correctly, and this was experienced with real devices. Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs@toradex.com>
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 663f41df33ab..b130a9282101 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1148,6 +1148,12 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
dev_err(dev, "failed to disable vpcie regulator: %d\n",
ret);
}
+
+ /* Some boards don't have PCIe reset GPIO. */
+ if (imx6_pcie->reset_gpiod) {
+ gpiod_set_value_cansleep(imx6_pcie->reset_gpiod,
+ !imx6_pcie->gpio_active_high);
+ }
}
static void imx6_pcie_set_l1_latency(struct imx6_pcie *imx6_pcie)
@@ -1223,16 +1229,6 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
break;
}
- /* Some boards don't have PCIe reset GPIO. */
- if (imx6_pcie->reset_gpiod) {
- gpiod_set_value_cansleep(imx6_pcie->reset_gpiod,
- !imx6_pcie->gpio_active_high);
- msleep(100);
- gpiod_set_value_cansleep(imx6_pcie->reset_gpiod,
- imx6_pcie->gpio_active_high);
- msleep(20);
- }
-
switch (imx6_pcie->drvdata->variant) {
case IMX8QM:
case IMX8QM_EP:
@@ -1403,6 +1399,19 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
break;
}
+ /* Some boards don't have PCIe reset GPIO. */
+ if (imx6_pcie->reset_gpiod) {
+ msleep(100);
+ gpiod_set_value_cansleep(imx6_pcie->reset_gpiod,
+ imx6_pcie->gpio_active_high);
+ /*
+ * PCI Express Base Specification:
+ * A delay of at least 100ms is required after PERST# is
+ * de-asserted before issuing any Configuration Requests
+ */
+ msleep(100);
+ }
+
return 0;
err_pll: