From b52142004fbdfd6db0091ba7ae33c91e3b459034 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 25 Jan 2019 11:52:42 +0100 Subject: [PATCH 1/7] pci: Add pci_get_devfn() to extract devfn from the fdt_pci_addr This function will be used by the Marvell Armada XP/38x PCIe driver, which is moved to DM right now. So let's extract the functionality from pci_uclass_child_post_bind() to make it available. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci-uclass.c | 28 +++++++++++++++++++--------- include/pci.h | 10 ++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 2cf55cb743..47f3cc9107 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1007,10 +1007,25 @@ static int pci_uclass_post_probe(struct udevice *bus) return 0; } +int pci_get_devfn(struct udevice *dev) +{ + struct fdt_pci_addr addr; + int ret; + + /* Extract the devfn from fdt_pci_addr */ + ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, + "reg", &addr); + if (ret) { + if (ret != -ENOENT) + return -EINVAL; + } + + return addr.phys_hi & 0xff00; +} + static int pci_uclass_child_post_bind(struct udevice *dev) { struct pci_child_platdata *pplat; - struct fdt_pci_addr addr; int ret; if (!dev_of_valid(dev)) @@ -1022,14 +1037,9 @@ static int pci_uclass_child_post_bind(struct udevice *dev) ofnode_read_pci_vendev(dev_ofnode(dev), &pplat->vendor, &pplat->device); /* Extract the devfn from fdt_pci_addr */ - ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, "reg", - &addr); - if (ret) { - if (ret != -ENOENT) - return -EINVAL; - } else { - pplat->devfn = addr.phys_hi & 0xff00; - } + pplat->devfn = pci_get_devfn(dev); + if (ret < 0) + return ret; return 0; } diff --git a/include/pci.h b/include/pci.h index 785d7d28b7..041f8e3747 100644 --- a/include/pci.h +++ b/include/pci.h @@ -1560,6 +1560,16 @@ struct dm_pci_emul_ops { int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, struct udevice **containerp, struct udevice **emulp); +/** + * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device + * + * Get devfn from fdt_pci_addr of the specifified device + * + * @dev: PCI device + * @return devfn in bits 15...8 if found, -ENODEV if not found + */ +int pci_get_devfn(struct udevice *dev); + #endif /* CONFIG_DM_PCI */ /** From 94f453ea38f52750d8da63e3745b548a9ee06dd4 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 25 Jan 2019 11:52:43 +0100 Subject: [PATCH 2/7] pci: pci_mvebu: Add DM_PCI support and move CONFIG_PCI_MVEBU to defconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Cc: Dirk Eibach Cc: Mario Six Cc: Chris Packham Cc: Phil Sutter Cc: Marek Behún Cc: VlaoMao --- 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 +- configs/x530_defconfig | 3 +- drivers/pci/Kconfig | 9 + drivers/pci/pci_mvebu.c | 476 ++++++++++++++++------------ 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 - include/configs/x530.h | 1 - scripts/config_whitelist.txt | 1 - 21 files changed, 299 insertions(+), 220 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/configs/x530_defconfig b/configs/x530_defconfig index 22482f8d39..25b9e885d8 100644 --- a/configs/x530_defconfig +++ b/configs/x530_defconfig @@ -46,7 +46,6 @@ CONFIG_DM_I2C=y CONFIG_SYS_I2C_MVTWSI=y CONFIG_I2C_MUX=y CONFIG_I2C_MUX_PCA954x=y -CONFIG_MISC=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_PXA3XX=y @@ -57,6 +56,8 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_SST=y CONFIG_MTD_UBI=y CONFIG_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCI_MVEBU=y CONFIG_DM_RTC=y CONFIG_RTC_DS1307=y CONFIG_DEBUG_UART_SHIFT=2 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..6026fa67f9 100644 --- a/drivers/pci/pci_mvebu.c +++ b/drivers/pci/pci_mvebu.c @@ -10,11 +10,16 @@ */ #include +#include +#include +#include +#include #include -#include #include #include #include +#include +#include #include 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,242 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie) pcie->base + PCIE_BAR_CTRL_OFF(1)); } -void pci_init_board(void) +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); - for (i = 0; i < MAX_PEX; i++) { - struct mvebu_pcie *pcie = &pcie_bus[i]; - struct pci_controller *hose = &pcie->hose; + /* 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)); - /* Get port number, lane number and memory target / attr */ - mvebu_get_port_lane(pcie, i, &mem_target, &mem_attr); + mvebu_pcie_set_local_bus_nr(pcie, bus); + mvebu_pcie_set_local_dev_nr(pcie, 0); + pcie->dev = PCI_BDF(bus, 0, 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); + 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 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; - } - pcie->base = (void __iomem *)PCIE_BASE(i); - - /* 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); - 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; + /* + * The Linux code used PCI_SLOT() here, which expects devfn + * in bits 7..0. PCI_DEV() in U-Boot is similar to PCI_SLOT(), + * only expects devfn in 15..8, where its saved in this driver. + */ + if (slot == PCI_DEV(devfn) && type == rtype) { + *tgt = DT_CPUADDR_TO_TARGET(cpuaddr); + *attr = DT_CPUADDR_TO_ATTR(cpuaddr); + return 0; } } + + return -ENOENT; } + +static int mvebu_pcie_ofdata_to_platdata(struct udevice *dev) +{ + struct mvebu_pcie *pcie = dev_get_platdata(dev); + int ret = 0; + + /* Get port number, lane number and memory target / attr */ + if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-port", + &pcie->port)) { + ret = -ENODEV; + goto err; + } + + if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-lane", &pcie->lane)) + pcie->lane = 0; + + sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane); + + /* pci_get_devfn() returns devfn in bits 15..8, see PCI_DEV usage */ + pcie->devfn = pci_get_devfn(dev); + if (pcie->devfn < 0) { + ret = -ENODEV; + goto err; + } + + ret = mvebu_get_tgt_attr(dev_ofnode(dev->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); + goto err; + } + + /* Parse PCIe controller register base from DT */ + ret = mvebu_pcie_port_parse_dt(dev_ofnode(dev), pcie); + if (ret < 0) + goto err; + + /* Check link and skip ports that have no link */ + if (!mvebu_pcie_link_up(pcie)) { + debug("%s: %s - down\n", __func__, pcie->name); + ret = -ENODEV; + goto err; + } + + return 0; + +err: + return ret; +} + +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, + .ofdata_to_platdata = mvebu_pcie_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct mvebu_pcie), +}; + +/* + * 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; + + /* 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; + + /* 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 2526a00084..27c858013d 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/include/configs/x530.h b/include/configs/x530.h index a1ef301d35..a83d49ba35 100644 --- a/include/configs/x530.h +++ b/include/configs/x530.h @@ -75,7 +75,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 b425cc360f..f7f30d15ae 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1443,7 +1443,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 From 6f139becf60e1ac97873a36d5672ea65cba97abd Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 25 Jan 2019 11:52:44 +0100 Subject: [PATCH 3/7] arm: mvebu: armada-xp/37x.dtsi: Sync PCIe DT nodes with Linux v4.20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch sync's the PCIe DT nodes with the recent Linux v4.20 version. This change makes it easier to reference specific PCIe nodes in the board dts files to e.g. enable a PCIe port as this is now necessary with the new DM PCI driver for these platforms. Signed-off-by: Stefan Roese Cc: Dirk Eibach Cc: Mario Six Cc: Chris Packham Cc: Phil Sutter Cc: Marek Behún Cc: VlaoMao Cc: Tom Rini --- arch/arm/dts/armada-375.dtsi | 8 +++++--- arch/arm/dts/armada-xp-mv78230.dtsi | 17 +++++++++------ arch/arm/dts/armada-xp-mv78260.dtsi | 29 +++++++++++++++++--------- arch/arm/dts/armada-xp-mv78460.dtsi | 32 +++++++++++++++++++---------- 4 files changed, 56 insertions(+), 30 deletions(-) diff --git a/arch/arm/dts/armada-375.dtsi b/arch/arm/dts/armada-375.dtsi index 249c41c757..62a548a55f 100644 --- a/arch/arm/dts/armada-375.dtsi +++ b/arch/arm/dts/armada-375.dtsi @@ -582,7 +582,7 @@ }; }; - pcie-controller { + pciec: pcie@82000000 { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -601,7 +601,7 @@ 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 1 MEM */ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1 IO */>; - pcie@1,0 { + pcie0: pcie@1,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; reg = <0x0800 0 0 0 0>; @@ -610,6 +610,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -618,7 +619,7 @@ status = "disabled"; }; - pcie@2,0 { + pcie1: pcie@2,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; @@ -627,6 +628,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; diff --git a/arch/arm/dts/armada-xp-mv78230.dtsi b/arch/arm/dts/armada-xp-mv78230.dtsi index 6e6d0f04bf..f6bab9fb20 100644 --- a/arch/arm/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/dts/armada-xp-mv78230.dtsi @@ -86,7 +86,7 @@ * configured as x4 or quad x1 lanes. One unit is * x1 only. */ - pcie-controller { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -114,7 +114,7 @@ 0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */ 0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>; - pcie@1,0 { + pcie1: pcie@1,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; reg = <0x0800 0 0 0 0>; @@ -123,6 +123,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -131,7 +132,7 @@ status = "disabled"; }; - pcie@2,0 { + pcie2: pcie@2,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; @@ -140,6 +141,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -148,7 +150,7 @@ status = "disabled"; }; - pcie@3,0 { + pcie3: pcie@3,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; reg = <0x1800 0 0 0 0>; @@ -157,6 +159,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -165,7 +168,7 @@ status = "disabled"; }; - pcie@4,0 { + pcie4: pcie@4,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; reg = <0x2000 0 0 0 0>; @@ -174,6 +177,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -182,7 +186,7 @@ status = "disabled"; }; - pcie@5,0 { + pcie5: pcie@5,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; reg = <0x2800 0 0 0 0>; @@ -191,6 +195,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; diff --git a/arch/arm/dts/armada-xp-mv78260.dtsi b/arch/arm/dts/armada-xp-mv78260.dtsi index c5fdc99f0d..d39231f69d 100644 --- a/arch/arm/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/dts/armada-xp-mv78260.dtsi @@ -87,7 +87,7 @@ * configured as x4 or quad x1 lanes. One unit is * x4 only. */ - pcie-controller { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -129,7 +129,7 @@ 0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */ 0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>; - pcie@1,0 { + pcie1: pcie@1,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; reg = <0x0800 0 0 0 0>; @@ -138,6 +138,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -146,7 +147,7 @@ status = "disabled"; }; - pcie@2,0 { + pcie2: pcie@2,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; @@ -155,6 +156,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -163,7 +165,7 @@ status = "disabled"; }; - pcie@3,0 { + pcie3: pcie@3,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; reg = <0x1800 0 0 0 0>; @@ -172,6 +174,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -180,7 +183,7 @@ status = "disabled"; }; - pcie@4,0 { + pcie4: pcie@4,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; reg = <0x2000 0 0 0 0>; @@ -189,6 +192,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -197,7 +201,7 @@ status = "disabled"; }; - pcie@5,0 { + pcie5: pcie@5,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; reg = <0x2800 0 0 0 0>; @@ -206,6 +210,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; @@ -214,7 +219,7 @@ status = "disabled"; }; - pcie@6,0 { + pcie6: pcie@6,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x84000 0 0x2000>; reg = <0x3000 0 0 0 0>; @@ -223,6 +228,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0 0x81000000 0 0 0x81000000 0x6 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 63>; marvell,pcie-port = <1>; @@ -231,7 +237,7 @@ status = "disabled"; }; - pcie@7,0 { + pcie7: pcie@7,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x88000 0 0x2000>; reg = <0x3800 0 0 0 0>; @@ -240,6 +246,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0 0x81000000 0 0 0x81000000 0x7 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 64>; marvell,pcie-port = <1>; @@ -248,7 +255,7 @@ status = "disabled"; }; - pcie@8,0 { + pcie8: pcie@8,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>; reg = <0x4000 0 0 0 0>; @@ -257,6 +264,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0 0x81000000 0 0 0x81000000 0x8 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 65>; marvell,pcie-port = <1>; @@ -265,7 +273,7 @@ status = "disabled"; }; - pcie@9,0 { + pcie9: pcie@9,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; reg = <0x4800 0 0 0 0>; @@ -274,6 +282,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 0x81000000 0 0 0x81000000 0x9 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 99>; marvell,pcie-port = <2>; diff --git a/arch/arm/dts/armada-xp-mv78460.dtsi b/arch/arm/dts/armada-xp-mv78460.dtsi index 0e24f1a385..c642565d1b 100644 --- a/arch/arm/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/dts/armada-xp-mv78460.dtsi @@ -104,7 +104,7 @@ * configured as x4 or quad x1 lanes. Two units are * x4/x1. */ - pcie-controller { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -150,7 +150,7 @@ 0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */ 0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>; - pcie@1,0 { + pcie1: pcie@1,0 { device_type = "pci"; assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; reg = <0x0800 0 0 0 0>; @@ -159,6 +159,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -167,7 +168,7 @@ status = "disabled"; }; - pcie@2,0 { + pcie2: pcie@2,0 { device_type = "pci"; assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; @@ -176,6 +177,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -184,7 +186,7 @@ status = "disabled"; }; - pcie@3,0 { + pcie3: pcie@3,0 { device_type = "pci"; assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; reg = <0x1800 0 0 0 0>; @@ -193,6 +195,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -201,7 +204,7 @@ status = "disabled"; }; - pcie@4,0 { + pcie4: pcie@4,0 { device_type = "pci"; assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; reg = <0x2000 0 0 0 0>; @@ -210,6 +213,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -218,7 +222,7 @@ status = "disabled"; }; - pcie@5,0 { + pcie5: pcie@5,0 { device_type = "pci"; assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; reg = <0x2800 0 0 0 0>; @@ -227,6 +231,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; @@ -235,7 +240,7 @@ status = "disabled"; }; - pcie@6,0 { + pcie6: pcie@6,0 { device_type = "pci"; assigned-addresses = <0x82003000 0 0x84000 0 0x2000>; reg = <0x3000 0 0 0 0>; @@ -244,6 +249,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0 0x81000000 0 0 0x81000000 0x6 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 63>; marvell,pcie-port = <1>; @@ -252,7 +258,7 @@ status = "disabled"; }; - pcie@7,0 { + pcie7: pcie@7,0 { device_type = "pci"; assigned-addresses = <0x82003800 0 0x88000 0 0x2000>; reg = <0x3800 0 0 0 0>; @@ -261,6 +267,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0 0x81000000 0 0 0x81000000 0x7 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 64>; marvell,pcie-port = <1>; @@ -269,7 +276,7 @@ status = "disabled"; }; - pcie@8,0 { + pcie8: pcie@8,0 { device_type = "pci"; assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>; reg = <0x4000 0 0 0 0>; @@ -278,6 +285,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0 0x81000000 0 0 0x81000000 0x8 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 65>; marvell,pcie-port = <1>; @@ -286,7 +294,7 @@ status = "disabled"; }; - pcie@9,0 { + pcie9: pcie@9,0 { device_type = "pci"; assigned-addresses = <0x82004800 0 0x42000 0 0x2000>; reg = <0x4800 0 0 0 0>; @@ -295,6 +303,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 0x81000000 0 0 0x81000000 0x9 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 99>; marvell,pcie-port = <2>; @@ -303,7 +312,7 @@ status = "disabled"; }; - pcie@10,0 { + pcie10: pcie@a,0 { device_type = "pci"; assigned-addresses = <0x82005000 0 0x82000 0 0x2000>; reg = <0x5000 0 0 0 0>; @@ -312,6 +321,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0 0x81000000 0 0 0x81000000 0xa 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 103>; marvell,pcie-port = <3>; From 9b276e90d640e1f655283f0fe823f1b1b05a542b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 25 Jan 2019 11:52:45 +0100 Subject: [PATCH 4/7] arm: mvebu: armada-xp-theadorable.dts: Enable PCIe DT nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the PCIe driver supports DM and DT parsing, enable the PCIe DT nodes that are used by this board. Signed-off-by: Stefan Roese Cc: Dirk Eibach Cc: Mario Six Cc: Chris Packham Cc: Phil Sutter Cc: Marek Behún Cc: VlaoMao --- arch/arm/dts/armada-xp-theadorable.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index 965c38426c..9b66ec678d 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -162,3 +162,17 @@ }; }; }; + +&pciec { + status = "okay"; + + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + + pcie@9,0 { + /* Port 2, Lane 0 */ + status = "okay"; + }; +}; From 32c9e1c269d05a9dcf22f2b9ebd1c47bfe19c971 Mon Sep 17 00:00:00 2001 From: Vladimir Vid Date: Mon, 28 Jan 2019 17:27:58 +0100 Subject: [PATCH 5/7] arm64: mvebu: Add basic support for uDPU board This adds initial support for micro-DPU (uDPU) board which is based on Armada-3720 SoC. micro-DPU is the single-port FTTdp "distribution point unit" made by Methode Electronics which offers complete modularity with replaceable SFP modules both for uplink and downlink (G.hn over twisted-pair, G.hn over coax, 1G and 2.5G Ethernet over Cat-5e cable). On-board features: - 512 MiB DDR3 - 2 x 2.5G SFP via HSGMII SERDES interface to the A3720 SoC - USB 2.0 Type-C connector - 4GB eMMC - ETSI TS 101548 reverse powering via twisted pair (RJ45) or coax (F Type) Cc: Luka Perkov Cc: Luis Torres Cc: Scott Roberts Cc: Paul Arola Signed-off-by: Vladimir Vid Reviewed-by: Stefan Roese Signed-off-by: Stefan Roese --- arch/arm/dts/Makefile | 1 + arch/arm/dts/armada-3720-uDPU-u-boot.dtsi | 13 ++ arch/arm/dts/armada-3720-uDPU.dts | 200 ++++++++++++++++++++ board/Marvell/mvebu_armada-37xx/MAINTAINERS | 5 + configs/uDPU_defconfig | 94 +++++++++ 5 files changed, 313 insertions(+) create mode 100644 arch/arm/dts/armada-3720-uDPU-u-boot.dtsi create mode 100644 arch/arm/dts/armada-3720-uDPU.dts create mode 100644 configs/uDPU_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 876c032d11..ca50623480 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -96,6 +96,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-3720-db.dtb \ armada-3720-espressobin.dtb \ armada-3720-turris-mox.dtb \ + armada-3720-uDPU.dts \ armada-375-db.dtb \ armada-388-clearfog.dtb \ armada-388-gp.dtb \ diff --git a/arch/arm/dts/armada-3720-uDPU-u-boot.dtsi b/arch/arm/dts/armada-3720-uDPU-u-boot.dtsi new file mode 100644 index 0000000000..ef178bdc86 --- /dev/null +++ b/arch/arm/dts/armada-3720-uDPU-u-boot.dtsi @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ + +&spi0 { + u-boot,dm-pre-reloc; + + spi-flash@0 { + u-boot,dm-pre-reloc; + }; +}; + +&sdhci1 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/armada-3720-uDPU.dts b/arch/arm/dts/armada-3720-uDPU.dts new file mode 100644 index 0000000000..683dac2a7c --- /dev/null +++ b/arch/arm/dts/armada-3720-uDPU.dts @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device tree for the uDPU board. + * Based on Marvell Armada 3720 development board (DB-88F3720-DDR3) + * Copyright (C) 2016 Marvell + * Copyright (C) 2018 Methode + * Copyright (C) 2018 Telus + * + * Vladimir Vid + */ + +/dts-v1/; + +#include "armada-37xx.dtsi" +#include "armada-3720-uDPU-u-boot.dtsi" + +/ { + model = "Methode uDPU Board"; + compatible = "methode,udpu"; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000"; + }; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + spi0 = &spi0; + }; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000 0x20000000>; + }; + + mdio: mdio@32004 { + #address-cells = <1>; + #size-cells = <0>; + ethphy0: ethernet-phy@0 { + reg = <0>; + }; + ethphy1: ethernet-phy@1 { + reg = <1>; + }; + }; + + scsi: scsi { + compatible = "marvell,mvebu-scsi"; + #address-cells = <1>; + #size-cells = <1>; + max-id = <1>; + max-lun = <1>; + status = "okay"; + }; + + i2c1: i2c@11080 { + compatible = "marvell,armada-3700-i2c", "simple-bus"; + reg = <0x0 0x11080 0x0 0x80>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + #address-cells = <2>; + #size-cells = <2>; + status = "okay"; + }; + + uart1: serial@12200 { + compatible = "marvell,armada-3700-uart-ext"; + reg = <0x0 0x12200 0x0 0x30>; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + interrupts = ; + status = "okay"; + #address-cells = <2>; + #size-cells = <2>; + }; + + vcc_sd_reg0: regulator@0 { + compatible = "regulator-gpio"; + regulator-name = "vcc_sd0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-type = "voltage"; + states = <1800000 0x1 + 3300000 0x0>; + gpios = <&gpiosb 23 GPIO_ACTIVE_HIGH>; + }; + + sfp_eth0: sfp-eth0 { + compatible = "sff,sfp"; + i2c-bus = <&i2c0>; + los-gpio = <&gpiosb 2 GPIO_ACTIVE_HIGH>; + mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>; + }; + + sfp_eth1: sfp-eth1 { + compatible = "sff,sfp"; + i2c-bus = <&i2c1>; + sfp,ethernet = <ð1>; + los-gpio = <&gpiosb 7 GPIO_ACTIVE_HIGH>; + mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>; + }; +}; + +&comphy { + phy0 { + phy-type = ; + phy-speed = ; + }; + phy1 { + phy-type = ; + phy-speed = ; + }; + + phy2 { + phy-type = ; + phy-speed = ; + }; +}; + +ð0 { + pinctrl-0 = <&pcie_pins>; + status = "okay"; + phy-mode = "sgmii"; + phy = <ðphy0>; + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +ð1 { + status = "okay"; + phy-mode = "sgmii"; + phy = <ðphy1>; + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi_quad_pins>; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q1024a","n25q512a"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + m25p,fast-read; + + partition@0 { + label = "uboot"; + reg = <0 0x400000>; + }; + }; +}; + +&sdhci1 { + non-removable; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + bus-width = <4>; + vqmmc-supply = <&vcc_sd_reg0>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + mmccard: mmccard@0 { + compatible = "mmc-card"; + reg = <0>; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; +}; + +&usb3 { + status = "okay"; +}; diff --git a/board/Marvell/mvebu_armada-37xx/MAINTAINERS b/board/Marvell/mvebu_armada-37xx/MAINTAINERS index 9b0afeef10..f2c0a582d7 100644 --- a/board/Marvell/mvebu_armada-37xx/MAINTAINERS +++ b/board/Marvell/mvebu_armada-37xx/MAINTAINERS @@ -9,3 +9,8 @@ ESPRESSOBin BOARD M: Konstantin Porotchkin S: Maintained F: configs/mvebu_espressobin-88f3720_defconfig + +uDPU BOARD +M: Vladimir Vid +S: Maintained +F: configs/uDPU_defconfig diff --git a/configs/uDPU_defconfig b/configs/uDPU_defconfig new file mode 100644 index 0000000000..53f2b6e746 --- /dev/null +++ b/configs/uDPU_defconfig @@ -0,0 +1,94 @@ +CONFIG_ARM=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_TEXT_BASE=0x00000000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_MVEBU_ARMADA_37XX=y +CONFIG_DEBUG_UART_BASE=0xd0012000 +CONFIG_DEBUG_UART_CLOCK=25804800 +CONFIG_SMBIOS_PRODUCT_NAME="uDPU" +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +CONFIG_DISTRO_DEFAULTS=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +CONFIG_SPI_BOOT=y +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_ARCH_EARLY_INIT_R=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SYS_PROMPT="uDPU>> " +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_MVEBU_BUBT=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nor0=spi0" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0:4m(uboot),-(rootfs)" +CONFIG_MAC_PARTITION=y +CONFIG_DEFAULT_DEVICE_TREE="armada-3720-uDPU" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_AHCI_MVEBU=y +CONFIG_CLK=y +CONFIG_CLK_MVEBU=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_GPIO=y +CONFIG_MISC=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_XENON=y +CONFIG_MTD=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_PHYLIB_10G=y +CONFIG_PHY_MARVELL=y +CONFIG_PHY_GIGE=y +CONFIG_E1000=y +CONFIG_MVNETA=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCI_AARDVARK=y +CONFIG_MVEBU_COMPHY_SUPPORT=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_ARMADA_37XX=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +# CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_DEBUG_MVEBU_A3700_UART=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_MVEBU_A3700_UART=y +CONFIG_MVEBU_A3700_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y +CONFIG_LZO=y +CONFIG_SPL_LZO=y From 6d9a98c58390156033e31a3a4078347bec618202 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 30 Jan 2019 08:54:11 +0100 Subject: [PATCH 6/7] video: Armada XP: Move driver to DM_VIDEO This patch moves the Armada XP video / LCD driver to DM_VIDEO. With this move, the legacy interface board_video_init() is removed from the theadorable board code (only user of this video driver). The support via DT will be added in a separate patch. This patch also enables DM_VIDEO for the theadorable board, as this is needed to not break git bisect'ability. Signed-off-by: Stefan Roese Reviewed-by: Anatolij Gustschin Acked-by: Anatolij Gustschin --- arch/arm/mach-mvebu/include/mach/cpu.h | 12 - board/theadorable/theadorable.c | 16 -- configs/theadorable_debug_defconfig | 3 +- drivers/video/mvebu_lcd.c | 317 +++++++++++++++---------- 4 files changed, 191 insertions(+), 157 deletions(-) diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 85d7dd1610..9e23043a48 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -158,18 +158,6 @@ int serdes_phy_config(void); */ int ddr3_init(void); -struct mvebu_lcd_info { - u32 fb_base; - int x_res; - int y_res; - int x_fp; /* frontporch */ - int y_fp; - int x_bp; /* backporch */ - int y_bp; -}; - -int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info); - /* * get_ref_clk * diff --git a/board/theadorable/theadorable.c b/board/theadorable/theadorable.c index b59589ae82..dd6def5e6e 100644 --- a/board/theadorable/theadorable.c +++ b/board/theadorable/theadorable.c @@ -218,22 +218,6 @@ int board_eth_init(bd_t *bis) } #endif -int board_video_init(void) -{ - struct mvebu_lcd_info lcd_info; - - /* Reserved memory area via CONFIG_SYS_MEM_TOP_HIDE */ - lcd_info.fb_base = gd->ram_size; - lcd_info.x_res = 240; - lcd_info.x_fp = 1; - lcd_info.x_bp = 45; - lcd_info.y_res = 320; - lcd_info.y_fp = 1; - lcd_info.y_bp = 3; - - return mvebu_lcd_register_init(&lcd_info); -} - #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig index ac6dfd6844..a7d02e957a 100644 --- a/configs/theadorable_debug_defconfig +++ b/configs/theadorable_debug_defconfig @@ -71,6 +71,5 @@ CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_MVEBU=y -CONFIG_VIDEO=y -# CONFIG_VIDEO_SW_CURSOR is not set diff --git a/drivers/video/mvebu_lcd.c b/drivers/video/mvebu_lcd.c index 5bf0d01faa..dc6254514a 100644 --- a/drivers/video/mvebu_lcd.c +++ b/drivers/video/mvebu_lcd.c @@ -6,74 +6,96 @@ */ #include -#include +#include +#include #include #include #include #include -#define MVEBU_LCD_WIN_CONTROL(w) (MVEBU_LCD_BASE + 0xf000 + ((w) << 4)) -#define MVEBU_LCD_WIN_BASE(w) (MVEBU_LCD_BASE + 0xf004 + ((w) << 4)) -#define MVEBU_LCD_WIN_REMAP(w) (MVEBU_LCD_BASE + 0xf00c + ((w) << 4)) +#define MVEBU_LCD_WIN_CONTROL(w) (0xf000 + ((w) << 4)) +#define MVEBU_LCD_WIN_BASE(w) (0xf004 + ((w) << 4)) +#define MVEBU_LCD_WIN_REMAP(w) (0xf00c + ((w) << 4)) -#define MVEBU_LCD_CFG_DMA_START_ADDR_0 (MVEBU_LCD_BASE + 0x00cc) -#define MVEBU_LCD_CFG_DMA_START_ADDR_1 (MVEBU_LCD_BASE + 0x00dc) +#define MVEBU_LCD_CFG_DMA_START_ADDR_0 0x00cc +#define MVEBU_LCD_CFG_DMA_START_ADDR_1 0x00dc -#define MVEBU_LCD_CFG_GRA_START_ADDR0 (MVEBU_LCD_BASE + 0x00f4) -#define MVEBU_LCD_CFG_GRA_START_ADDR1 (MVEBU_LCD_BASE + 0x00f8) -#define MVEBU_LCD_CFG_GRA_PITCH (MVEBU_LCD_BASE + 0x00fc) -#define MVEBU_LCD_SPU_GRA_OVSA_HPXL_VLN (MVEBU_LCD_BASE + 0x0100) -#define MVEBU_LCD_SPU_GRA_HPXL_VLN (MVEBU_LCD_BASE + 0x0104) -#define MVEBU_LCD_SPU_GZM_HPXL_VLN (MVEBU_LCD_BASE + 0x0108) -#define MVEBU_LCD_SPU_HWC_OVSA_HPXL_VLN (MVEBU_LCD_BASE + 0x010c) -#define MVEBU_LCD_SPU_HWC_HPXL_VLN (MVEBU_LCD_BASE + 0x0110) -#define MVEBU_LCD_SPUT_V_H_TOTAL (MVEBU_LCD_BASE + 0x0114) -#define MVEBU_LCD_SPU_V_H_ACTIVE (MVEBU_LCD_BASE + 0x0118) -#define MVEBU_LCD_SPU_H_PORCH (MVEBU_LCD_BASE + 0x011c) -#define MVEBU_LCD_SPU_V_PORCH (MVEBU_LCD_BASE + 0x0120) -#define MVEBU_LCD_SPU_BLANKCOLOR (MVEBU_LCD_BASE + 0x0124) -#define MVEBU_LCD_SPU_ALPHA_COLOR1 (MVEBU_LCD_BASE + 0x0128) -#define MVEBU_LCD_SPU_ALPHA_COLOR2 (MVEBU_LCD_BASE + 0x012c) -#define MVEBU_LCD_SPU_COLORKEY_Y (MVEBU_LCD_BASE + 0x0130) -#define MVEBU_LCD_SPU_COLORKEY_U (MVEBU_LCD_BASE + 0x0134) -#define MVEBU_LCD_SPU_COLORKEY_V (MVEBU_LCD_BASE + 0x0138) -#define MVEBU_LCD_CFG_RDREG4F (MVEBU_LCD_BASE + 0x013c) -#define MVEBU_LCD_SPU_SPI_RXDATA (MVEBU_LCD_BASE + 0x0140) -#define MVEBU_LCD_SPU_ISA_RXDATA (MVEBU_LCD_BASE + 0x0144) -#define MVEBU_LCD_SPU_DBG_ISA (MVEBU_LCD_BASE + 0x0148) +#define MVEBU_LCD_CFG_GRA_START_ADDR0 0x00f4 +#define MVEBU_LCD_CFG_GRA_START_ADDR1 0x00f8 +#define MVEBU_LCD_CFG_GRA_PITCH 0x00fc +#define MVEBU_LCD_SPU_GRA_OVSA_HPXL_VLN 0x0100 +#define MVEBU_LCD_SPU_GRA_HPXL_VLN 0x0104 +#define MVEBU_LCD_SPU_GZM_HPXL_VLN 0x0108 +#define MVEBU_LCD_SPU_HWC_OVSA_HPXL_VLN 0x010c +#define MVEBU_LCD_SPU_HWC_HPXL_VLN 0x0110 +#define MVEBU_LCD_SPUT_V_H_TOTAL 0x0114 +#define MVEBU_LCD_SPU_V_H_ACTIVE 0x0118 +#define MVEBU_LCD_SPU_H_PORCH 0x011c +#define MVEBU_LCD_SPU_V_PORCH 0x0120 +#define MVEBU_LCD_SPU_BLANKCOLOR 0x0124 +#define MVEBU_LCD_SPU_ALPHA_COLOR1 0x0128 +#define MVEBU_LCD_SPU_ALPHA_COLOR2 0x012c +#define MVEBU_LCD_SPU_COLORKEY_Y 0x0130 +#define MVEBU_LCD_SPU_COLORKEY_U 0x0134 +#define MVEBU_LCD_SPU_COLORKEY_V 0x0138 +#define MVEBU_LCD_CFG_RDREG4F 0x013c +#define MVEBU_LCD_SPU_SPI_RXDATA 0x0140 +#define MVEBU_LCD_SPU_ISA_RXDATA 0x0144 +#define MVEBU_LCD_SPU_DBG_ISA 0x0148 -#define MVEBU_LCD_SPU_HWC_RDDAT (MVEBU_LCD_BASE + 0x0158) -#define MVEBU_LCD_SPU_GAMMA_RDDAT (MVEBU_LCD_BASE + 0x015c) -#define MVEBU_LCD_SPU_PALETTE_RDDAT (MVEBU_LCD_BASE + 0x0160) -#define MVEBU_LCD_SPU_IOPAD_IN (MVEBU_LCD_BASE + 0x0178) -#define MVEBU_LCD_FRAME_COUNT (MVEBU_LCD_BASE + 0x017c) -#define MVEBU_LCD_SPU_DMA_CTRL0 (MVEBU_LCD_BASE + 0x0190) -#define MVEBU_LCD_SPU_DMA_CTRL1 (MVEBU_LCD_BASE + 0x0194) -#define MVEBU_LCD_SPU_SRAM_CTRL (MVEBU_LCD_BASE + 0x0198) -#define MVEBU_LCD_SPU_SRAM_WRDAT (MVEBU_LCD_BASE + 0x019c) -#define MVEBU_LCD_SPU_SRAM_PARA0 (MVEBU_LCD_BASE + 0x01a0) -#define MVEBU_LCD_SPU_SRAM_PARA1 (MVEBU_LCD_BASE + 0x01a4) -#define MVEBU_LCD_CFG_SCLK_DIV (MVEBU_LCD_BASE + 0x01a8) -#define MVEBU_LCD_SPU_CONTRAST (MVEBU_LCD_BASE + 0x01ac) -#define MVEBU_LCD_SPU_SATURATION (MVEBU_LCD_BASE + 0x01b0) -#define MVEBU_LCD_SPU_CBSH_HUE (MVEBU_LCD_BASE + 0x01b4) -#define MVEBU_LCD_SPU_DUMB_CTRL (MVEBU_LCD_BASE + 0x01b8) -#define MVEBU_LCD_SPU_IOPAD_CONTROL (MVEBU_LCD_BASE + 0x01bc) -#define MVEBU_LCD_SPU_IRQ_ENA_2 (MVEBU_LCD_BASE + 0x01d8) -#define MVEBU_LCD_SPU_IRQ_ISR_2 (MVEBU_LCD_BASE + 0x01dc) -#define MVEBU_LCD_SPU_IRQ_ENA (MVEBU_LCD_BASE + 0x01c0) -#define MVEBU_LCD_SPU_IRQ_ISR (MVEBU_LCD_BASE + 0x01c4) -#define MVEBU_LCD_ADLL_CTRL (MVEBU_LCD_BASE + 0x01c8) -#define MVEBU_LCD_CLK_DIS (MVEBU_LCD_BASE + 0x01cc) -#define MVEBU_LCD_VGA_HVSYNC_DELAY (MVEBU_LCD_BASE + 0x01d4) -#define MVEBU_LCD_CLK_CFG_0 (MVEBU_LCD_BASE + 0xf0a0) -#define MVEBU_LCD_CLK_CFG_1 (MVEBU_LCD_BASE + 0xf0a4) -#define MVEBU_LCD_LVDS_CLK_CFG (MVEBU_LCD_BASE + 0xf0ac) +#define MVEBU_LCD_SPU_HWC_RDDAT 0x0158 +#define MVEBU_LCD_SPU_GAMMA_RDDAT 0x015c +#define MVEBU_LCD_SPU_PALETTE_RDDAT 0x0160 +#define MVEBU_LCD_SPU_IOPAD_IN 0x0178 +#define MVEBU_LCD_FRAME_COUNT 0x017c +#define MVEBU_LCD_SPU_DMA_CTRL0 0x0190 +#define MVEBU_LCD_SPU_DMA_CTRL1 0x0194 +#define MVEBU_LCD_SPU_SRAM_CTRL 0x0198 +#define MVEBU_LCD_SPU_SRAM_WRDAT 0x019c +#define MVEBU_LCD_SPU_SRAM_PARA0 0x01a0 +#define MVEBU_LCD_SPU_SRAM_PARA1 0x01a4 +#define MVEBU_LCD_CFG_SCLK_DIV 0x01a8 +#define MVEBU_LCD_SPU_CONTRAST 0x01ac +#define MVEBU_LCD_SPU_SATURATION 0x01b0 +#define MVEBU_LCD_SPU_CBSH_HUE 0x01b4 +#define MVEBU_LCD_SPU_DUMB_CTRL 0x01b8 +#define MVEBU_LCD_SPU_IOPAD_CONTROL 0x01bc +#define MVEBU_LCD_SPU_IRQ_ENA_2 0x01d8 +#define MVEBU_LCD_SPU_IRQ_ISR_2 0x01dc +#define MVEBU_LCD_SPU_IRQ_ENA 0x01c0 +#define MVEBU_LCD_SPU_IRQ_ISR 0x01c4 +#define MVEBU_LCD_ADLL_CTRL 0x01c8 +#define MVEBU_LCD_CLK_DIS 0x01cc +#define MVEBU_LCD_VGA_HVSYNC_DELAY 0x01d4 +#define MVEBU_LCD_CLK_CFG_0 0xf0a0 +#define MVEBU_LCD_CLK_CFG_1 0xf0a4 +#define MVEBU_LCD_LVDS_CLK_CFG 0xf0ac #define MVEBU_LVDS_PADS_REG (MVEBU_SYSTEM_REG_BASE + 0xf0) +enum { + /* Maximum LCD size we support */ + LCD_MAX_WIDTH = 640, + LCD_MAX_HEIGHT = 480, + LCD_MAX_LOG2_BPP = VIDEO_BPP16, +}; + +struct mvebu_lcd_info { + u32 fb_base; + int x_res; + int y_res; + int x_fp; + int y_fp; + int x_bp; + int y_bp; +}; + +struct mvebu_video_priv { + uintptr_t regs; +}; + /* Setup Mbus Bridge Windows for LCD */ -static void mvebu_lcd_conf_mbus_registers(void) +static void mvebu_lcd_conf_mbus_registers(uintptr_t regs) { const struct mbus_dram_target_info *dram; int i; @@ -82,9 +104,9 @@ static void mvebu_lcd_conf_mbus_registers(void) /* Disable windows, set size/base/remap to 0 */ for (i = 0; i < 6; i++) { - writel(0, MVEBU_LCD_WIN_CONTROL(i)); - writel(0, MVEBU_LCD_WIN_BASE(i)); - writel(0, MVEBU_LCD_WIN_REMAP(i)); + writel(0, regs + MVEBU_LCD_WIN_CONTROL(i)); + writel(0, regs + MVEBU_LCD_WIN_BASE(i)); + writel(0, regs + MVEBU_LCD_WIN_REMAP(i)); } /* Write LCD bridge window registers */ @@ -92,14 +114,15 @@ static void mvebu_lcd_conf_mbus_registers(void) const struct mbus_dram_window *cs = dram->cs + i; writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | (dram->mbus_dram_target_id << 4) | 1, - MVEBU_LCD_WIN_CONTROL(i)); + regs + MVEBU_LCD_WIN_CONTROL(i)); - writel(cs->base & 0xffff0000, MVEBU_LCD_WIN_BASE(i)); + writel(cs->base & 0xffff0000, regs + MVEBU_LCD_WIN_BASE(i)); } } /* Initialize LCD registers */ -int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) +static void mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info, + uintptr_t regs) { /* Local variable for easier handling */ int x = lcd_info->x_res; @@ -107,7 +130,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) u32 val; /* Setup Mbus Bridge Windows */ - mvebu_lcd_conf_mbus_registers(); + mvebu_lcd_conf_mbus_registers(regs); /* * Set LVDS Pads Control Register @@ -121,8 +144,8 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * end (currently 1GB-64MB but also may be 2GB-64MB). * See also the Window 0 settings! */ - writel(lcd_info->fb_base, MVEBU_LCD_CFG_GRA_START_ADDR0); - writel(lcd_info->fb_base, MVEBU_LCD_CFG_GRA_START_ADDR1); + writel(lcd_info->fb_base, regs + MVEBU_LCD_CFG_GRA_START_ADDR0); + writel(lcd_info->fb_base, regs + MVEBU_LCD_CFG_GRA_START_ADDR1); /* * Set the LCD_CFG_GRA_PITCH Register @@ -132,14 +155,14 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 15-00: Line Length in Bytes * 240*2 (for RGB1555)=480=0x1E0 */ - writel(0x80100000 + 2 * x, MVEBU_LCD_CFG_GRA_PITCH); + writel(0x80100000 + 2 * x, regs + MVEBU_LCD_CFG_GRA_PITCH); /* * Set the LCD_SPU_GRA_OVSA_HPXL_VLN Register * Bits 31-16: Vertical start of graphical overlay on screen * Bits 15-00: Horizontal start of graphical overlay on screen */ - writel(0x00000000, MVEBU_LCD_SPU_GRA_OVSA_HPXL_VLN); + writel(0x00000000, regs + MVEBU_LCD_SPU_GRA_OVSA_HPXL_VLN); /* * Set the LCD_SPU_GRA_HPXL_VLN Register @@ -147,7 +170,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 15-00: Horizontal size of graphical overlay 240=0xF0 * Values before zooming */ - writel((y << 16) | x, MVEBU_LCD_SPU_GRA_HPXL_VLN); + writel((y << 16) | x, regs + MVEBU_LCD_SPU_GRA_HPXL_VLN); /* * Set the LCD_SPU_GZM_HPXL_VLN Register @@ -155,21 +178,21 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 15-00: Horizontal size of graphical overlay 240=0xF0 * Values after zooming */ - writel((y << 16) | x, MVEBU_LCD_SPU_GZM_HPXL_VLN); + writel((y << 16) | x, regs + MVEBU_LCD_SPU_GZM_HPXL_VLN); /* * Set the LCD_SPU_HWC_OVSA_HPXL_VLN Register * Bits 31-16: Vertical position of HW Cursor 320=0x140 * Bits 15-00: Horizontal position of HW Cursor 240=0xF0 */ - writel((y << 16) | x, MVEBU_LCD_SPU_HWC_OVSA_HPXL_VLN); + writel((y << 16) | x, regs + MVEBU_LCD_SPU_HWC_OVSA_HPXL_VLN); /* * Set the LCD_SPU_HWC_OVSA_HPXL_VLN Register * Bits 31-16: Vertical size of HW Cursor * Bits 15-00: Horizontal size of HW Cursor */ - writel(0x00000000, MVEBU_LCD_SPU_HWC_HPXL_VLN); + writel(0x00000000, regs + MVEBU_LCD_SPU_HWC_HPXL_VLN); /* * Set the LCD_SPU_HWC_OVSA_HPXL_VLN Register @@ -191,14 +214,14 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) */ val = ((y + lcd_info->y_fp + lcd_info->y_bp + 1) << 16) | (x + lcd_info->x_fp + lcd_info->x_bp + 1); - writel(val, MVEBU_LCD_SPUT_V_H_TOTAL); + writel(val, regs + MVEBU_LCD_SPUT_V_H_TOTAL); /* * Set the LCD_SPU_V_H_ACTIVE Register * Bits 31-16: Screen active vertical lines 320=0x140 * Bits 15-00: Screen active horizontakl pixels 240=0x00F0 */ - writel((y << 16) | x, MVEBU_LCD_SPU_V_H_ACTIVE); + writel((y << 16) | x, regs + MVEBU_LCD_SPU_V_H_ACTIVE); /* * Set the LCD_SPU_H_PORCH Register @@ -207,7 +230,8 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Note: The terms "front" and "back" for the Marvell seem to be * exactly opposite to the display. */ - writel((lcd_info->x_fp << 16) | lcd_info->x_bp, MVEBU_LCD_SPU_H_PORCH); + writel((lcd_info->x_fp << 16) | lcd_info->x_bp, + regs + MVEBU_LCD_SPU_H_PORCH); /* * Set the LCD_SPU_V_PORCH Register @@ -216,14 +240,15 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Note: The terms "front" and "back" for the Marvell seem to be exactly * opposite to the display. */ - writel((lcd_info->y_fp << 16) | lcd_info->y_bp, MVEBU_LCD_SPU_V_PORCH); + writel((lcd_info->y_fp << 16) | lcd_info->y_bp, + regs + MVEBU_LCD_SPU_V_PORCH); /* * Set the LCD_SPU_BLANKCOLOR Register * This should be black = 0 * For tests this is magenta=00FF00FF */ - writel(0x00FF00FF, MVEBU_LCD_SPU_BLANKCOLOR); + writel(0x00FF00FF, regs + MVEBU_LCD_SPU_BLANKCOLOR); /* * Registers in the range of 0x0128 to 0x012C are colors for the cursor @@ -240,7 +265,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bit 8: FIFO watermark for DMA: 0=disable * Bits 07-00: Empty 8B FIFO entries to trigger DMA, default=0x80 */ - writel(0x00000780, MVEBU_LCD_CFG_RDREG4F); + writel(0x00000780, regs + MVEBU_LCD_CFG_RDREG4F); /* * Set the LCD_SPU_DMACTRL 0 Register @@ -271,7 +296,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bit 01: Video YUV to RGB Conversion: 0=disable * Bit 00: Video Transfer: 0=disable */ - writel(0x88111100, MVEBU_LCD_SPU_DMA_CTRL0); + writel(0x88111100, regs + MVEBU_LCD_SPU_DMA_CTRL0); /* * Set the LCD_SPU_DMA_CTRL1 Register @@ -288,7 +313,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 15-08: Configure Alpha: 0x00. * Bits 07-00: Reserved. */ - writel(0x20010000, MVEBU_LCD_SPU_DMA_CTRL1); + writel(0x20010000, regs + MVEBU_LCD_SPU_DMA_CTRL1); /* * Set the LCD_SPU_SRAM_CTRL Register @@ -297,14 +322,14 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 11-08: SRAM address ID: 0=gamma_yr, 1=gammy_ug, 2=gamma_vb, * 3=palette, 15=cursor */ - writel(0x0000C000, MVEBU_LCD_SPU_SRAM_CTRL); + writel(0x0000C000, regs + MVEBU_LCD_SPU_SRAM_CTRL); /* * LCD_SPU_SRAM_WRDAT register: 019C * LCD_SPU_SRAM_PARA0 register: 01A0 * LCD_SPU_SRAM_PARA1 register: 01A4 - Cursor control/Power settings */ - writel(0x00000000, MVEBU_LCD_SPU_SRAM_PARA1); + writel(0x00000000, regs + MVEBU_LCD_SPU_SRAM_PARA1); /* Clock settings in the at 01A8 and in the range F0A0 see below */ @@ -314,21 +339,21 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 31-16: Brightness sign ext. 8-bit value +255 to -255: default=0 * Bits 15-00: Contrast sign ext. 8-bit value +255 to -255: default=0 */ - writel(0x00000000, MVEBU_LCD_SPU_CONTRAST); + writel(0x00000000, regs + MVEBU_LCD_SPU_CONTRAST); /* * Set LCD_SPU_SATURATION * Bits 31-16: Multiplier signed 4.12 fixed point value * Bits 15-00: Saturation signed 4.12 fixed point value */ - writel(0x10001000, MVEBU_LCD_SPU_SATURATION); + writel(0x10001000, regs + MVEBU_LCD_SPU_SATURATION); /* * Set LCD_SPU_HUE * Bits 31-16: Sine signed 2.14 fixed point value * Bits 15-00: Cosine signed 2.14 fixed point value */ - writel(0x00000000, MVEBU_LCD_SPU_CBSH_HUE); + writel(0x00000000, regs + MVEBU_LCD_SPU_CBSH_HUE); /* * Set LCD_SPU_DUMB_CTRL @@ -348,7 +373,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Question: Do we have to disable Smart and Dumb LCD * and separately enable LVDS? */ - writel(0x6000080F, MVEBU_LCD_SPU_DUMB_CTRL); + writel(0x6000080F, regs + MVEBU_LCD_SPU_DUMB_CTRL); /* * Set LCD_SPU_IOPAD_CTRL @@ -366,17 +391,17 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * 128 Bytes burst * Bits 03-00: LCD pins: ??? 0=24-bit Dump panel ?? */ - writel(0x000000C0, MVEBU_LCD_SPU_IOPAD_CONTROL); + writel(0x000000C0, regs + MVEBU_LCD_SPU_IOPAD_CONTROL); /* * Set SUP_IRQ_ENA_2: Disable all interrupts */ - writel(0x00000000, MVEBU_LCD_SPU_IRQ_ENA_2); + writel(0x00000000, regs + MVEBU_LCD_SPU_IRQ_ENA_2); /* * Set SUP_IRQ_ENA: Disable all interrupts. */ - writel(0x00000000, MVEBU_LCD_SPU_IRQ_ENA); + writel(0x00000000, regs + MVEBU_LCD_SPU_IRQ_ENA); /* * Set up ADDL Control Register @@ -399,19 +424,19 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 05-00: Delay taps, 0x3F=Half Cycle, 0x00=No delay * Note: ADLL is used for a VGA interface with DAC - not used here */ - writel(0x00000000, MVEBU_LCD_ADLL_CTRL); + writel(0x00000000, regs + MVEBU_LCD_ADLL_CTRL); /* * Set the LCD_CLK_DIS Register: * Bits 3 and 4 must be 1 */ - writel(0x00000018, MVEBU_LCD_CLK_DIS); + writel(0x00000018, regs + MVEBU_LCD_CLK_DIS); /* * Set the LCD_VGA_HSYNC/VSYNC Delay Register: * Bits 03-00: Sets the delay for the HSYNC and VSYNC signals */ - writel(0x00000000, MVEBU_LCD_VGA_HVSYNC_DELAY); + writel(0x00000000, regs + MVEBU_LCD_VGA_HVSYNC_DELAY); /* * Clock registers @@ -423,12 +448,12 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) /* * Disable PLL, see "LCD Clock Configuration 1 Register" below */ - writel(0x8FF40007, MVEBU_LCD_CLK_CFG_1); + writel(0x8FF40007, regs + MVEBU_LCD_CLK_CFG_1); /* * Powerdown, see "LCD Clock Configuration 0 Register" below */ - writel(0x94000174, MVEBU_LCD_CLK_CFG_0); + writel(0x94000174, regs + MVEBU_LCD_CLK_CFG_0); /* * Set the LCD_CFG_SCLK_DIV Register @@ -437,7 +462,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 15-01: Clock Divider: Bypass for LVDS=0x0001 * See page 475 in section 28.5. */ - writel(0x80000001, MVEBU_LCD_CFG_SCLK_DIV); + writel(0x80000001, regs + MVEBU_LCD_CFG_SCLK_DIV); /* * Set the LCD Clock Configuration 0 Register: @@ -452,7 +477,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * N=28=0x1C => 0x1B * Bits 03-00: R1_CTRL (for N=28 => 0x4) */ - writel(0x940021B4, MVEBU_LCD_CLK_CFG_0); + writel(0x940021B4, regs + MVEBU_LCD_CLK_CFG_0); /* * Set the LCD Clock Configuration 1 Register: @@ -465,7 +490,7 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Bits 12-00: PLL Full Divider [Note: Assumed to be the Post-Divider * M' for LVDS=7!] */ - writel(0x8FF40007, MVEBU_LCD_CLK_CFG_1); + writel(0x8FF40007, regs + MVEBU_LCD_CLK_CFG_1); /* * Set the LVDS Clock Configuration Register: @@ -479,12 +504,12 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) * Note: Bits 0 and must be verified with the help of the * Interface/display */ - writel(0xC0000201, MVEBU_LCD_LVDS_CLK_CFG); + writel(0xC0000201, regs + MVEBU_LCD_LVDS_CLK_CFG); /* * Power up PLL (Clock Config 0) */ - writel(0x140021B4, MVEBU_LCD_CLK_CFG_0); + writel(0x140021B4, regs + MVEBU_LCD_CLK_CFG_0); /* wait 10 ms */ mdelay(10); @@ -492,40 +517,78 @@ int mvebu_lcd_register_init(struct mvebu_lcd_info *lcd_info) /* * Enable PLL (Clock Config 1) */ - writel(0x8FF60007, MVEBU_LCD_CLK_CFG_1); + writel(0x8FF60007, regs + MVEBU_LCD_CLK_CFG_1); +} + +static int mvebu_video_probe(struct udevice *dev) +{ + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + struct video_priv *uc_priv = dev_get_uclass_priv(dev); + struct mvebu_video_priv *priv = dev_get_priv(dev); + struct mvebu_lcd_info lcd_info; + struct display_timing timings; + u32 fb_start, fb_end; + int ret; + + priv->regs = dev_read_addr(dev); + if (priv->regs == FDT_ADDR_T_NONE) { + dev_err(dev, "failed to get LCD address\n"); + return -ENXIO; + } + + ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, &timings); + if (ret) { + dev_err(dev, "failed to get any display timings\n"); + return -EINVAL; + } + + /* Use DT timing (resolution) in internal info struct */ + lcd_info.fb_base = plat->base; + lcd_info.x_res = timings.hactive.typ; + lcd_info.x_fp = timings.hfront_porch.typ; + lcd_info.x_bp = timings.hback_porch.typ; + lcd_info.y_res = timings.vactive.typ; + lcd_info.y_fp = timings.vfront_porch.typ; + lcd_info.y_bp = timings.vback_porch.typ; + + /* Initialize the LCD controller */ + mvebu_lcd_register_init(&lcd_info, priv->regs); + + /* Enable dcache for the frame buffer */ + fb_start = plat->base & ~(MMU_SECTION_SIZE - 1); + fb_end = plat->base + plat->size; + fb_end = ALIGN(fb_end, 1 << MMU_SECTION_SHIFT); + mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start, + DCACHE_WRITEBACK); + video_set_flush_dcache(dev, true); + + uc_priv->xsize = lcd_info.x_res; + uc_priv->ysize = lcd_info.y_res; + uc_priv->bpix = VIDEO_BPP16; /* Uses RGB555 format */ return 0; } -int __weak board_video_init(void) +static int mvebu_video_bind(struct udevice *dev) { - return -1; + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + + plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT * + (1 << LCD_MAX_LOG2_BPP) / 8; + + return 0; } -void *video_hw_init(void) -{ - static GraphicDevice mvebufb; - GraphicDevice *pGD = &mvebufb; - u32 val; +static const struct udevice_id mvebu_video_ids[] = { + { .compatible = "marvell,armada-xp-lcd" }, + { } +}; - /* - * The board code needs to call mvebu_lcd_register_init() - * in its board_video_init() implementation, with the board - * specific parameters for its LCD. - */ - if (board_video_init() || !readl(MVEBU_LCD_CFG_GRA_START_ADDR0)) - return NULL; - - /* Provide the necessary values for the U-Boot video IF */ - val = readl(MVEBU_LCD_SPU_V_H_ACTIVE); - pGD->winSizeY = val >> 16; - pGD->winSizeX = val & 0x0000ffff; - pGD->gdfBytesPP = 2; - pGD->gdfIndex = GDF_15BIT_555RGB; - pGD->frameAdrs = readl(MVEBU_LCD_CFG_GRA_START_ADDR0); - - debug("LCD: buffer at 0x%08x resolution %dx%d\n", pGD->frameAdrs, - pGD->winSizeX, pGD->winSizeY); - - return pGD; -} +U_BOOT_DRIVER(mvebu_video) = { + .name = "mvebu_video", + .id = UCLASS_VIDEO, + .of_match = mvebu_video_ids, + .bind = mvebu_video_bind, + .probe = mvebu_video_probe, + .priv_auto_alloc_size = sizeof(struct mvebu_video_priv), +}; From f18220919079eeb8e79f4791e152f1db073574a8 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 30 Jan 2019 08:54:13 +0100 Subject: [PATCH 7/7] arm: mvebu: theadorable: Enable video / LCD support with the new DM driver With the new DM_VIDEO support in the Armada XP LCD driver, this patch adds the needed DT node for the LCD controller to the theadorable dts file. This DT property is not added to the Armada XP dtsi files, as this LCD feature is pretty unusual for this SoC and I personally know of no other board that uses this controller. This patch also enables CONFIG_BMP_16BPP/24BPP/32BPP, as the "old" bmp command supported these BMP files. Signed-off-by: Stefan Roese Reviewed-by: Anatolij Gustschin Acked-by: Anatolij Gustschin --- arch/arm/dts/armada-xp-theadorable.dts | 25 +++++++++++++++++++++++++ include/configs/theadorable.h | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index 9b66ec678d..5695e9b758 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -159,6 +159,31 @@ spi-max-frequency = <27777777>; }; }; + + /* The LCD controller is only used on this board */ + lcd0: lcd-controller@e0000 { + compatible = "marvell,armada-xp-lcd"; + reg = <0xe0000 0x10000>; + status = "okay"; + u-boot,dm-pre-reloc; + + display-timings { + native-mode = <&timing0>; + timing0: panel0 { + hactive = <240>; + vactive = <320>; + hfront-porch = <1>; + hback-porch = <45>; + vfront-porch = <1>; + vback-porch = <3>; + + /* Some dummy parameters */ + clock-frequency = <0>; + hsync-len = <0>; + vsync-len = <0>; + }; + }; + }; }; }; }; diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h index 27c858013d..886456ec26 100644 --- a/include/configs/theadorable.h +++ b/include/configs/theadorable.h @@ -65,6 +65,10 @@ /* Enable LCD and reserve 512KB from top of memory*/ #define CONFIG_SYS_MEM_TOP_HIDE 0x80000 +#define CONFIG_BMP_16BPP +#define CONFIG_BMP_24BPP +#define CONFIG_BMP_32BPP + /* FPGA programming support */ #define CONFIG_FPGA_STRATIX_V