
On Thu, May 11, 2017 at 6:01 AM, Peter Senna Tschudin peter.senna@collabora.com wrote:
Thank you for working on this! Your patch worked for me, but I needed to add an "extern void imx_pcie_remove(void);" before calling the function, which probably means I'm missing something.
The extern should be added into a header file.
After applying this patch to u-boot, u-boot can initialize PCI and 4.11.0-next-20170510 will boot. Without your patch 4.11.0-next-20170510 do not boot if u-boot initialize the PCI bus.
Thanks a lot!
Here is the patch I'm using for our board:
Stefano,
The patches that Tim/Peter posted solve a kernel hang with kernel 4.11 on mx6q when U-Boot has PCI support.
Could you please take a look and let us know if there is a more generic way to fix this issue, like fixing it for all mx6qdl boards that have PCI support?
I understand that ideally the imx6 pci driver should be converted to driver model and then we add the .remove hook, like Lucas did for Barebox: https://git.pengutronix.de/cgit/barebox/commit/?id=f1da98da2760c21487bbba8f7...
While the imx pci driver is not converted to device model, would you be willing to accept such per board patches for the time being?
Please advise.
Thanks
diff --git a/board/ge/bx50v3/bx50v3.c b/board/ge/bx50v3/bx50v3.c index cb49b58..7e03082 100644 --- a/board/ge/bx50v3/bx50v3.c +++ b/board/ge/bx50v3/bx50v3.c @@ -829,6 +829,7 @@ static void remove_ethaddr_env_var(int index) setenv(env_var_name, NULL); }
+extern void imx_pcie_remove(void); int last_stage_init(void) { int i;
@@ -838,6 +839,8 @@ int last_stage_init(void) { remove_ethaddr_env_var(i); }
imx_pcie_remove();
return 0;
}
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 732d59d..eab0a2b 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -42,6 +42,9 @@
/* PCIe Port Logic registers (memory-mapped) */ #define PL_OFFSET 0x700 +#define PCIE_PL_PFLR (PL_OFFSET + 0x08) +#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16) +#define PCIE_PL_PFLR_FORCE_LINK (1 << 15) #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) #define PCIE_PHY_DEBUG_R1_LINK_UP (1 << 4) @@ -445,6 +448,36 @@ static int imx6_pcie_assert_core_reset(void) /* Power up PCIe PHY */ setbits_le32(&gpc_regs->cntr, PCIE_PHY_PUP_REQ); #else
/*
* If the bootloader already enabled the link we need some special
* handling to get the core back into a state where it is safe to
* touch it for configuration. As there is no dedicated reset signal
* wired up for MX6QDL, we need to manually force LTSSM into "detect"
* state before completely disabling LTSSM, which is a prerequisite
* for core configuration.
*
* If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
* indication that the bootloader activated the link.
*/
if (is_mx6dq()) {
u32 val, gpr1, gpr12;
gpr1 = readl(&iomuxc_regs->gpr[1]);
gpr12 = readl(&iomuxc_regs->gpr[12]);
if ((gpr1 & IOMUXC_GPR1_PCIE_REF_CLK_EN) &&
(gpr12 & IOMUXC_GPR12_PCIE_CTL_2)) {
val = readl(MX6_DBI_ADDR + PCIE_PL_PFLR);
val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
val |= PCIE_PL_PFLR_FORCE_LINK;
imx_pcie_fix_dabt_handler(true);
writel(val, MX6_DBI_ADDR + PCIE_PL_PFLR);
imx_pcie_fix_dabt_handler(false);
gpr12 &= ~IOMUXC_GPR12_PCIE_CTL_2;
writel(val, &iomuxc_regs->gpr[12]);
}
} setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN); clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
#endif @@ -652,6 +685,11 @@ void imx_pcie_init(void) } }
+void imx_pcie_remove(void) +{
imx6_pcie_assert_core_reset();
+}
/* Probe function. */ void pci_init_board(void) {