[U-Boot] [PATCH 1/3 v2] pci: pci_mvebu: Add DM_PCI support and move CONFIG_PCI_MVEBU to defconfig
Chris Packham
judge.packham at gmail.com
Tue Jan 22 07:35:04 UTC 2019
Hi Stefan,
On Sat, Jan 19, 2019 at 12:51 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>
A couple of minor comments below. With them taken care of
Reviewed-by: Chris Packham <judge.packham at gmail.com>
Tested-by: Chris Packham <judge.packham at gmail.com>
> ---
> v2:
> - Completely configure the controller based on DT properties. Now
> port and lane are read from the DT nodes and also the tgt and
> attr values are generated using the DT similar to how this is
> done in the Linux driver version. All A38x / XP specific defines
> can now be removed from this driver because of this.
> - Please note that now the board specific dts file needs to enable
> the used PCIe ports, as this is also done in Linux.
>
> 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 | 457 ++++++++++++++++------------
> 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, 287 insertions(+), 209 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
Now that it's been merged you'll need the following for the x530_defconfig
---8<---
Subject: [PATCH] fixup! pci: pci_mvebu: Add DM_PCI support and move
CONFIG_PCI_MVEBU to defconfig
---
configs/x530_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/configs/x530_defconfig b/configs/x530_defconfig
index 22482f8d39be..6014aaa32134 100644
--- a/configs/x530_defconfig
+++ b/configs/x530_defconfig
@@ -57,6 +57,8 @@ CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_SST=y
CONFIG_MTD_UBI=y
CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
CONFIG_DM_RTC=y
CONFIG_RTC_DS1307=y
CONFIG_DEBUG_UART_SHIFT=2
--
---8<---
> 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..a03b979692 100644
> --- a/drivers/pci/pci_mvebu.c
> +++ b/drivers/pci/pci_mvebu.c
> @@ -10,11 +10,16 @@
> */
>
> #include <common.h>
> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <dm/lists.h>
> +#include <dm/of_access.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/ioport.h>
> #include <linux/mbus.h>
>
> DECLARE_GLOBAL_DATA_PTR;
> @@ -59,26 +64,22 @@ DECLARE_GLOBAL_DATA_PTR;
> #define PCIE_DEBUG_CTRL 0x1a60
> #define PCIE_DEBUG_SOFT_RESET BIT(20)
>
> -struct resource {
> - u32 start;
> - u32 end;
> -};
> -
> struct mvebu_pcie {
> struct pci_controller hose;
> - char *name;
> void __iomem *base;
> void __iomem *membase;
> struct resource mem;
> void __iomem *iobase;
> u32 port;
> u32 lane;
> + int devfn;
> u32 lane_mask;
> pci_dev_t dev;
> + char name[16];
> + unsigned int mem_target;
> + unsigned 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
> @@ -87,82 +88,6 @@ struct mvebu_pcie {
> 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
> - * 1 - Port 1.0
> - * 2 - Port 2.0
> - * 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)
> -{
> - u8 port[] = { 0, 1, 2, 3 };
> - u8 lane[] = { 0, 0, 0, 0 };
> - u8 target[] = { 8, 4, 4, 4 };
> - u8 attr[] = { 0xe8, 0xe8, 0xd8, 0xb8 };
> -
> - pcie->port = port[pex_idx];
> - pcie->lane = lane[pex_idx];
> - *mem_target = target[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
> - * 1 - Port 0.1
> - * 2 - Port 0.2
> - * 3 - Port 0.3
> - * 4 - Port 1.0
> - * 5 - Port 1.1
> - * 6 - Port 1.2
> - * 7 - Port 1.3
> - * 8 - Port 2.0
> - * 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)
> -{
> - u8 port[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 3 };
> - u8 lane[] = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 0 };
> - u8 target[] = { 4, 4, 4, 4, 8, 8, 8, 8, 4, 8 };
> - u8 attr[] = { 0xe8, 0xd8, 0xb8, 0x78,
> - 0xe8, 0xd8, 0xb8, 0x78,
> - 0xf8, 0xf8 };
> -
> - pcie->port = port[pex_idx];
> - pcie->lane = lane[pex_idx];
> - *mem_target = target[pex_idx];
> - *mem_attr = attr[pex_idx];
> -}
> -#endif
> -
> -static int mvebu_pex_unit_is_x4(int pex_idx)
> -{
> - int pex_unit = pex_idx < 9 ? pex_idx >> 2 : 3;
> - u32 mask = (0x0f << (pex_unit * 8));
> -
> - return (readl(COMPHY_REFCLK_ALIGNMENT) & mask) == mask;
> -}
> -
> static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
> {
> u32 val;
> @@ -211,67 +136,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 +272,241 @@ 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
Typo? Should this be be mvebu_pcie_probe? Or nothing since the
function name is just below.
> + *
> + * @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));
> +
> + 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));
>
> - for (i = 0; i < MAX_PEX; i++) {
> - struct mvebu_pcie *pcie = &pcie_bus[i];
> - struct pci_controller *hose = &pcie->hose;
> + /* 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;
> +}
> +
> +#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
> +#define DT_TYPE_IO 0x1
> +#define DT_TYPE_MEM32 0x2
> +#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
> +#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
> +
> +static int mvebu_get_tgt_attr(ofnode node, int devfn,
> + unsigned long type,
> + unsigned int *tgt,
> + unsigned int *attr)
> +{
> + const int na = 3, ns = 2;
> + const __be32 *range;
> + int rlen, nranges, rangesz, pna, i;
> +
> + *tgt = -1;
> + *attr = -1;
> +
> + range = ofnode_get_property(node, "ranges", &rlen);
> + if (!range)
> + return -EINVAL;
> +
> + pna = 2; /* hardcoded for now because of lack of of_n_addr_cells() */
> + rangesz = pna + na + ns;
> + nranges = rlen / sizeof(__be32) / rangesz;
> +
> + for (i = 0; i < nranges; i++, range += rangesz) {
> + u32 flags = of_read_number(range, 1);
> + u32 slot = of_read_number(range + 1, 1);
> + u64 cpuaddr = of_read_number(range + na, pna);
> + unsigned long rtype;
> +
> + if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
> + rtype = IORESOURCE_IO;
> + else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
> + rtype = IORESOURCE_MEM;
> + else
> + continue;
> +
> + if (slot == PCI_SLOT(devfn) && type == rtype) {
> + *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
> + *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
> + return 0;
> + }
> + }
> +
> + return -ENOENT;
> +}
> +
> +/*
> + * 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;
> + int ret;
> +
> + /* 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)) {
> + if (!ofnode_is_available(subnode))
> + continue;
> +
> + 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);
> + if (ofnode_read_u32(subnode, "marvell,pcie-port",
> + &pcie->port)) {
> + free(pcie);
> + continue;
> + }
> +
> + if (ofnode_read_u32(subnode, "marvell,pcie-lane", &pcie->lane))
> + pcie->lane = 0;
>
> - /* 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);
> + sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane);
> +
> + pcie->devfn = ofnode_pci_get_devfn(subnode);
> + if (pcie->devfn < 0) {
> + free(pcie);
> continue;
> }
>
> - pcie->base = (void __iomem *)PCIE_BASE(i);
> + ret = mvebu_get_tgt_attr(dev_ofnode(parent), pcie->devfn,
> + IORESOURCE_MEM,
> + &pcie->mem_target, &pcie->mem_attr);
> + if (ret < 0) {
> + printf("%s: cannot get tgt/attr for mem window\n",
> + pcie->name);
> + free(pcie);
> + continue;
> + }
> +
> + /* Parse PCIe controller register base from DT */
> + ret = mvebu_pcie_port_parse_dt(subnode, pcie);
> + if (ret < 0) {
> + 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);
> +
> + 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;
> -
> - /* 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))
> - i += 3;
> - }
> + /* Create child device UCLASS_PCI and bind it */
> + device_bind_ofnode(parent, &pcie_mvebu_drv, pcie->name, pcie,
> + subnode, &dev);
> }
> +
> + 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