From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peter Senna Tschudin Date: Thu, 11 May 2017 11:01:17 +0200 Subject: [U-Boot] [RFC] drivers: pci: imx: add imx_pcie_remove function In-Reply-To: References: <1494434600-24661-1-git-send-email-tharvey@gateworks.com> Message-ID: <20170511090117.GA25159@collabora.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Wed, May 10, 2017 at 03:10:37PM -0300, Fabio Estevam wrote: Hi Tim, > Hi Tim, > > Thanks for working on this! > > [Adding Peter and Jagan on Cc] > [snip] 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. 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: 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) {