From mboxrd@z Thu Jan 1 00:00:00 1970 From: Fabio Estevam Date: Thu, 11 May 2017 08:06:12 -0300 Subject: [U-Boot] [RFC] drivers: pci: imx: add imx_pcie_remove function In-Reply-To: <20170511090117.GA25159@collabora.com> References: <1494434600-24661-1-git-send-email-tharvey@gateworks.com> <20170511090117.GA25159@collabora.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Thu, May 11, 2017 at 6:01 AM, Peter Senna Tschudin 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=f1da98da2760c21487bbba8f7fb957c843a22896 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) > {