Hi Yuri,
Our hardware and software is configured as described in the forum post you linked and is functional with some devices, but the issue is that not all devices are able to initialize properly.
I found that modifying the pci-imx6.c driver so that the PCIe PHY is released from reset before the ~PERST signal to reset the PCIe device is toggled allowed both the 3160 card that was failing before to initialize properly.
I don't have access to the PCI SIG PCIe specifications documentation, would you or someone at NXP be able to confirm that the change I made is in accordance with the specifications? The i.MX7D TRM shows the start up sequence in Figure 11-56, however it doesn't include PERST. It does include a signal "CMN_RST", how is this signal controlled? I don't see it referenced in the driver.
Here are the changes I made in imx6_pcie_deassert_core_reset:
/* allow the clocks to stabilize */
udelay(200);
+ /*
+ * Release the PCIe PHY reset here for iMX7D
+ */
+ if (is_imx7d_pcie(imx6_pcie)) {
+ /* wait for more than 10us to release phy g_rst and btnrst */
+ udelay(10);
+ regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(1), 0);
+ regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(2), 0);
+ regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(6), 0);
+
+ /* wait for phy pll to lock. */
+ pci_imx_phy_pll_locked(imx6_pcie);
+ }
+
/* Some boards don't have PCIe reset GPIO. */
if (gpio_is_valid(imx6_pcie->reset_gpio)) {
gpio_set_value_cansleep(imx6_pcie->reset_gpio, 0);
mdelay(20);
gpio_set_value_cansleep(imx6_pcie->reset_gpio, 1);
mdelay(20);
}
/*
- * Release the PCIe PHY reset here
+ * Release the PCIe PHY reset here for i.MX6
*/
- if (is_imx7d_pcie(imx6_pcie)) {
- /* wait for more than 10us to release phy g_rst and btnrst */
- udelay(10);
- regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(6), 0);
- regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(1), 0);
- regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(2), 0);
-
- /* wait for phy pll lock firstly. */
- pci_imx_phy_pll_locked(imx6_pcie);
- } else if (is_imx6sx_pcie(imx6_pcie)) {
+ if (is_imx6sx_pcie(imx6_pcie)) {
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
IMX6SX_GPR5_PCIE_BTNRST, 0);
} else if (is_imx6qp_pcie(imx6_pcie)) {
Thanks,
Anna