diff options
author | Andrejs Cainikovs <andrejs.cainikovs@toradex.com> | 2022-02-05 14:56:28 +0100 |
---|---|---|
committer | Francesco Dolcini <francesco.dolcini@toradex.com> | 2022-02-15 12:08:00 +0000 |
commit | 75d336c1651af429f12f2a89fb030a209a994946 (patch) | |
tree | 912c1e0f1c2f877f05cba681cb80f51807fc8f32 | |
parent | 6232d38adfd5c584d198bad83ab94ec5288b9303 (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.c | 29 |
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: |