[U-Boot] [PATCH 1/5] ARM: imx: Call imx_pcie_remove() only for non-DM PCI driver

The DM iMX PCI driver has DM_FLAG_OS_PREPARE set and will call imx_pcie_remove() from the .remove callback. Do not call it from the architecture code again.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de --- arch/arm/mach-imx/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 6b83f92662..93e60b2039 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -285,7 +285,7 @@ u32 get_ahb_clk(void)
void arch_preboot_os(void) { -#if defined(CONFIG_PCIE_IMX) +#if defined(CONFIG_PCIE_IMX) && !CONFIG_IS_ENABLED(DM_PCI) imx_pcie_remove(); #endif #if defined(CONFIG_SATA)

Pull out hard-coded register base addresses into driver private structure in preparation for DM conversion. No functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de --- drivers/pci/pcie_imx.c | 75 +++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 31 deletions(-)
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index fcc4ab7139..173636f48e 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -92,6 +92,18 @@ #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) #define PCIE_ATU_UPPER_TARGET 0x91C
+struct imx_pcie_priv { + void __iomem *dbi_base; + void __iomem *cfg_base; +}; + +static struct imx_pcie_priv imx_pcie_priv = { + .dbi_base = (void __iomem *)MX6_DBI_ADDR, + .cfg_base = (void __iomem *)MX6_ROOT_ADDR, +}; + +static struct imx_pcie_priv *priv = &imx_pcie_priv; + /* * PHY access functions */ @@ -231,7 +243,7 @@ static int imx6_pcie_link_up(void) int rx_valid, temp;
/* link is debug bit 36, debug register 1 starts at bit 32 */ - rc = readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R1); + rc = readl(priv->dbi_base + PCIE_PHY_DEBUG_R1); if ((rc & PCIE_PHY_DEBUG_R1_LINK_UP) && !(rc & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING)) return -EAGAIN; @@ -243,8 +255,8 @@ static int imx6_pcie_link_up(void) * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition * to gen2 is stuck */ - pcie_phy_read((void *)MX6_DBI_ADDR, PCIE_PHY_RX_ASIC_OUT, &rx_valid); - ltssm = readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R0) & 0x3F; + pcie_phy_read(priv->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); + ltssm = readl(priv->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F;
if (rx_valid & 0x01) return 0; @@ -254,15 +266,15 @@ static int imx6_pcie_link_up(void)
printf("transition to gen2 is stuck, reset PHY!\n");
- pcie_phy_read((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, &temp); + pcie_phy_read(priv->dbi_base, PHY_RX_OVRD_IN_LO, &temp); temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | PHY_RX_OVRD_IN_LO_RX_PLL_EN); - pcie_phy_write((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, temp); + pcie_phy_write(priv->dbi_base, PHY_RX_OVRD_IN_LO, temp);
udelay(3000);
- pcie_phy_read((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, &temp); + pcie_phy_read(priv->dbi_base, PHY_RX_OVRD_IN_LO, &temp); temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN | PHY_RX_OVRD_IN_LO_RX_PLL_EN); - pcie_phy_write((void *)MX6_DBI_ADDR, PHY_RX_OVRD_IN_LO, temp); + pcie_phy_write(priv->dbi_base, PHY_RX_OVRD_IN_LO, temp);
return 0; } @@ -285,24 +297,25 @@ static int imx_pcie_regions_setup(void) */
/* CMD reg:I/O space, MEM space, and Bus Master Enable */ - setbits_le32(MX6_DBI_ADDR | PCI_COMMAND, + setbits_le32(priv->dbi_base + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
/* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */ - setbits_le32(MX6_DBI_ADDR + PCI_CLASS_REVISION, + setbits_le32(priv->dbi_base + PCI_CLASS_REVISION, PCI_CLASS_BRIDGE_PCI << 16);
/* Region #0 is used for Outbound CFG space access. */ - writel(0, MX6_DBI_ADDR + PCIE_ATU_VIEWPORT); + writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT);
- writel(MX6_ROOT_ADDR, MX6_DBI_ADDR + PCIE_ATU_LOWER_BASE); - writel(0, MX6_DBI_ADDR + PCIE_ATU_UPPER_BASE); - writel(MX6_ROOT_ADDR + MX6_ROOT_SIZE, MX6_DBI_ADDR + PCIE_ATU_LIMIT); + writel((u32)priv->cfg_base, priv->dbi_base + PCIE_ATU_LOWER_BASE); + writel(0, priv->dbi_base + PCIE_ATU_UPPER_BASE); + writel((u32)priv->cfg_base + MX6_ROOT_SIZE, + priv->dbi_base + PCIE_ATU_LIMIT);
- writel(0, MX6_DBI_ADDR + PCIE_ATU_LOWER_TARGET); - writel(0, MX6_DBI_ADDR + PCIE_ATU_UPPER_TARGET); - writel(PCIE_ATU_TYPE_CFG0, MX6_DBI_ADDR + PCIE_ATU_CR1); - writel(PCIE_ATU_ENABLE, MX6_DBI_ADDR + PCIE_ATU_CR2); + writel(0, priv->dbi_base + PCIE_ATU_LOWER_TARGET); + writel(0, priv->dbi_base + PCIE_ATU_UPPER_TARGET); + writel(PCIE_ATU_TYPE_CFG0, priv->dbi_base + PCIE_ATU_CR1); + writel(PCIE_ATU_ENABLE, priv->dbi_base + PCIE_ATU_CR2);
return 0; } @@ -315,18 +328,18 @@ static uint32_t get_bus_address(pci_dev_t d, int where) uint32_t va_address;
/* Reconfigure Region #0 */ - writel(0, MX6_DBI_ADDR + PCIE_ATU_VIEWPORT); + writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT);
if (PCI_BUS(d) < 2) - writel(PCIE_ATU_TYPE_CFG0, MX6_DBI_ADDR + PCIE_ATU_CR1); + writel(PCIE_ATU_TYPE_CFG0, priv->dbi_base + PCIE_ATU_CR1); else - writel(PCIE_ATU_TYPE_CFG1, MX6_DBI_ADDR + PCIE_ATU_CR1); + writel(PCIE_ATU_TYPE_CFG1, priv->dbi_base + PCIE_ATU_CR1);
if (PCI_BUS(d) == 0) { - va_address = MX6_DBI_ADDR; + va_address = (u32)priv->dbi_base; } else { - writel(d << 8, MX6_DBI_ADDR + PCIE_ATU_LOWER_TARGET); - va_address = MX6_IO_ADDR + SZ_16M - SZ_1M; + writel(d << 8, priv->dbi_base + PCIE_ATU_LOWER_TARGET); + va_address = (u32)priv->cfg_base; }
va_address += (where & ~0x3); @@ -465,12 +478,12 @@ static int imx6_pcie_assert_core_reset(bool prepare_for_boot) 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 = readl(priv->dbi_base + 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); + writel(val, priv->dbi_base + PCIE_PL_PFLR); imx_pcie_fix_dabt_handler(false);
gpr12 &= ~IOMUXC_GPR12_PCIE_CTL_2; @@ -621,9 +634,9 @@ static int imx_pcie_link_up(void) * Force the PCIe RC subordinate to 0xff, otherwise no downstream * devices will be detected if the enumeration is applied strictly. */ - tmp = readl(MX6_DBI_ADDR + 0x18); + tmp = readl(priv->dbi_base + 0x18); tmp |= (0xff << 16); - writel(tmp, MX6_DBI_ADDR + 0x18); + writel(tmp, priv->dbi_base + 0x18);
/* * FIXME: Force the PCIe RC to Gen1 operation @@ -631,10 +644,10 @@ static int imx_pcie_link_up(void) * up, otherwise no downstream devices are detected. After the * link is up, a managed Gen1->Gen2 transition can be initiated. */ - tmp = readl(MX6_DBI_ADDR + 0x7c); + tmp = readl(priv->dbi_base + 0x7c); tmp &= ~0xf; tmp |= 0x1; - writel(tmp, MX6_DBI_ADDR + 0x7c); + writel(tmp, priv->dbi_base + 0x7c);
/* LTSSM enable, starting link. */ setbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_APPS_LTSSM_ENABLE); @@ -647,8 +660,8 @@ static int imx_pcie_link_up(void) puts("PCI: pcie phy link never came up\n"); #endif debug("DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", - readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R0), - readl(MX6_DBI_ADDR + PCIE_PHY_DEBUG_R1)); + readl(priv->dbi_base + PCIE_PHY_DEBUG_R0), + readl(priv->dbi_base + PCIE_PHY_DEBUG_R1)); return -EINVAL; } }

On Sat, May 18, 2019 at 2:26 AM Marek Vasut marex@denx.de wrote:
Pull out hard-coded register base addresses into driver private structure in preparation for DM conversion. No functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de
drivers/pci/pcie_imx.c | 75 +++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 31 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

The driver limits the config space base to 32bit, however it can be 64bit on 64bit iMX hardware too. Remove that limitation. This patch has no impact on the iMX6, which is the only SoC currently supported by this driver.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de --- drivers/pci/pcie_imx.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 173636f48e..76f9e06b36 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -307,9 +307,11 @@ static int imx_pcie_regions_setup(void) /* Region #0 is used for Outbound CFG space access. */ writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT);
- writel((u32)priv->cfg_base, priv->dbi_base + PCIE_ATU_LOWER_BASE); - writel(0, priv->dbi_base + PCIE_ATU_UPPER_BASE); - writel((u32)priv->cfg_base + MX6_ROOT_SIZE, + writel(lower_32_bits((uintptr_t)priv->cfg_base), + priv->dbi_base + PCIE_ATU_LOWER_BASE); + writel(upper_32_bits((uintptr_t)priv->cfg_base), + priv->dbi_base + PCIE_ATU_UPPER_BASE); + writel(lower_32_bits((uintptr_t)priv->cfg_base + MX6_ROOT_SIZE), priv->dbi_base + PCIE_ATU_LIMIT);
writel(0, priv->dbi_base + PCIE_ATU_LOWER_TARGET); @@ -323,9 +325,9 @@ static int imx_pcie_regions_setup(void) /* * PCI Express accessors */ -static uint32_t get_bus_address(pci_dev_t d, int where) +static void __iomem *get_bus_address(pci_dev_t d, int where) { - uint32_t va_address; + void __iomem *va_address;
/* Reconfigure Region #0 */ writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT); @@ -336,10 +338,10 @@ static uint32_t get_bus_address(pci_dev_t d, int where) writel(PCIE_ATU_TYPE_CFG1, priv->dbi_base + PCIE_ATU_CR1);
if (PCI_BUS(d) == 0) { - va_address = (u32)priv->dbi_base; + va_address = priv->dbi_base; } else { writel(d << 8, priv->dbi_base + PCIE_ATU_LOWER_TARGET); - va_address = (u32)priv->cfg_base; + va_address = priv->cfg_base; }
va_address += (where & ~0x3); @@ -390,7 +392,7 @@ static void imx_pcie_fix_dabt_handler(bool set) static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, int where, u32 *val) { - uint32_t va_address; + void __iomem *va_address; int ret;
ret = imx_pcie_addr_valid(d); @@ -419,7 +421,7 @@ static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, int where, u32 val) { - uint32_t va_address = 0; + void __iomem *va_address = NULL; int ret;
ret = imx_pcie_addr_valid(d);

On Sat, May 18, 2019 at 2:26 AM Marek Vasut marex@denx.de wrote:
The driver limits the config space base to 32bit, however it can be 64bit on 64bit iMX hardware too. Remove that limitation. This patch has no impact on the iMX6, which is the only SoC currently supported by this driver.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de
drivers/pci/pcie_imx.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

Pass the driver private data around the driver as much as possible, instead of having it as a static global variable. This is done in preparation for the DM conversion, no functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de --- drivers/pci/pcie_imx.c | 44 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 76f9e06b36..bcee3745f4 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -97,13 +97,6 @@ struct imx_pcie_priv { void __iomem *cfg_base; };
-static struct imx_pcie_priv imx_pcie_priv = { - .dbi_base = (void __iomem *)MX6_DBI_ADDR, - .cfg_base = (void __iomem *)MX6_ROOT_ADDR, -}; - -static struct imx_pcie_priv *priv = &imx_pcie_priv; - /* * PHY access functions */ @@ -237,7 +230,7 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data) return 0; }
-static int imx6_pcie_link_up(void) +static int imx6_pcie_link_up(struct imx_pcie_priv *priv) { u32 rc, ltssm; int rx_valid, temp; @@ -282,7 +275,7 @@ static int imx6_pcie_link_up(void) /* * iATU region setup */ -static int imx_pcie_regions_setup(void) +static int imx_pcie_regions_setup(struct imx_pcie_priv *priv) { /* * i.MX6 defines 16MB in the AXI address map for PCIe. @@ -325,7 +318,8 @@ static int imx_pcie_regions_setup(void) /* * PCI Express accessors */ -static void __iomem *get_bus_address(pci_dev_t d, int where) +static void __iomem *get_bus_address(struct imx_pcie_priv *priv, + pci_dev_t d, int where) { void __iomem *va_address;
@@ -392,6 +386,7 @@ static void imx_pcie_fix_dabt_handler(bool set) static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, int where, u32 *val) { + struct imx_pcie_priv *priv = hose->priv_data; void __iomem *va_address; int ret;
@@ -401,7 +396,7 @@ static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, return 0; }
- va_address = get_bus_address(d, where); + va_address = get_bus_address(priv, d, where);
/* * Read the PCIe config space. We must replace the DABT handler @@ -421,6 +416,7 @@ static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, int where, u32 val) { + struct imx_pcie_priv *priv = hose->priv_data; void __iomem *va_address = NULL; int ret;
@@ -428,7 +424,7 @@ static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, if (ret) return ret;
- va_address = get_bus_address(d, where); + va_address = get_bus_address(priv, d, where);
/* * Write the PCIe config space. We must replace the DABT handler @@ -445,7 +441,8 @@ static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, /* * Initial bus setup */ -static int imx6_pcie_assert_core_reset(bool prepare_for_boot) +static int imx6_pcie_assert_core_reset(struct imx_pcie_priv *priv, + bool prepare_for_boot) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
@@ -617,17 +614,17 @@ static int imx6_pcie_deassert_core_reset(void) return 0; }
-static int imx_pcie_link_up(void) +static int imx_pcie_link_up(struct imx_pcie_priv *priv) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; uint32_t tmp; int count = 0;
- imx6_pcie_assert_core_reset(false); + imx6_pcie_assert_core_reset(priv, false); imx6_pcie_init_phy(); imx6_pcie_deassert_core_reset();
- imx_pcie_regions_setup(); + imx_pcie_regions_setup(priv);
/* * By default, the subordinate is set equally to the secondary @@ -654,7 +651,7 @@ static int imx_pcie_link_up(void) /* LTSSM enable, starting link. */ setbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_APPS_LTSSM_ENABLE);
- while (!imx6_pcie_link_up()) { + while (!imx6_pcie_link_up(priv)) { udelay(10); count++; if (count >= 4000) { @@ -671,6 +668,13 @@ static int imx_pcie_link_up(void) return 0; }
+static struct imx_pcie_priv imx_pcie_priv = { + .dbi_base = (void __iomem *)MX6_DBI_ADDR, + .cfg_base = (void __iomem *)MX6_ROOT_ADDR, +}; + +static struct imx_pcie_priv *priv = &imx_pcie_priv; + void imx_pcie_init(void) { /* Static instance of the controller. */ @@ -680,6 +684,8 @@ void imx_pcie_init(void)
memset(&pcc, 0, sizeof(pcc));
+ hose->priv_data = priv; + /* PCI I/O space */ pci_set_region(&hose->regions[0], MX6_IO_ADDR, MX6_IO_ADDR, @@ -706,7 +712,7 @@ void imx_pcie_init(void) imx_pcie_write_config);
/* Start the controller. */ - ret = imx_pcie_link_up(); + ret = imx_pcie_link_up(priv);
if (!ret) { pci_register_hose(hose); @@ -716,7 +722,7 @@ void imx_pcie_init(void)
void imx_pcie_remove(void) { - imx6_pcie_assert_core_reset(true); + imx6_pcie_assert_core_reset(priv, true); }
/* Probe function. */

On Sat, May 18, 2019 at 2:26 AM Marek Vasut marex@denx.de wrote:
Pass the driver private data around the driver as much as possible, instead of having it as a static global variable. This is done in preparation for the DM conversion, no functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de
drivers/pci/pcie_imx.c | 44 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

Add DM support and support for probing the iMX PCI driver from DT. The legacy non-DM support is retained, however shall be removed once DM PCI is the only option remaining.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de --- drivers/pci/pcie_imx.c | 111 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index bcee3745f4..e6a396023b 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -16,6 +16,7 @@ #include <asm/arch/crm_regs.h> #include <asm/gpio.h> #include <asm/io.h> +#include <dm.h> #include <linux/sizes.h> #include <errno.h> #include <asm/arch/sys_proto.h> @@ -383,10 +384,9 @@ static void imx_pcie_fix_dabt_handler(bool set) } }
-static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, - int where, u32 *val) +static int imx_pcie_read_cfg(struct imx_pcie_priv *priv, pci_dev_t d, + int where, u32 *val) { - struct imx_pcie_priv *priv = hose->priv_data; void __iomem *va_address; int ret;
@@ -413,10 +413,9 @@ static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, return 0; }
-static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, - int where, u32 val) +static int imx_pcie_write_cfg(struct imx_pcie_priv *priv, pci_dev_t d, + int where, u32 val) { - struct imx_pcie_priv *priv = hose->priv_data; void __iomem *va_address = NULL; int ret;
@@ -668,6 +667,7 @@ static int imx_pcie_link_up(struct imx_pcie_priv *priv) return 0; }
+#if !CONFIG_IS_ENABLED(DM_PCI) static struct imx_pcie_priv imx_pcie_priv = { .dbi_base = (void __iomem *)MX6_DBI_ADDR, .cfg_base = (void __iomem *)MX6_ROOT_ADDR, @@ -675,6 +675,22 @@ static struct imx_pcie_priv imx_pcie_priv = {
static struct imx_pcie_priv *priv = &imx_pcie_priv;
+static int imx_pcie_read_config(struct pci_controller *hose, pci_dev_t d, + int where, u32 *val) +{ + struct imx_pcie_priv *priv = hose->priv_data; + + return imx_pcie_read_cfg(priv, d, where, val); +} + +static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d, + int where, u32 *val) +{ + struct imx_pcie_priv *priv = hose->priv_data; + + return imx_pcie_write_cfg(priv, d, where, val); +} + void imx_pcie_init(void) { /* Static instance of the controller. */ @@ -730,3 +746,86 @@ void pci_init_board(void) { imx_pcie_init(); } +#else +static int imx_pcie_dm_read_config(struct udevice *dev, pci_dev_t bdf, + uint offset, ulong *value, + enum pci_size_t size) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + u32 tmpval; + int ret; + + ret = imx_pcie_read_cfg(priv, bdf, offset, &tmpval); + if (ret) + return ret; + + *value = pci_conv_32_to_size(tmpval, offset, size); + return 0; +} + +static int imx_pcie_dm_write_config(struct udevice *dev, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + u32 tmpval, newval; + int ret; + + ret = imx_pcie_read_cfg(priv, bdf, offset, &tmpval); + if (ret) + return ret; + + newval = pci_conv_size_to_32(tmpval, value, offset, size); + return imx_pcie_write_cfg(priv, bdf, offset, newval); +} + +static int imx_pcie_dm_probe(struct udevice *dev) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + + return imx_pcie_link_up(priv); +} + +static int imx_pcie_dm_remove(struct udevice *dev) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + + imx6_pcie_assert_core_reset(priv, true); + + return 0; +} + +static int imx_pcie_ofdata_to_platdata(struct udevice *dev) +{ + struct imx_pcie_priv *priv = dev_get_priv(dev); + + priv->dbi_base = (void __iomem *)devfdt_get_addr_index(dev, 0); + priv->cfg_base = (void __iomem *)devfdt_get_addr_index(dev, 1); + if (!priv->dbi_base || !priv->cfg_base) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops imx_pcie_ops = { + .read_config = imx_pcie_dm_read_config, + .write_config = imx_pcie_dm_write_config, +}; + +static const struct udevice_id imx_pcie_ids[] = { + { .compatible = "fsl,imx6q-pcie" }, + { } +}; + +U_BOOT_DRIVER(imx_pcie) = { + .name = "imx_pcie", + .id = UCLASS_PCI, + .of_match = imx_pcie_ids, + .ops = &imx_pcie_ops, + .probe = imx_pcie_dm_probe, + .remove = imx_pcie_dm_remove, + .ofdata_to_platdata = imx_pcie_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct imx_pcie_priv), + .flags = DM_FLAG_OS_PREPARE, +}; +#endif

On Sat, May 18, 2019 at 2:26 AM Marek Vasut marex@denx.de wrote:
Add DM support and support for probing the iMX PCI driver from DT. The legacy non-DM support is retained, however shall be removed once DM PCI is the only option remaining.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de
drivers/pci/pcie_imx.c | 111 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 6 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Sat, May 18, 2019 at 2:26 AM Marek Vasut marex@denx.de wrote:
The DM iMX PCI driver has DM_FLAG_OS_PREPARE set and will call imx_pcie_remove() from the .remove callback. Do not call it from the architecture code again.
Signed-off-by: Marek Vasut marex@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Stefano Babic sbabic@denx.de
arch/arm/mach-imx/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
participants (2)
-
Bin Meng
-
Marek Vasut