Hi Stefan, On Sat, Jan 19, 2019 at 12:51 AM Stefan Roese <[email protected]> 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 <[email protected]> > Cc: Dirk Eibach <[email protected]> > Cc: Mario Six <[email protected]> > Cc: Chris Packham <[email protected]> > Cc: Phil Sutter <[email protected]> > Cc: Marek BehĂșn <[email protected]> > Cc: VlaoMao <[email protected]>
A couple of minor comments below. With them taken care of Reviewed-by: Chris Packham <[email protected]> Tested-by: Chris Packham <[email protected]> > --- > 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 > [email protected] > https://lists.denx.de/listinfo/u-boot _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

