[U-Boot] [PATCH 1/2] pci: pci_mvebu: Add DM_PCI support and move CONFIG_PCI_MVEBU to defconfig

Chris Packham judge.packham at gmail.com
Fri Jan 18 08:53:34 UTC 2019


Hi Stefan,

On Fri, Jan 18, 2019 at 2:35 AM Stefan Roese <sr at denx.de> wrote:
>
> This patch adds DM_PCI support to the MVEBU PCIe driver. This is
> necessary, since all PCI drivers have to be moved to DM (driver model)
> until the v2019.07 release.
>
> To not break git bisect'ablility, this patch also moves CONFIG_PCI_MVEBU
> from config headers to the defconfig files.
>
> Signed-off-by: Stefan Roese <sr at denx.de>
> Cc: Dirk Eibach <dirk.eibach at gdsys.cc>
> Cc: Mario Six <mario.six at gdsys.cc>
> Cc: Chris Packham <chris.packham at alliedtelesis.co.nz>
> Cc: Phil Sutter <phil at nwl.cc>
> Cc: Marek BehĂșn <marek.behun at nic.cz>
> Cc: VlaoMao <vlaomao at gmail.com>

Reviewed-by: Chris Packham <chris.packham at alliedtelesis.co.nz>

The db-88f6820-amc board I have is just standalone so it has no PCI
devices connected. But the driver compiles and the controller shows up
in dm tree. A slightly more useful test is on the atl-x530 which has a
PCI device attached to it.

=> pci enum
=> pci
Scanning PCI devices on bus 0
BusDevFun  VendorId   DeviceId   Device Class       Sub-Class
_____________________________________________________________
00.00.00   0x11ab     0x6820     Memory controller       0x80
00.01.00   0x11ab     0xc804     Network controller      0x00

That network controller listed is a switch ASIC which is not likely to
see a u-boot driver any time soon. So I can't test operation of the
pci devices on top of the bus but I can poke at config registers.

Tested-by: Chris Packham <chris.packham at alliedtelesis.co.nz>

> ---
>  configs/clearfog_defconfig          |   1 +
>  configs/controlcenterdc_defconfig   |   3 +
>  configs/db-88f6820-amc_defconfig    |   1 +
>  configs/db-88f6820-gp_defconfig     |   1 +
>  configs/db-mv784mp-gp_defconfig     |   1 +
>  configs/ds414_defconfig             |   1 +
>  configs/theadorable_debug_defconfig |   2 +
>  configs/turris_omnia_defconfig      |   3 +-
>  drivers/pci/Kconfig                 |   9 +
>  drivers/pci/pci_mvebu.c             | 329 ++++++++++++++++++----------
>  include/configs/clearfog.h          |   1 -
>  include/configs/controlcenterdc.h   |   3 -
>  include/configs/db-88f6820-amc.h    |   1 -
>  include/configs/db-88f6820-gp.h     |   1 -
>  include/configs/db-mv784mp-gp.h     |   1 -
>  include/configs/ds414.h             |   1 -
>  include/configs/theadorable.h       |   7 -
>  include/configs/turris_omnia.h      |   1 -
>  scripts/config_whitelist.txt        |   1 -
>  19 files changed, 236 insertions(+), 132 deletions(-)
>
> diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig
> index e1c5a1fa13..0f69ff606d 100644
> --- a/configs/clearfog_defconfig
> +++ b/configs/clearfog_defconfig
> @@ -56,6 +56,7 @@ CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
>  CONFIG_PCI=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_SCSI=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
> diff --git a/configs/controlcenterdc_defconfig b/configs/controlcenterdc_defconfig
> index 0c762ad77c..f22a3ab819 100644
> --- a/configs/controlcenterdc_defconfig
> +++ b/configs/controlcenterdc_defconfig
> @@ -58,6 +58,9 @@ CONFIG_PHY_MARVELL=y
>  CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
> +CONFIG_PCI=y
> +CONFIG_DM_PCI_COMPAT=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_SCSI=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
> diff --git a/configs/db-88f6820-amc_defconfig b/configs/db-88f6820-amc_defconfig
> index 9068a58406..03bf2bcafc 100644
> --- a/configs/db-88f6820-amc_defconfig
> +++ b/configs/db-88f6820-amc_defconfig
> @@ -60,6 +60,7 @@ CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
>  CONFIG_PCI=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
>  CONFIG_KIRKWOOD_SPI=y
> diff --git a/configs/db-88f6820-gp_defconfig b/configs/db-88f6820-gp_defconfig
> index 413010c4ef..b36b7c3b2c 100644
> --- a/configs/db-88f6820-gp_defconfig
> +++ b/configs/db-88f6820-gp_defconfig
> @@ -56,6 +56,7 @@ CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
>  CONFIG_PCI=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_SCSI=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
> diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig
> index 3f140986b6..b6c61c3a48 100644
> --- a/configs/db-mv784mp-gp_defconfig
> +++ b/configs/db-mv784mp-gp_defconfig
> @@ -55,6 +55,7 @@ CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
>  CONFIG_PCI=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
>  CONFIG_KIRKWOOD_SPI=y
> diff --git a/configs/ds414_defconfig b/configs/ds414_defconfig
> index 5325bd9968..32f37440c3 100644
> --- a/configs/ds414_defconfig
> +++ b/configs/ds414_defconfig
> @@ -52,6 +52,7 @@ CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
>  CONFIG_PCI=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
>  CONFIG_KIRKWOOD_SPI=y
> diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig
> index 9e99618998..ac6dfd6844 100644
> --- a/configs/theadorable_debug_defconfig
> +++ b/configs/theadorable_debug_defconfig
> @@ -62,6 +62,8 @@ CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
>  CONFIG_PCI=y
> +CONFIG_DM_PCI_COMPAT=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
>  CONFIG_KIRKWOOD_SPI=y
> diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
> index 4a1e23c86c..5cafe2ee34 100644
> --- a/configs/turris_omnia_defconfig
> +++ b/configs/turris_omnia_defconfig
> @@ -37,7 +37,6 @@ CONFIG_DEFAULT_DEVICE_TREE="armada-385-turris-omnia"
>  CONFIG_ENV_IS_IN_SPI_FLASH=y
>  CONFIG_SPL_OF_TRANSLATE=y
>  CONFIG_SCSI_AHCI=y
> -CONFIG_MISC=y
>  CONFIG_ATSHA204A=y
>  CONFIG_MMC_SDHCI=y
>  CONFIG_MMC_SDHCI_MV=y
> @@ -45,6 +44,8 @@ CONFIG_PHY_MARVELL=y
>  CONFIG_PHY_GIGE=y
>  CONFIG_MVNETA=y
>  CONFIG_MII=y
> +CONFIG_PCI=y
> +CONFIG_PCI_MVEBU=y
>  CONFIG_DEBUG_UART_SHIFT=2
>  CONFIG_SYS_NS16550=y
>  CONFIG_KIRKWOOD_SPI=y
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index f59803dbd6..1521885bde 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -112,4 +112,13 @@ config PCIE_INTEL_FPGA
>           Say Y here if you want to enable PCIe controller support on Intel
>           FPGA, example Stratix 10.
>
> +config PCI_MVEBU
> +       bool "Enable Armada XP/38x PCIe driver"
> +       depends on ARCH_MVEBU
> +       select DM_PCI
> +       select MISC
> +       help
> +         Say Y here if you want to enable PCIe controller support on
> +         Armada XP/38x SoCs.
> +
>  endif
> diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
> index affe9f98ad..57d62b3493 100644
> --- a/drivers/pci/pci_mvebu.c
> +++ b/drivers/pci/pci_mvebu.c
> @@ -10,11 +10,14 @@
>   */
>
>  #include <common.h>
> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <dm/lists.h>
>  #include <pci.h>
> -#include <linux/errno.h>
>  #include <asm/io.h>
>  #include <asm/arch/cpu.h>
>  #include <asm/arch/soc.h>
> +#include <linux/errno.h>
>  #include <linux/mbus.h>
>
>  DECLARE_GLOBAL_DATA_PTR;
> @@ -66,7 +69,6 @@ struct resource {
>
>  struct mvebu_pcie {
>         struct pci_controller hose;
> -       char *name;
>         void __iomem *base;
>         void __iomem *membase;
>         struct resource mem;
> @@ -75,10 +77,11 @@ struct mvebu_pcie {
>         u32 lane;
>         u32 lane_mask;
>         pci_dev_t dev;
> +       char name[16];
> +       int mem_target;
> +       int mem_attr;
>  };
>
> -#define to_pcie(_hc)   container_of(_hc, struct mvebu_pcie, pci)
> -
>  /*
>   * MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
>   * into SoCs address space. Each controller will map 128M of MEM
> @@ -88,11 +91,6 @@ static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
>  #define PCIE_MEM_SIZE  (128 << 20)
>
>  #if defined(CONFIG_ARMADA_38X)
> -#define PCIE_BASE(if)                                  \
> -       ((if) == 0 ?                                    \
> -        MVEBU_REG_PCIE0_BASE :                         \
> -        (MVEBU_REG_PCIE_BASE + 0x4000 * (if - 1)))
> -
>  /*
>   * On A38x MV6820 these PEX ports are supported:
>   *  0 - Port 0.0
> @@ -101,7 +99,6 @@ static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
>   *  3 - Port 3.0
>   */
>  #define MAX_PEX 4
> -static struct mvebu_pcie pcie_bus[MAX_PEX];
>
>  static void mvebu_get_port_lane(struct mvebu_pcie *pcie, int pex_idx,
>                                 int *mem_target, int *mem_attr)
> @@ -117,11 +114,6 @@ static void mvebu_get_port_lane(struct mvebu_pcie *pcie, int pex_idx,
>         *mem_attr = attr[pex_idx];
>  }
>  #else
> -#define PCIE_BASE(if)                                                  \
> -       ((if) < 8 ?                                                     \
> -        (MVEBU_REG_PCIE_BASE + ((if) / 4) * 0x40000 + ((if) % 4) * 0x4000) : \
> -        (MVEBU_REG_PCIE_BASE + 0x2000 + ((if) % 8) * 0x40000))
> -
>  /*
>   * On AXP MV78460 these PEX ports are supported:
>   *  0 - Port 0.0
> @@ -136,7 +128,6 @@ static void mvebu_get_port_lane(struct mvebu_pcie *pcie, int pex_idx,
>   *  9 - Port 3.0
>   */
>  #define MAX_PEX 10
> -static struct mvebu_pcie pcie_bus[MAX_PEX];
>
>  static void mvebu_get_port_lane(struct mvebu_pcie *pcie, int pex_idx,
>                                 int *mem_target, int *mem_attr)
> @@ -155,6 +146,10 @@ static void mvebu_get_port_lane(struct mvebu_pcie *pcie, int pex_idx,
>  }
>  #endif
>
> +struct mvebu_pcie_base {
> +       struct mvebu_pcie pcie[MAX_PEX];
> +};
> +
>  static int mvebu_pex_unit_is_x4(int pex_idx)
>  {
>         int pex_unit = pex_idx < 9 ? pex_idx >> 2 : 3;
> @@ -211,67 +206,83 @@ static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
>         return container_of(hose, struct mvebu_pcie, hose);
>  }
>
> -static int mvebu_pcie_read_config_dword(struct pci_controller *hose,
> -               pci_dev_t dev, int offset, u32 *val)
> +static int mvebu_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
> +                                 uint offset, ulong *valuep,
> +                                 enum pci_size_t size)
>  {
> -       struct mvebu_pcie *pcie = hose_to_pcie(hose);
> +       struct mvebu_pcie *pcie = dev_get_platdata(bus);
>         int local_bus = PCI_BUS(pcie->dev);
>         int local_dev = PCI_DEV(pcie->dev);
>         u32 reg;
> +       u32 data;
> +
> +       debug("PCIE CFG read:  (b,d,f)=(%2d,%2d,%2d) ",
> +             PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
>
>         /* Only allow one other device besides the local one on the local bus */
> -       if (PCI_BUS(dev) == local_bus && PCI_DEV(dev) != local_dev) {
> -               if (local_dev == 0 && PCI_DEV(dev) != 1) {
> +       if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) != local_dev) {
> +               if (local_dev == 0 && PCI_DEV(bdf) != 1) {
> +                       debug("- out of range\n");
>                         /*
>                          * If local dev is 0, the first other dev can
>                          * only be 1
>                          */
> -                       *val = 0xffffffff;
> -                       return 1;
> -               } else if (local_dev != 0 && PCI_DEV(dev) != 0) {
> +                       *valuep = pci_get_ff(size);
> +                       return 0;
> +               } else if (local_dev != 0 && PCI_DEV(bdf) != 0) {
> +                       debug("- out of range\n");
>                         /*
>                          * If local dev is not 0, the first other dev can
>                          * only be 0
>                          */
> -                       *val = 0xffffffff;
> -                       return 1;
> +                       *valuep = pci_get_ff(size);
> +                       return 0;
>                 }
>         }
>
>         /* write address */
> -       reg = PCIE_CONF_ADDR(dev, offset);
> +       reg = PCIE_CONF_ADDR(bdf, offset);
>         writel(reg, pcie->base + PCIE_CONF_ADDR_OFF);
> -       *val = readl(pcie->base + PCIE_CONF_DATA_OFF);
> +       data = readl(pcie->base + PCIE_CONF_DATA_OFF);
> +       debug("(addr,val)=(0x%04x, 0x%08x)\n", offset, data);
> +       *valuep = pci_conv_32_to_size(data, offset, size);
>
>         return 0;
>  }
>
> -static int mvebu_pcie_write_config_dword(struct pci_controller *hose,
> -               pci_dev_t dev, int offset, u32 val)
> +static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
> +                                  uint offset, ulong value,
> +                                  enum pci_size_t size)
>  {
> -       struct mvebu_pcie *pcie = hose_to_pcie(hose);
> +       struct mvebu_pcie *pcie = dev_get_platdata(bus);
>         int local_bus = PCI_BUS(pcie->dev);
>         int local_dev = PCI_DEV(pcie->dev);
> +       u32 data;
> +
> +       debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
> +             PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
> +       debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
>
>         /* Only allow one other device besides the local one on the local bus */
> -       if (PCI_BUS(dev) == local_bus && PCI_DEV(dev) != local_dev) {
> -               if (local_dev == 0 && PCI_DEV(dev) != 1) {
> +       if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) != local_dev) {
> +               if (local_dev == 0 && PCI_DEV(bdf) != 1) {
>                         /*
>                          * If local dev is 0, the first other dev can
>                          * only be 1
>                          */
> -                       return 1;
> -               } else if (local_dev != 0 && PCI_DEV(dev) != 0) {
> +                       return 0;
> +               } else if (local_dev != 0 && PCI_DEV(bdf) != 0) {
>                         /*
>                          * If local dev is not 0, the first other dev can
>                          * only be 0
>                          */
> -                       return 1;
> +                       return 0;
>                 }
>         }
>
> -       writel(PCIE_CONF_ADDR(dev, offset), pcie->base + PCIE_CONF_ADDR_OFF);
> -       writel(val, pcie->base + PCIE_CONF_DATA_OFF);
> +       writel(PCIE_CONF_ADDR(bdf, offset), pcie->base + PCIE_CONF_ADDR_OFF);
> +       data = pci_conv_size_to_32(0, value, offset, size);
> +       writel(data, pcie->base + PCIE_CONF_DATA_OFF);
>
>         return 0;
>  }
> @@ -331,107 +342,197 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
>                pcie->base + PCIE_BAR_CTRL_OFF(1));
>  }
>
> -void pci_init_board(void)
> +/**
> + * pcie_dw_mvebu_probe() - Probe the PCIe bus for active link
> + *
> + * @dev: A pointer to the device being operated on
> + *
> + * Probe for an active link on the PCIe bus and configure the controller
> + * to enable this port.
> + *
> + * Return: 0 on success, else -ENODEV
> + */
> +static int mvebu_pcie_probe(struct udevice *dev)
>  {
> -       int mem_target, mem_attr, i;
> -       int bus = 0;
> +       struct mvebu_pcie *pcie = dev_get_platdata(dev);
> +       struct udevice *ctlr = pci_get_controller(dev);
> +       struct pci_controller *hose = dev_get_uclass_priv(ctlr);
> +       static int bus;
>         u32 reg;
> -       u32 soc_ctrl = readl(MVEBU_SYSTEM_REG_BASE + 0x4);
>
> -       /* Check SoC Control Power State */
> -       debug("%s: SoC Control %08x, 0en %01lx, 1en %01lx, 2en %01lx\n",
> -             __func__, soc_ctrl, SELECT(soc_ctrl, 0), SELECT(soc_ctrl, 1),
> -             SELECT(soc_ctrl, 2));
> +       debug("%s: PCIe %d.%d - up, base %08x\n", __func__,
> +             pcie->port, pcie->lane, (u32)pcie->base);
> +
> +       /* Read Id info and local bus/dev */
> +       debug("direct conf read %08x, local bus %d, local dev %d\n",
> +             readl(pcie->base), mvebu_pcie_get_local_bus_nr(pcie),
> +             mvebu_pcie_get_local_dev_nr(pcie));
>
> -       for (i = 0; i < MAX_PEX; i++) {
> -               struct mvebu_pcie *pcie = &pcie_bus[i];
> -               struct pci_controller *hose = &pcie->hose;
> +       mvebu_pcie_set_local_bus_nr(pcie, bus);
> +       mvebu_pcie_set_local_dev_nr(pcie, 0);
> +       pcie->dev = PCI_BDF(bus, 0, 0);
> +
> +       pcie->mem.start = (u32)mvebu_pcie_membase;
> +       pcie->mem.end = pcie->mem.start + PCIE_MEM_SIZE - 1;
> +       mvebu_pcie_membase += PCIE_MEM_SIZE;
> +
> +       if (mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
> +                                       (phys_addr_t)pcie->mem.start,
> +                                       PCIE_MEM_SIZE)) {
> +               printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
> +                      (u32)pcie->mem.start, PCIE_MEM_SIZE);
> +       }
> +
> +       /* Setup windows and configure host bridge */
> +       mvebu_pcie_setup_wins(pcie);
> +
> +       /* Master + slave enable. */
> +       reg = readl(pcie->base + PCIE_CMD_OFF);
> +       reg |= PCI_COMMAND_MEMORY;
> +       reg |= PCI_COMMAND_MASTER;
> +       reg |= BIT(10);         /* disable interrupts */
> +       writel(reg, pcie->base + PCIE_CMD_OFF);
> +
> +       /* Set BAR0 to internal registers */
> +       writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
> +       writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
> +
> +       /* PCI memory space */
> +       pci_set_region(hose->regions + 0, pcie->mem.start,
> +                      pcie->mem.start, PCIE_MEM_SIZE, PCI_REGION_MEM);
> +       pci_set_region(hose->regions + 1,
> +                      0, 0,
> +                      gd->ram_size,
> +                      PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
> +       hose->region_count = 2;
> +
> +       bus++;
> +
> +       return 0;
> +}
> +
> +static const struct dm_pci_ops mvebu_pcie_ops = {
> +       .read_config    = mvebu_pcie_read_config,
> +       .write_config   = mvebu_pcie_write_config,
> +};
> +
> +static struct driver pcie_mvebu_drv = {
> +       .name                   = "pcie_mvebu",
> +       .id                     = UCLASS_PCI,
> +       .ops                    = &mvebu_pcie_ops,
> +       .probe                  = mvebu_pcie_probe,
> +       .platdata_auto_alloc_size = sizeof(struct mvebu_pcie),
> +};
> +
> +static int mvebu_pcie_port_parse_dt(ofnode node, struct mvebu_pcie *pcie)
> +{
> +       const u32 *addr;
> +       int len;
> +
> +       addr = ofnode_get_property(node, "assigned-addresses", &len);
> +       if (!addr) {
> +               pr_err("property \"assigned-addresses\" not found");
> +               return -FDT_ERR_NOTFOUND;
> +       }
> +
> +       pcie->base = (void *)(fdt32_to_cpu(addr[2]) + SOC_REGS_PHY_BASE);
> +
> +       return 0;
> +}
> +
> +/*
> + * Use a MISC device to bind the n instances (child nodes) of the
> + * PCIe base controller in UCLASS_PCI.
> + */
> +static int mvebu_pcie_bind(struct udevice *parent)
> +{
> +       struct mvebu_pcie *pcie;
> +       struct uclass_driver *drv;
> +       struct udevice *dev;
> +       ofnode subnode;
> +       u32 soc_ctrl;
> +       int port = 0;
> +       int i = 0;
> +       int ret;
> +
> +       soc_ctrl = readl(MVEBU_SYSTEM_REG_BASE + 0x4);
> +
> +       /* Lookup eth driver */
> +       drv = lists_uclass_lookup(UCLASS_PCI);
> +       if (!drv) {
> +               puts("Cannot find PCI driver\n");
> +               return -ENOENT;
> +       }
> +
> +       ofnode_for_each_subnode(subnode, dev_ofnode(parent)) {
> +               pcie = calloc(1, sizeof(*pcie));
> +               if (!pcie)
> +                       return -ENOMEM;
>
>                 /* Get port number, lane number and memory target / attr */
> -               mvebu_get_port_lane(pcie, i, &mem_target, &mem_attr);
> +               mvebu_get_port_lane(pcie, i,
> +                                   &pcie->mem_target, &pcie->mem_attr);
>
>                 /* Don't read at all from pci registers if port power is down */
>                 if (SELECT(soc_ctrl, pcie->port) == 0) {
>                         if (pcie->lane == 0)
> -                               debug("%s: skipping port %d\n", __func__, pcie->port);
> +                               debug("%s: skipping port %d\n", __func__,
> +                                     pcie->port);
> +                       i++;
> +                       free(pcie);
>                         continue;
>                 }
>
> -               pcie->base = (void __iomem *)PCIE_BASE(i);
> +               /* Parse PCIe controller register base from DT */
> +               ret = mvebu_pcie_port_parse_dt(subnode, pcie);
> +               if (ret < 0) {
> +                       i++;
> +                       free(pcie);
> +                       continue;
> +               }
>
>                 /* Check link and skip ports that have no link */
>                 if (!mvebu_pcie_link_up(pcie)) {
>                         debug("%s: PCIe %d.%d - down\n", __func__,
>                               pcie->port, pcie->lane);
> +
> +                       i++;
> +                       free(pcie);
>                         continue;
>                 }
> -               debug("%s: PCIe %d.%d - up, base %08x\n", __func__,
> -                     pcie->port, pcie->lane, (u32)pcie->base);
> -
> -               /* Read Id info and local bus/dev */
> -               debug("direct conf read %08x, local bus %d, local dev %d\n",
> -                     readl(pcie->base), mvebu_pcie_get_local_bus_nr(pcie),
> -                     mvebu_pcie_get_local_dev_nr(pcie));
> -
> -               mvebu_pcie_set_local_bus_nr(pcie, bus);
> -               mvebu_pcie_set_local_dev_nr(pcie, 0);
> -               pcie->dev = PCI_BDF(bus, 0, 0);
> -
> -               pcie->mem.start = (u32)mvebu_pcie_membase;
> -               pcie->mem.end = pcie->mem.start + PCIE_MEM_SIZE - 1;
> -               mvebu_pcie_membase += PCIE_MEM_SIZE;
> -
> -               if (mvebu_mbus_add_window_by_id(mem_target, mem_attr,
> -                                               (phys_addr_t)pcie->mem.start,
> -                                               PCIE_MEM_SIZE)) {
> -                       printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
> -                              (u32)pcie->mem.start, PCIE_MEM_SIZE);
> -               }
>
> -               /* Setup windows and configure host bridge */
> -               mvebu_pcie_setup_wins(pcie);
> -
> -               /* Master + slave enable. */
> -               reg = readl(pcie->base + PCIE_CMD_OFF);
> -               reg |= PCI_COMMAND_MEMORY;
> -               reg |= PCI_COMMAND_MASTER;
> -               reg |= BIT(10);         /* disable interrupts */
> -               writel(reg, pcie->base + PCIE_CMD_OFF);
> -
> -               /* Setup U-Boot PCI Controller */
> -               hose->first_busno = 0;
> -               hose->current_busno = bus;
> -
> -               /* PCI memory space */
> -               pci_set_region(hose->regions + 0, pcie->mem.start,
> -                              pcie->mem.start, PCIE_MEM_SIZE, PCI_REGION_MEM);
> -               pci_set_region(hose->regions + 1,
> -                              0, 0,
> -                              gd->ram_size,
> -                              PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
> -               hose->region_count = 2;
> -
> -               pci_set_ops(hose,
> -                           pci_hose_read_config_byte_via_dword,
> -                           pci_hose_read_config_word_via_dword,
> -                           mvebu_pcie_read_config_dword,
> -                           pci_hose_write_config_byte_via_dword,
> -                           pci_hose_write_config_word_via_dword,
> -                           mvebu_pcie_write_config_dword);
> -               pci_register_hose(hose);
> -
> -               hose->last_busno = pci_hose_scan(hose);
> -
> -               /* Set BAR0 to internal registers */
> -               writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
> -               writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
> -
> -               bus = hose->last_busno + 1;
> +               sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane);
> +
> +               /* Create child device UCLASS_PCI and bind it */
> +               device_bind_ofnode(parent, &pcie_mvebu_drv, pcie->name, pcie,
> +                                  subnode, &dev);
>
>                 /* need to skip more for X4 links, otherwise scan will hang */
>                 if (mvebu_soc_family() == MVEBU_SOC_AXP) {
> -                       if (mvebu_pex_unit_is_x4(i))
> +                       if (mvebu_pex_unit_is_x4(i)) {
> +                               subnode = ofnode_next_subnode(subnode);
> +                               subnode = ofnode_next_subnode(subnode);
> +                               subnode = ofnode_next_subnode(subnode);
>                                 i += 3;
> +                       }
>                 }
> +
> +               i++;
> +               port++;
>         }
> +
> +       return 0;
>  }
> +
> +static const struct udevice_id mvebu_pcie_ids[] = {
> +       { .compatible = "marvell,armada-xp-pcie" },
> +       { .compatible = "marvell,armada-370-pcie" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(pcie_mvebu_base) = {
> +       .name                   = "pcie_mvebu_base",
> +       .id                     = UCLASS_MISC,
> +       .of_match               = mvebu_pcie_ids,
> +       .bind                   = mvebu_pcie_bind,
> +};
> diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h
> index 77ab6caf52..f9510826d7 100644
> --- a/include/configs/clearfog.h
> +++ b/include/configs/clearfog.h
> @@ -55,7 +55,6 @@
>
>  /* PCIe support */
>  #ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI_MVEBU
>  #define CONFIG_PCI_SCAN_SHOW
>  #endif
>
> diff --git a/include/configs/controlcenterdc.h b/include/configs/controlcenterdc.h
> index b38cab1164..06c93c3e66 100644
> --- a/include/configs/controlcenterdc.h
> +++ b/include/configs/controlcenterdc.h
> @@ -63,9 +63,6 @@
>
>  /* PCIe support */
>  #ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI
> -#define CONFIG_PCI_MVEBU
> -#define CONFIG_PCI_PNP
>  #define CONFIG_PCI_SCAN_SHOW
>  #endif
>
> diff --git a/include/configs/db-88f6820-amc.h b/include/configs/db-88f6820-amc.h
> index e68246cc0f..626a406cff 100644
> --- a/include/configs/db-88f6820-amc.h
> +++ b/include/configs/db-88f6820-amc.h
> @@ -34,7 +34,6 @@
>
>  /* PCIe support */
>  #ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI_MVEBU
>  #define CONFIG_PCI_SCAN_SHOW
>  #endif
>
> diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h
> index 3900cbed2d..1f328e97c5 100644
> --- a/include/configs/db-88f6820-gp.h
> +++ b/include/configs/db-88f6820-gp.h
> @@ -59,7 +59,6 @@
>
>  /* PCIe support */
>  #ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI_MVEBU
>  #define CONFIG_PCI_SCAN_SHOW
>  #endif
>
> diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h
> index 8ad007cc49..6cba326927 100644
> --- a/include/configs/db-mv784mp-gp.h
> +++ b/include/configs/db-mv784mp-gp.h
> @@ -46,7 +46,6 @@
>
>  /* PCIe support */
>  #ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI_MVEBU
>  #define CONFIG_PCI_SCAN_SHOW
>  #endif
>
> diff --git a/include/configs/ds414.h b/include/configs/ds414.h
> index b9b708ad41..4ba050553a 100644
> --- a/include/configs/ds414.h
> +++ b/include/configs/ds414.h
> @@ -41,7 +41,6 @@
>
>  /* PCIe support */
>  #ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI_MVEBU
>  #define CONFIG_PCI_SCAN_SHOW
>  #endif
>
> diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h
> index de31681f8c..6837d55507 100644
> --- a/include/configs/theadorable.h
> +++ b/include/configs/theadorable.h
> @@ -62,13 +62,6 @@
>  #define CONFIG_SYS_SATA_MAX_DEVICE     1
>  #define CONFIG_LBA48
>
> -/* PCIe support */
> -#ifdef CONFIG_CMD_PCI
> -#ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI_MVEBU
> -#endif
> -#endif
> -
>  /* Enable LCD and reserve 512KB from top of memory*/
>  #define CONFIG_SYS_MEM_TOP_HIDE                0x80000
>
> diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h
> index 598674c96e..710b8991a4 100644
> --- a/include/configs/turris_omnia.h
> +++ b/include/configs/turris_omnia.h
> @@ -66,7 +66,6 @@
>
>  /* PCIe support */
>  #ifndef CONFIG_SPL_BUILD
> -#define CONFIG_PCI_MVEBU
>  #define CONFIG_PCI_SCAN_SHOW
>  #endif
>
> diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
> index 527050de97..da9809dcf3 100644
> --- a/scripts/config_whitelist.txt
> +++ b/scripts/config_whitelist.txt
> @@ -1449,7 +1449,6 @@ CONFIG_PCI_MEM_BUS
>  CONFIG_PCI_MEM_PHYS
>  CONFIG_PCI_MEM_SIZE
>  CONFIG_PCI_MSC01
> -CONFIG_PCI_MVEBU
>  CONFIG_PCI_NOSCAN
>  CONFIG_PCI_OHCI
>  CONFIG_PCI_OHCI_DEVNO
> --
> 2.20.1
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list