Question: Is this RC element needed to work properly?
It is not mentioned in the carrier board design guidelines.
I am still questioning what can cause this wrong behaviour (PERST deasserted before REFCLK stable). Can it be a misconfiguration of the BSP (e.g. devicetree)?
Could you please verify how the signal behaviour is on your side?
The effect of this problem on our side is: On many specimen of our carrier boards, the PCIe Switch works correctly, but on some specimen sometimes the PCIe bus does not come up (PHY link never came up), and on some boards it never comes up. This is a major issue that blocks our board production. Please help.
We are currently carrying out some tests and I would like to ask you to test the following patch (at the end of this message) for the file drivers/pci/controller/dwc/pci-imx6.c
You can use git apply --ignore-whitespace patch_name to apply the patch at the root of your local linux-toradex repository.
If you need help to build, please refer to the article below
Let us know if with this patch your PCI bridge works.
Also, if possible, send us the output of your oscilloscope for both PERST and the PCI clock.
About the presence of the RC circuit, the time constant of this circuit is around 100ms, which is the delay that is stated on your PCI bridge datasheet. So maybe it would actually behave better if you had the RC circuit. We are still trying to clarify if this is general documentation that should be on our design guide.
The patch:
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 663f41df33ab..17cadb2e0c1e 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1227,10 +1227,6 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
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) {
@@ -1403,6 +1399,16 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
break;
}
+ /* Make sure we respect the PCIe specification and wait at least 100ms
+ * before talking to the device. At this point we already have the clock
+ * enabled.
+ */
+ if (imx6_pcie->reset_gpiod) {
+ msleep(100);
+ gpiod_set_value_cansleep(imx6_pcie->reset_gpiod,
+ imx6_pcie->gpio_active_high);
+ }
+
return 0;
err_pll:
I tried your patch and can confirm that it works. The timing is now correct and it fixed our problem. The PCIe bridge of our carrier board is now detected on all the boards which had problems to bring up the bridge.
Hello @rafael.tx,
Sorry for my late reply. At the moment we our using our own yocto image based on BSP 5.2. We’ll test your changes when we migrate to the latest BSP. But this will not happen before summer 2022. Sorry