]> git.karo-electronics.de Git - karo-tx-uboot.git/commitdiff
Merge git://git.denx.de/u-boot-marvell
authorTom Rini <trini@konsulko.com>
Mon, 17 Aug 2015 21:19:40 +0000 (17:19 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 17 Aug 2015 21:19:40 +0000 (17:19 -0400)
19 files changed:
arch/arm/cpu/arm926ejs/armada100/dram.c
arch/arm/mach-mvebu/Makefile
arch/arm/mach-mvebu/cpu.c
arch/arm/mach-mvebu/dram.c
arch/arm/mach-mvebu/include/mach/cpu.h
arch/arm/mach-mvebu/include/mach/soc.h
arch/arm/mach-mvebu/mbus.c
board/Marvell/db-88f6820-gp/db-88f6820-gp.c
board/Marvell/db-mv784mp-gp/db-mv784mp-gp.c
drivers/ddr/marvell/axp/ddr3_axp_config.h
drivers/ddr/marvell/axp/xor.c
drivers/ddr/marvell/axp/xor.h
drivers/net/mvneta.c
drivers/pci/Makefile
drivers/pci/pci_mvebu.c [new file with mode: 0644]
drivers/usb/host/ehci-marvell.c
include/configs/db-88f6820-gp.h
include/configs/db-mv784mp-gp.h
include/configs/maxbcm.h

index 8d7c71ff68c4652ff808cde5aaaa33b16d1290f5..f3b9a66cd5aad5dcddd9499aa7906baf8188fe59 100644 (file)
@@ -72,7 +72,6 @@ u32 armd1_sdram_size(int chip_sel)
        }
 }
 
-#ifndef CONFIG_SYS_BOARD_DRAM_INIT
 int dram_init(void)
 {
        int i;
@@ -113,4 +112,3 @@ void dram_init_banksize(void)
 {
        dram_init();
 }
-#endif /* CONFIG_SYS_BOARD_DRAM_INIT */
index 446ce04109740cb47c57becab6e9f6c1ce557f79..21c56a4d969889a054467a1cba134efac70edf20 100644 (file)
@@ -14,6 +14,10 @@ else
 
 obj-y  = cpu.o
 obj-y  += dram.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_SYS_MVEBU_DDR_A38X) += ../../../drivers/ddr/marvell/a38x/xor.o
+obj-$(CONFIG_SYS_MVEBU_DDR_AXP) += ../../../drivers/ddr/marvell/axp/xor.o
+endif
 obj-y  += gpio.o
 obj-y  += mbus.o
 obj-y  += timer.o
index 9496d5fc5b9b153257e54d0ef0bb56b47f74b787..ea83e21d433cd6d639ce1bf0e54087f6720f2575 100644 (file)
 #define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
 
 static struct mbus_win windows[] = {
-       /* PCIE MEM address space */
-       { DEFADR_PCI_MEM, 256 << 20, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_MEM },
-
-       /* PCIE IO address space */
-       { DEFADR_PCI_IO, 64 << 10, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_IO },
-
        /* SPI */
-       { DEFADR_SPIF, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI,
-         CPU_ATTR_SPIFLASH },
+       { MBUS_SPI_BASE, MBUS_SPI_SIZE,
+         CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH },
 
        /* NOR */
-       { DEFADR_BOOTROM, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI,
-         CPU_ATTR_BOOTROM },
+       { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE,
+         CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM },
 };
 
 void reset_cpu(unsigned long ignored)
@@ -177,17 +171,69 @@ static void set_cbar(u32 addr)
        asm("mcr p15, 4, %0, c15, c0" : : "r" (addr));
 }
 
+#define MV_USB_PHY_BASE                        (MVEBU_AXP_USB_BASE + 0x800)
+#define MV_USB_PHY_PLL_REG(reg)                (MV_USB_PHY_BASE | (((reg) & 0xF) << 2))
+#define MV_USB_X3_BASE(addr)           (MVEBU_AXP_USB_BASE | BIT(11) | \
+                                        (((addr) & 0xF) << 6))
+#define MV_USB_X3_PHY_CHANNEL(dev, reg)        (MV_USB_X3_BASE((dev) + 1) |    \
+                                        (((reg) & 0xF) << 2))
 
-int arch_cpu_init(void)
+static void setup_usb_phys(void)
 {
-#ifndef CONFIG_SPL_BUILD
+       int dev;
+
+       /*
+        * USB PLL init
+        */
+
+       /* Setup PLL frequency */
+       /* USB REF frequency = 25 MHz */
+       clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0x3ff, 0x605);
+
+       /* Power up PLL and PHY channel */
+       clrsetbits_le32(MV_USB_PHY_PLL_REG(2), 0, BIT(9));
+
+       /* Assert VCOCAL_START */
+       clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0, BIT(21));
+
+       mdelay(1);
+
        /*
-        * Only with disabled MMU its possible to switch the base
-        * register address on Armada 38x. Without this the SDRAM
-        * located at >= 0x4000.0000 is also not accessible, as its
-        * still locked to cache.
+        * USB PHY init (change from defaults) specific for 40nm (78X30 78X60)
         */
-       mmu_disable();
+
+       for (dev = 0; dev < 3; dev++) {
+               clrsetbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 3), 0, BIT(15));
+
+               /* Assert REG_RCAL_START in channel REG 1 */
+               clrsetbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), 0, BIT(12));
+               udelay(40);
+               clrsetbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12), 0);
+       }
+}
+
+int arch_cpu_init(void)
+{
+#ifndef CONFIG_SPL_BUILD
+       if (mvebu_soc_family() == MVEBU_SOC_A38X) {
+               struct pl310_regs *const pl310 =
+                       (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
+
+               /*
+                * Only with disabled MMU its possible to switch the base
+                * register address on Armada 38x. Without this the SDRAM
+                * located at >= 0x4000.0000 is also not accessible, as its
+                * still locked to cache.
+                *
+                * So to fully release / unlock this area from cache, we need
+                * to first flush all caches, then disable the MMU and
+                * disable the L2 cache.
+                */
+               icache_disable();
+               dcache_disable();
+               mmu_disable();
+               clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+       }
 #endif
 
        /* Linux expects the internal registers to be at 0xf1000000 */
@@ -227,10 +273,33 @@ int arch_cpu_init(void)
         */
        mvebu_mbus_probe(windows, ARRAY_SIZE(windows));
 
+       if (mvebu_soc_family() == MVEBU_SOC_AXP) {
+               /* Enable GBE0, GBE1, LCD and NFC PUP */
+               clrsetbits_le32(ARMADA_XP_PUP_ENABLE, 0,
+                               GE0_PUP_EN | GE1_PUP_EN | LCD_PUP_EN |
+                               NAND_PUP_EN | SPI_PUP_EN);
+
+               /* Configure USB PLL and PHYs on AXP */
+               setup_usb_phys();
+       }
+
+       /* Enable NAND and NAND arbiter */
+       clrsetbits_le32(MVEBU_SOC_DEV_MUX_REG, 0, NAND_EN | NAND_ARBITER_EN);
+
+       /* Disable MBUS error propagation */
+       clrsetbits_le32(SOC_COHERENCY_FABRIC_CTRL_REG, MBUS_ERR_PROP_EN, 0);
+
        return 0;
 }
 #endif /* CONFIG_ARCH_CPU_INIT */
 
+u32 mvebu_get_nand_clock(void)
+{
+       return CONFIG_SYS_MVEBU_PLL_CLOCK /
+               ((readl(MVEBU_CORE_DIV_CLK_CTRL(1)) &
+                 NAND_ECC_DIVCKL_RATIO_MASK) >> NAND_ECC_DIVCKL_RATIO_OFFS);
+}
+
 /*
  * SOC specific misc init
  */
index db18791a8627e77f9baba41199a9ba5fba3af37c..ddc5b7ee3eaf5b49cf4dcd410f2cad3a826bc955 100644 (file)
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
 
+#ifdef CONFIG_SYS_MVEBU_DDR_A38X
+#include "../../../drivers/ddr/marvell/axp/xor.h"
+#include "../../../drivers/ddr/marvell/axp/xor_regs.h"
+#endif
+#ifdef CONFIG_SYS_MVEBU_DDR_AXP
+#include "../../../drivers/ddr/marvell/axp/xor.h"
+#include "../../../drivers/ddr/marvell/axp/xor_regs.h"
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 struct sdram_bank {
@@ -28,6 +37,16 @@ struct sdram_addr_dec {
 #define REG_CPUCS_WIN_WIN0_CS(x)       (((x) & 0x3) << 2)
 #define REG_CPUCS_WIN_SIZE(x)          (((x) & 0xff) << 24)
 
+#define SDRAM_SIZE_MAX                 0xc0000000
+
+#define SCRUB_MAGIC            0xbeefdead
+
+#define SCRB_XOR_UNIT          0
+#define SCRB_XOR_CHAN          1
+#define SCRB_XOR_WIN           0
+
+#define XEBARX_BASE_OFFS       16
+
 /*
  * mvebu_sdram_bar - reads SDRAM Base Address Register
  */
@@ -93,32 +112,146 @@ void mvebu_sdram_size_adjust(enum memory_bank bank)
        mvebu_sdram_bs_set(bank, size);
 }
 
-#ifndef CONFIG_SYS_BOARD_DRAM_INIT
+#if defined(CONFIG_SYS_MVEBU_DDR_A38X) || defined(CONFIG_SYS_MVEBU_DDR_AXP)
+static u32 xor_ctrl_save;
+static u32 xor_base_save;
+static u32 xor_mask_save;
+
+static void mv_xor_init2(u32 cs)
+{
+       u32 reg, base, size, base2;
+       u32 bank_attr[4] = { 0xe00, 0xd00, 0xb00, 0x700 };
+
+       xor_ctrl_save = reg_read(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT,
+                                                    SCRB_XOR_CHAN));
+       xor_base_save = reg_read(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT,
+                                                  SCRB_XOR_WIN));
+       xor_mask_save = reg_read(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT,
+                                                  SCRB_XOR_WIN));
+
+       /* Enable Window x for each CS */
+       reg = 0x1;
+       reg |= (0x3 << 16);
+       reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN), reg);
+
+       base = 0;
+       size = mvebu_sdram_bs(cs) - 1;
+       if (size) {
+               base2 = ((base / (64 << 10)) << XEBARX_BASE_OFFS) |
+                       bank_attr[cs];
+               reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
+                         base2);
+
+               base += size + 1;
+               size = (size / (64 << 10)) << 16;
+               /* Window x - size - 256 MB */
+               reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN), size);
+       }
+
+       mv_xor_hal_init(0);
+
+       return;
+}
+
+static void mv_xor_finish2(void)
+{
+       reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN),
+                 xor_ctrl_save);
+       reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
+                 xor_base_save);
+       reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
+                 xor_mask_save);
+}
+
+static void dram_ecc_scrubbing(void)
+{
+       int cs;
+       u32 size, temp;
+       u32 total_mem = 0;
+       u64 total;
+       u32 start_addr;
+
+       /*
+        * The DDR training code from the bin_hdr / SPL already
+        * scrubbed the DDR till 0x1000000. And the main U-Boot
+        * is loaded to an address < 0x1000000. So we need to
+        * skip this range to not re-scrub this area again.
+        */
+       temp = reg_read(REG_SDRAM_CONFIG_ADDR);
+       temp |= (1 << REG_SDRAM_CONFIG_IERR_OFFS);
+       reg_write(REG_SDRAM_CONFIG_ADDR, temp);
+
+       for (cs = 0; cs < CONFIG_NR_DRAM_BANKS; cs++) {
+               size = mvebu_sdram_bs(cs) - 1;
+               if (size == 0)
+                       continue;
+
+               total = (u64)size + 1;
+               total_mem += (u32)(total / (1 << 30));
+               start_addr = 0;
+               mv_xor_init2(cs);
+
+               /* Skip first 16 MiB */
+               if (0 == cs) {
+                       start_addr = 0x1000000;
+                       size -= start_addr;
+               }
+
+               mv_xor_mem_init(SCRB_XOR_CHAN, start_addr, size,
+                               SCRUB_MAGIC, SCRUB_MAGIC);
+
+               /* Wait for previous transfer completion */
+               while (mv_xor_state_get(SCRB_XOR_CHAN) != MV_IDLE)
+                       ;
+
+               mv_xor_finish2();
+       }
+
+       temp = reg_read(REG_SDRAM_CONFIG_ADDR);
+       temp &= ~(1 << REG_SDRAM_CONFIG_IERR_OFFS);
+       reg_write(REG_SDRAM_CONFIG_ADDR, temp);
+}
+
+static int ecc_enabled(void)
+{
+       if (reg_read(REG_SDRAM_CONFIG_ADDR) & (1 << REG_SDRAM_CONFIG_ECC_OFFS))
+               return 1;
+
+       return 0;
+}
+#else
+static void dram_ecc_scrubbing(void)
+{
+}
+
+static int ecc_enabled(void)
+{
+       return 0;
+}
+#endif
+
 int dram_init(void)
 {
+       u64 size = 0;
        int i;
 
-       gd->ram_size = 0;
        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-               gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
-               gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);
                /*
                 * It is assumed that all memory banks are consecutive
                 * and without gaps.
                 * If the gap is found, ram_size will be reported for
                 * consecutive memory only
                 */
-               if (gd->bd->bi_dram[i].start != gd->ram_size)
+               if (mvebu_sdram_bar(i) != size)
                        break;
 
                /*
                 * Don't report more than 3GiB of SDRAM, otherwise there is no
                 * address space left for the internal registers etc.
                 */
-               if ((gd->ram_size + gd->bd->bi_dram[i].size != 0) &&
-                   (gd->ram_size + gd->bd->bi_dram[i].size <= (3 << 30)))
-                       gd->ram_size += gd->bd->bi_dram[i].size;
-
+               size += mvebu_sdram_bs(i);
+               if (size > SDRAM_SIZE_MAX)
+                       size = SDRAM_SIZE_MAX;
        }
 
        for (; i < CONFIG_NR_DRAM_BANKS; i++) {
@@ -130,6 +263,12 @@ int dram_init(void)
                gd->bd->bi_dram[i].size = 0;
        }
 
+
+       if (ecc_enabled())
+               dram_ecc_scrubbing();
+
+       gd->ram_size = size;
+
        return 0;
 }
 
@@ -139,6 +278,25 @@ int dram_init(void)
  */
 void dram_init_banksize(void)
 {
-       dram_init();
+       u64 size = 0;
+       int i;
+
+       for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+               gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
+               gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);
+
+               /* Clip the banksize to 1GiB if it exceeds the max size */
+               size += gd->bd->bi_dram[i].size;
+               if (size > SDRAM_SIZE_MAX)
+                       mvebu_sdram_bs_set(i, 0x40000000);
+       }
+}
+
+void board_add_ram_info(int use_default)
+{
+       if (ecc_enabled())
+               printf(" (ECC");
+       else
+               printf(" (ECC not");
+       printf(" enabled)");
 }
-#endif /* CONFIG_SYS_BOARD_DRAM_INIT */
index 8bcdef689f5fcf2dbda583a618b56b2a1f2cbb30..6fa41736e2aa140c354bd61bc9d3fc6a03e33bd7 100644 (file)
@@ -65,10 +65,14 @@ enum {
 /*
  * Default Device Address MAP BAR values
  */
-#define DEFADR_PCI_MEM         0x90000000
-#define DEFADR_PCI_IO          0xC0000000
-#define DEFADR_SPIF            0xF4000000
-#define DEFADR_BOOTROM         0xF8000000
+#define MBUS_PCI_MEM_BASE      0xE8000000
+#define MBUS_PCI_MEM_SIZE      (128 << 20)
+#define MBUS_PCI_IO_BASE       0xF1100000
+#define MBUS_PCI_IO_SIZE       (64 << 10)
+#define MBUS_SPI_BASE          0xF4000000
+#define MBUS_SPI_SIZE          (8 << 20)
+#define MBUS_BOOTROM_BASE      0xF8000000
+#define MBUS_BOOTROM_SIZE      (8 << 20)
 
 struct mbus_win {
        u32 base;
@@ -113,6 +117,7 @@ unsigned int mvebu_sdram_bs(enum memory_bank bank);
 void mvebu_sdram_size_adjust(enum memory_bank bank);
 int mvebu_mbus_probe(struct mbus_win windows[], int count);
 int mvebu_soc_family(void);
+u32 mvebu_get_nand_clock(void);
 
 int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks);
 
index 125b5f278d695bc136a512a79352670b3b4d3657..a8a6b27d802b7c4e4dc9caa512e49b9daaf72c87 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef _MVEBU_SOC_H
 #define _MVEBU_SOC_H
 
+#define BIT(x)                 (1 << (x))
+
 #define SOC_MV78460_ID         0x7846
 #define SOC_88F6810_ID         0x6810
 #define SOC_88F6820_ID         0x6820
@@ -25,6 +27,9 @@
 #define CONFIG_SYS_TCLK                250000000       /* 250MHz */
 #endif
 
+/* Armada XP PLL frequency (used for NAND clock generation) */
+#define CONFIG_SYS_MVEBU_PLL_CLOCK     2000000000
+
 /* SOC specific definations */
 #define INTREG_BASE            0xd0000000
 #define INTREG_BASE_ADDR_REG   (INTREG_BASE + 0x20080)
 #define MVEBU_GPIO1_BASE       (MVEBU_REGISTER(0x18140))
 #define MVEBU_GPIO2_BASE       (MVEBU_REGISTER(0x18180))
 #define MVEBU_SYSTEM_REG_BASE  (MVEBU_REGISTER(0x18200))
+#define MVEBU_CLOCK_BASE       (MVEBU_REGISTER(0x18700))
 #define MVEBU_CPU_WIN_BASE     (MVEBU_REGISTER(0x20000))
 #define MVEBU_SDRAM_BASE       (MVEBU_REGISTER(0x20180))
 #define MVEBU_TIMER_BASE       (MVEBU_REGISTER(0x20300))
 #define MVEBU_EGIGA2_BASE      (MVEBU_REGISTER(0x30000))
 #define MVEBU_EGIGA3_BASE      (MVEBU_REGISTER(0x34000))
 #define MVEBU_REG_PCIE_BASE    (MVEBU_REGISTER(0x40000))
+#define MVEBU_AXP_USB_BASE      (MVEBU_REGISTER(0x50000))
 #define MVEBU_USB20_BASE       (MVEBU_REGISTER(0x58000))
 #define MVEBU_EGIGA0_BASE      (MVEBU_REGISTER(0x70000))
 #define MVEBU_EGIGA1_BASE      (MVEBU_REGISTER(0x74000))
 #define MVEBU_AXP_SATA_BASE    (MVEBU_REGISTER(0xa0000))
 #define MVEBU_SATA0_BASE       (MVEBU_REGISTER(0xa8000))
+#define MVEBU_NAND_BASE                (MVEBU_REGISTER(0xd0000))
 #define MVEBU_SDIO_BASE                (MVEBU_REGISTER(0xd8000))
 
+#define SOC_COHERENCY_FABRIC_CTRL_REG  (MVEBU_REGISTER(0x20200))
+#define MBUS_ERR_PROP_EN       (1 << 8)
+
+#define MBUS_BRIDGE_WIN_CTRL_REG (MVEBU_REGISTER(0x20250))
+#define MBUS_BRIDGE_WIN_BASE_REG (MVEBU_REGISTER(0x20254))
+
+#define MVEBU_SOC_DEV_MUX_REG  (MVEBU_SYSTEM_REG_BASE + 0x08)
+#define NAND_EN                        BIT(0)
+#define NAND_ARBITER_EN                BIT(27)
+
+#define ARMADA_XP_PUP_ENABLE   (MVEBU_SYSTEM_REG_BASE + 0x44c)
+#define GE0_PUP_EN             BIT(0)
+#define GE1_PUP_EN             BIT(1)
+#define LCD_PUP_EN             BIT(2)
+#define NAND_PUP_EN            BIT(4)
+#define SPI_PUP_EN             BIT(5)
+
+#define MVEBU_CORE_DIV_CLK_CTRL(i)     (MVEBU_CLOCK_BASE + ((i) * 0x8))
+#define NAND_ECC_DIVCKL_RATIO_OFFS     8
+#define NAND_ECC_DIVCKL_RATIO_MASK     (0x3F << NAND_ECC_DIVCKL_RATIO_OFFS)
+
 #define SDRAM_MAX_CS           4
 #define SDRAM_ADDR_MASK                0xFF000000
 
index 9b76bce91d03a11d2a7f5246e5751e2bcea794a4..771cce6fa3b7a381d8400bc196f018fee897439f 100644 (file)
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
+#include <linux/compat.h>
 #include <linux/mbus.h>
 
-#define BIT(nr)                        (1UL << (nr))
-
 /* DDR target is the same on all platforms */
 #define TARGET_DDR             0
 
@@ -407,6 +406,53 @@ int mvebu_mbus_del_window(phys_addr_t base, size_t size)
        return 0;
 }
 
+static void mvebu_mbus_get_lowest_base(struct mvebu_mbus_state *mbus,
+                                      phys_addr_t *base)
+{
+       int win;
+       *base = 0xffffffff;
+
+       for (win = 0; win < mbus->soc->num_wins; win++) {
+               u64 wbase;
+               u32 wsize;
+               u8 wtarget, wattr;
+               int enabled;
+
+               mvebu_mbus_read_window(mbus, win,
+                                      &enabled, &wbase, &wsize,
+                                      &wtarget, &wattr, NULL);
+
+               if (!enabled)
+                       continue;
+
+               if (wbase < *base)
+                       *base = wbase;
+       }
+}
+
+static void mvebu_config_mbus_bridge(struct mvebu_mbus_state *mbus)
+{
+       phys_addr_t base;
+       u32 val;
+       u32 size;
+
+       /* Set MBUS bridge base/ctrl */
+       mvebu_mbus_get_lowest_base(&mbus_state, &base);
+
+       size = 0xffffffff - base + 1;
+       if (!is_power_of_2(size)) {
+               /* Round up to next power of 2 */
+               size = 1 << (ffs(base) + 1);
+               base = 0xffffffff - size + 1;
+       }
+
+       /* Now write base and size */
+       writel(base, MBUS_BRIDGE_WIN_BASE_REG);
+       /* Align window size to 64KiB */
+       val = (size / (64 << 10)) - 1;
+       writel((val << 16) | 0x1, MBUS_BRIDGE_WIN_CTRL_REG);
+}
+
 int mbus_dt_setup_win(struct mvebu_mbus_state *mbus,
                      u32 base, u32 size, u8 target, u8 attr)
 {
@@ -426,6 +472,13 @@ int mbus_dt_setup_win(struct mvebu_mbus_state *mbus,
                        return -ENOMEM;
        }
 
+       /*
+        * Re-configure the mbus bridge registers each time this function
+        * is called. Since it may get called from the board code in
+        * later boot stages as well.
+        */
+       mvebu_config_mbus_bridge(mbus);
+
        return 0;
 }
 
index e661fa129671d3ef1cdd9d4dd65abfb604d3f566..84ca55c7d5025d6a61c8f1fd4049c983aaa2f992 100644 (file)
@@ -7,6 +7,7 @@
 #include <common.h>
 #include <i2c.h>
 #include <miiphy.h>
+#include <netdev.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
@@ -15,8 +16,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define BIT(nr)                                (1UL << (nr))
-
 #define ETH_PHY_CTRL_REG               0
 #define ETH_PHY_CTRL_POWER_DOWN_BIT    11
 #define ETH_PHY_CTRL_POWER_DOWN_MASK   (1 << ETH_PHY_CTRL_POWER_DOWN_BIT)
@@ -132,3 +131,9 @@ int checkboard(void)
 
        return 0;
 }
+
+int board_eth_init(bd_t *bis)
+{
+       cpu_eth_init(bis); /* Built in controller(s) come first */
+       return pci_eth_init(bis);
+}
index 00ca878873d92a807a92a5af7778119eb80609c5..d7aa1499adf00aa6484107d8d9c6f7c70ebd2a9c 100644 (file)
@@ -6,14 +6,13 @@
 
 #include <common.h>
 #include <miiphy.h>
+#include <netdev.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define BIT(nr)                                (1UL << (nr))
-
 #define ETH_PHY_CTRL_REG               0
 #define ETH_PHY_CTRL_POWER_DOWN_BIT    11
 #define ETH_PHY_CTRL_POWER_DOWN_MASK   (1 << ETH_PHY_CTRL_POWER_DOWN_BIT)
@@ -82,6 +81,12 @@ int checkboard(void)
        return 0;
 }
 
+int board_eth_init(bd_t *bis)
+{
+       cpu_eth_init(bis); /* Built in controller(s) come first */
+       return pci_eth_init(bis);
+}
+
 #ifdef CONFIG_RESET_PHY_R
 /* Configure and enable MV88E1545 PHY */
 void reset_phy(void)
index 800d2d14765db396c547cc76b2bc196dfd0bb820..a6720442ffae5d06c7f9ddd3d4fa8b4e01b5b010 100644 (file)
@@ -44,7 +44,7 @@
  * DDR3_TRAINING_DEBUG - Debug prints of internal code
  */
 #define DDR_TARGET_FABRIC                      5
-#define DRAM_ECC                               0
+#define DRAM_ECC                               1
 
 #ifdef MV_DDR_32BIT
 #define BUS_WIDTH                               32
index 66c96aef4ecb826aca9f0387d75a315f8ec7d6be..54924cac3ca32fee43ed36dda0afe0bd5e5e7e4d 100644 (file)
@@ -18,7 +18,6 @@ static u32 xor_regs_ctrl_backup;
 static u32 xor_regs_base_backup[MAX_CS];
 static u32 xor_regs_mask_backup[MAX_CS];
 
-static void mv_xor_hal_init(u32 chan_num);
 static int mv_xor_cmd_set(u32 chan, int command);
 static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl);
 
@@ -110,7 +109,7 @@ void mv_sys_xor_finish(void)
  * RETURN:
  *       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  */
-static void mv_xor_hal_init(u32 chan_num)
+void mv_xor_hal_init(u32 chan_num)
 {
        u32 i;
 
index 353648758a907d3eeae3a889880e804222e59141..3ff784d7a984d166f131e4fdc6d7dd23fd16f868 100644 (file)
@@ -60,6 +60,7 @@ struct crc_dma_desc {
        u32 src_addr1;          /* Mode: Source Block address pointer */
 } __packed;
 
+void mv_xor_hal_init(u32 chan_num);
 int mv_xor_state_get(u32 chan);
 void mv_sys_xor_init(MV_DRAM_INFO *dram_info);
 void mv_sys_xor_finish(void);
index efaae167feffc904c08fe76cb8a8ffdf296ebd35..38ad14eff96dc8a62dc0bba4af2b5a41d8986583 100644 (file)
@@ -41,7 +41,6 @@
        printf(fmt, ##args)
 
 #define CONFIG_NR_CPUS         1
-#define BIT(nr)                        (1UL << (nr))
 #define ETH_HLEN               14      /* Total octets in header */
 
 /* 2(HW hdr) 14(MAC hdr) 4(CRC) 32(extra for cache prefetch) */
index adc238f0f09ba61c0e98aea106a0c99ec2ec6e1d..bcf8127b98dcc8961913774af55281261ca4cb81 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o
 obj-$(CONFIG_PCI_MSC01) += pci_msc01.o
 obj-$(CONFIG_PCIE_IMX) += pcie_imx.o
 obj-$(CONFIG_FTPCI100) += pci_ftpci100.o
+obj-$(CONFIG_PCI_MVEBU) += pci_mvebu.o
 obj-$(CONFIG_SH4_PCI) += pci_sh4.o
 obj-$(CONFIG_SH7751_PCI) +=pci_sh7751.o
 obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
new file mode 100644 (file)
index 0000000..fd2744d
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * PCIe driver for Marvell MVEBU SoCs
+ *
+ * Based on Barebox drivers/pci/pci-mvebu.c
+ *
+ * Ported to U-Boot by:
+ * Anton Schubert <anton.schubert@gmx.de>
+ * Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+#include <linux/mbus.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* PCIe unit register offsets */
+#define SELECT(x, n)                   ((x >> n) & 1UL)
+
+#define PCIE_DEV_ID_OFF                        0x0000
+#define PCIE_CMD_OFF                   0x0004
+#define PCIE_DEV_REV_OFF               0x0008
+#define  PCIE_BAR_LO_OFF(n)            (0x0010 + ((n) << 3))
+#define  PCIE_BAR_HI_OFF(n)            (0x0014 + ((n) << 3))
+#define PCIE_CAPAB_OFF                 0x0060
+#define PCIE_CTRL_STAT_OFF             0x0068
+#define PCIE_HEADER_LOG_4_OFF          0x0128
+#define  PCIE_BAR_CTRL_OFF(n)          (0x1804 + (((n) - 1) * 4))
+#define  PCIE_WIN04_CTRL_OFF(n)                (0x1820 + ((n) << 4))
+#define  PCIE_WIN04_BASE_OFF(n)                (0x1824 + ((n) << 4))
+#define  PCIE_WIN04_REMAP_OFF(n)       (0x182c + ((n) << 4))
+#define PCIE_WIN5_CTRL_OFF             0x1880
+#define PCIE_WIN5_BASE_OFF             0x1884
+#define PCIE_WIN5_REMAP_OFF            0x188c
+#define PCIE_CONF_ADDR_OFF             0x18f8
+#define  PCIE_CONF_ADDR_EN             BIT(31)
+#define  PCIE_CONF_REG(r)              ((((r) & 0xf00) << 16) | ((r) & 0xfc))
+#define  PCIE_CONF_BUS(b)              (((b) & 0xff) << 16)
+#define  PCIE_CONF_DEV(d)              (((d) & 0x1f) << 11)
+#define  PCIE_CONF_FUNC(f)             (((f) & 0x7) << 8)
+#define  PCIE_CONF_ADDR(dev, reg) \
+       (PCIE_CONF_BUS(PCI_BUS(dev)) | PCIE_CONF_DEV(PCI_DEV(dev))    | \
+        PCIE_CONF_FUNC(PCI_FUNC(dev)) | PCIE_CONF_REG(reg) | \
+        PCIE_CONF_ADDR_EN)
+#define PCIE_CONF_DATA_OFF             0x18fc
+#define PCIE_MASK_OFF                  0x1910
+#define  PCIE_MASK_ENABLE_INTS          (0xf << 24)
+#define PCIE_CTRL_OFF                  0x1a00
+#define  PCIE_CTRL_X1_MODE             BIT(0)
+#define PCIE_STAT_OFF                  0x1a04
+#define  PCIE_STAT_BUS                  (0xff << 8)
+#define  PCIE_STAT_DEV                  (0x1f << 16)
+#define  PCIE_STAT_LINK_DOWN           BIT(0)
+#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;
+       u32 lane_mask;
+       pci_dev_t dev;
+};
+
+#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 32M of MEM
+ * and 64K of I/O space when registered.
+ */
+static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
+#define PCIE_MEM_SIZE  (32 << 20)
+
+#if defined(CONFIG_ARMADA_38X)
+#define PCIE_BASE(if)                                  \
+       ((if) == 0 ?                                    \
+        MVEBU_REG_PCIE_BASE + 0x40000 :                \
+        MVEBU_REG_PCIE_BASE + 0x4000 * (if))
+
+/*
+ * On A38x MV6820 these PEX ports are supported:
+ *  0 - Port 0.0
+ *  1 - Port 0.1
+ *  2 - Port 0.2
+ */
+#define MAX_PEX 3
+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 };
+       u8 lane[] = { 0, 0, 0 };
+       u8 target[] = { 8, 4, 4 };
+       u8 attr[] = { 0xe8, 0xe8, 0xd8 };
+
+       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 inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
+{
+       u32 val;
+       val = readl(pcie->base + PCIE_STAT_OFF);
+       return !(val & PCIE_STAT_LINK_DOWN);
+}
+
+static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
+{
+       u32 stat;
+
+       stat = readl(pcie->base + PCIE_STAT_OFF);
+       stat &= ~PCIE_STAT_BUS;
+       stat |= busno << 8;
+       writel(stat, pcie->base + PCIE_STAT_OFF);
+}
+
+static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie *pcie, int devno)
+{
+       u32 stat;
+
+       stat = readl(pcie->base + PCIE_STAT_OFF);
+       stat &= ~PCIE_STAT_DEV;
+       stat |= devno << 16;
+       writel(stat, pcie->base + PCIE_STAT_OFF);
+}
+
+static int mvebu_pcie_get_local_bus_nr(struct mvebu_pcie *pcie)
+{
+       u32 stat;
+
+       stat = readl(pcie->base + PCIE_STAT_OFF);
+       return (stat & PCIE_STAT_BUS) >> 8;
+}
+
+static int mvebu_pcie_get_local_dev_nr(struct mvebu_pcie *pcie)
+{
+       u32 stat;
+
+       stat = readl(pcie->base + PCIE_STAT_OFF);
+       return (stat & PCIE_STAT_DEV) >> 16;
+}
+
+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)
+{
+       struct mvebu_pcie *pcie = hose_to_pcie(hose);
+       int local_bus = PCI_BUS(pcie->dev);
+       int local_dev = PCI_DEV(pcie->dev);
+       u32 reg;
+
+       /* 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 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) {
+                       /*
+                        * If local dev is not 0, the first other dev can
+                        * only be 0
+                        */
+                       *val = 0xffffffff;
+                       return 1;
+               }
+       }
+
+       /* write address */
+       reg = PCIE_CONF_ADDR(dev, offset);
+       writel(reg, pcie->base + PCIE_CONF_ADDR_OFF);
+       *val = readl(pcie->base + PCIE_CONF_DATA_OFF);
+
+       return 0;
+}
+
+static int mvebu_pcie_write_config_dword(struct pci_controller *hose,
+               pci_dev_t dev, int offset, u32 val)
+{
+       struct mvebu_pcie *pcie = hose_to_pcie(hose);
+       int local_bus = PCI_BUS(pcie->dev);
+       int local_dev = PCI_DEV(pcie->dev);
+
+       /* 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 local dev is 0, the first other dev can
+                        * only be 1
+                        */
+                       return 1;
+               } else if (local_dev != 0 && PCI_DEV(dev) != 0) {
+                       /*
+                        * If local dev is not 0, the first other dev can
+                        * only be 0
+                        */
+                       return 1;
+               }
+       }
+
+       writel(PCIE_CONF_ADDR(dev, offset), pcie->base + PCIE_CONF_ADDR_OFF);
+       writel(val, pcie->base + PCIE_CONF_DATA_OFF);
+
+       return 0;
+}
+
+/*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+ * WIN[0-3] -> DRAM bank[0-3]
+ */
+static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
+{
+       const struct mbus_dram_target_info *dram = mvebu_mbus_dram_info();
+       u32 size;
+       int i;
+
+       /* First, disable and clear BARs and windows. */
+       for (i = 1; i < 3; i++) {
+               writel(0, pcie->base + PCIE_BAR_CTRL_OFF(i));
+               writel(0, pcie->base + PCIE_BAR_LO_OFF(i));
+               writel(0, pcie->base + PCIE_BAR_HI_OFF(i));
+       }
+
+       for (i = 0; i < 5; i++) {
+               writel(0, pcie->base + PCIE_WIN04_CTRL_OFF(i));
+               writel(0, pcie->base + PCIE_WIN04_BASE_OFF(i));
+               writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
+       }
+
+       writel(0, pcie->base + PCIE_WIN5_CTRL_OFF);
+       writel(0, pcie->base + PCIE_WIN5_BASE_OFF);
+       writel(0, pcie->base + PCIE_WIN5_REMAP_OFF);
+
+       /* Setup windows for DDR banks. Count total DDR size on the fly. */
+       size = 0;
+       for (i = 0; i < dram->num_cs; i++) {
+               const struct mbus_dram_window *cs = dram->cs + i;
+
+               writel(cs->base & 0xffff0000,
+                      pcie->base + PCIE_WIN04_BASE_OFF(i));
+               writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
+               writel(((cs->size - 1) & 0xffff0000) |
+                      (cs->mbus_attr << 8) |
+                      (dram->mbus_dram_target_id << 4) | 1,
+                      pcie->base + PCIE_WIN04_CTRL_OFF(i));
+
+               size += cs->size;
+       }
+
+       /* Round up 'size' to the nearest power of two. */
+       if ((size & (size - 1)) != 0)
+               size = 1 << fls(size);
+
+       /* Setup BAR[1] to all DRAM banks. */
+       writel(dram->cs[0].base | 0xc, pcie->base + PCIE_BAR_LO_OFF(1));
+       writel(0, pcie->base + PCIE_BAR_HI_OFF(1));
+       writel(((size - 1) & 0xffff0000) | 0x1,
+              pcie->base + PCIE_BAR_CTRL_OFF(1));
+}
+
+void pci_init_board(void)
+{
+       int mem_target, mem_attr, i;
+       int bus = 0;
+       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));
+
+       for (i = 0; i < MAX_PEX; i++) {
+               struct mvebu_pcie *pcie = &pcie_bus[i];
+               struct pci_controller *hose = &pcie->hose;
+
+               /* Get port number, lane number and memory target / attr */
+               mvebu_get_port_lane(pcie, i, &mem_target, &mem_attr);
+
+               /* Don't read at all from pci registers if port power is down */
+               if (pcie->lane == 0 && SELECT(soc_ctrl, pcie->port) == 0) {
+                       i += 3;
+                       debug("%s: skipping port %d\n", __func__, pcie->port);
+                       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;
+       }
+}
index 3a9f60f169d893917374c92bc5e3b3b9b5516ca7..50fa01c07989779650264d872bd6954d246222d6 100644 (file)
@@ -30,14 +30,22 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 #ifdef CONFIG_ARMADA_XP
 
-#define MVUSB0_BASE            MVEBU_USB20_BASE
+/*
+ * Armada XP and Armada 38x have different base addresses for
+ * the USB 2.0 EHCI host controller. So we need to provide
+ * a mechnism to support both here.
+ */
+#define MVUSB0_BASE                                    \
+       (mvebu_soc_family() == MVEBU_SOC_A38X ?         \
+        MVEBU_USB20_BASE : MVEBU_AXP_USB_BASE)
+#define MVUSB_BASE(port)       MVUSB0_BASE + ((port) << 12)
 
 /*
  * Once all the older Marvell SoC's (Orion, Kirkwood) are converted
  * to the common mvebu archticture including the mbus setup, this
  * will be the only function needed to configure the access windows
  */
-static void usb_brg_adrdec_setup(void)
+static void usb_brg_adrdec_setup(int index)
 {
        const struct mbus_dram_target_info *dram;
        int i;
@@ -45,8 +53,8 @@ static void usb_brg_adrdec_setup(void)
        dram = mvebu_mbus_dram_info();
 
        for (i = 0; i < 4; i++) {
-               writel(0, MVUSB0_BASE + USB_WINDOW_CTRL(i));
-               writel(0, MVUSB0_BASE + USB_WINDOW_BASE(i));
+               writel(0, MVUSB_BASE(index) + USB_WINDOW_CTRL(i));
+               writel(0, MVUSB_BASE(index) + USB_WINDOW_BASE(i));
        }
 
        for (i = 0; i < dram->num_cs; i++) {
@@ -55,14 +63,16 @@ static void usb_brg_adrdec_setup(void)
                /* Write size, attributes and target id to control register */
                writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
                       (dram->mbus_dram_target_id << 4) | 1,
-                      MVUSB0_BASE + USB_WINDOW_CTRL(i));
+                      MVUSB_BASE(index) + USB_WINDOW_CTRL(i));
 
                /* Write base address to base register */
-               writel(cs->base, MVUSB0_BASE + USB_WINDOW_BASE(i));
+               writel(cs->base, MVUSB_BASE(index) + USB_WINDOW_BASE(i));
        }
 }
 #else
-static void usb_brg_adrdec_setup(void)
+#define MVUSB_BASE(port)       MVUSB0_BASE
+
+static void usb_brg_adrdec_setup(int index)
 {
        int i;
        u32 size, base, attrib;
@@ -111,9 +121,9 @@ static void usb_brg_adrdec_setup(void)
 int ehci_hcd_init(int index, enum usb_init_type init,
                struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       usb_brg_adrdec_setup();
+       usb_brg_adrdec_setup(index);
 
-       *hccr = (struct ehci_hccr *)(MVUSB0_BASE + 0x100);
+       *hccr = (struct ehci_hccr *)(MVUSB_BASE(index) + 0x100);
        *hcor = (struct ehci_hcor *)((uint32_t) *hccr
                        + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
index 739c2bf3d5553bd81bdd78c72f68b2b9b9d9b9f7..1dd41821366f5d6e61c194a99189911d8ece225b 100644 (file)
 #define CONFIG_SYS_GENERIC_BOARD
 #define CONFIG_DISPLAY_BOARDINFO_LATE
 
-#define        CONFIG_SYS_TEXT_BASE    0x04000000
+/*
+ * TEXT_BASE needs to be below 16MiB, since this area is scrubbed
+ * for DDR ECC byte filling in the SPL before loading the main
+ * U-Boot into it.
+ */
+#define        CONFIG_SYS_TEXT_BASE    0x00800000
 #define CONFIG_SYS_TCLK                250000000       /* 250MHz */
 
 /*
@@ -36,6 +41,7 @@
 #define CONFIG_CMD_FS_GENERIC
 #define CONFIG_CMD_I2C
 #define CONFIG_CMD_MMC
+#define CONFIG_CMD_PCI
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_SCSI
 #define CONFIG_CMD_SF
 #define CONFIG_SYS_NETA_INTERFACE_TYPE PHY_INTERFACE_MODE_RGMII
 #define PHY_ANEG_TIMEOUT       8000    /* PHY needs a longer aneg time */
 
+/* PCIe support */
+#define CONFIG_PCI
+#define CONFIG_PCI_MVEBU
+#define CONFIG_PCI_PNP
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_E1000   /* enable Intel E1000 support for testing */
+
 #define CONFIG_SYS_CONSOLE_INFO_QUIET  /* don't print console @ startup */
 #define CONFIG_SYS_ALT_MEMTEST
 
index 41e6fdcb526b01aea465c433490fa6e440e71f12..eec2ba933ffe351e064c0c1d96ba7fd4cf6ab115 100644 (file)
 #define CONFIG_SYS_GENERIC_BOARD
 #define CONFIG_DISPLAY_BOARDINFO_LATE
 
-#define        CONFIG_SYS_TEXT_BASE    0x04000000
+/*
+ * TEXT_BASE needs to be below 16MiB, since this area is scrubbed
+ * for DDR ECC byte filling in the SPL before loading the main
+ * U-Boot into it.
+ */
+#define        CONFIG_SYS_TEXT_BASE    0x00800000
 #define CONFIG_SYS_TCLK                250000000       /* 250MHz */
 
 /*
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_I2C
 #define CONFIG_CMD_IDE
+#define CONFIG_CMD_PCI
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_SF
 #define CONFIG_CMD_SPI
 #define CONFIG_CMD_TFTPPUT
 #define CONFIG_CMD_TIME
+#define CONFIG_CMD_USB
 
 /* I2C */
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_SLAVE           0x0
 #define CONFIG_SYS_I2C_SPEED           100000
 
+/* USB/EHCI configuration */
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_EHCI_MARVELL
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
+
 /* SPI NOR flash default params, used by sf commands */
 #define CONFIG_SF_DEFAULT_SPEED                1000000
 #define CONFIG_SF_DEFAULT_MODE         SPI_MODE_3
 #define CONFIG_DOS_PARTITION
 #endif /* CONFIG_CMD_IDE */
 
+/* PCIe support */
+#define CONFIG_PCI
+#define CONFIG_PCI_MVEBU
+#define CONFIG_PCI_PNP
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_E1000   /* enable Intel E1000 support for testing */
+
 /*
  * mv-common.h should be defined after CMD configs since it used them
  * to enable certain macros
 #define CONFIG_SPL_SPI_BUS             0
 #define CONFIG_SPL_SPI_CS              0
 #define CONFIG_SYS_SPI_U_BOOT_OFFS     0x20000
+#define CONFIG_SYS_U_BOOT_OFFS         CONFIG_SYS_SPI_U_BOOT_OFFS
 
 /* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */
 #define CONFIG_SYS_MVEBU_DDR_AXP
index 0fb117f9d3651a59af64c74366cfa94502566625..3530a2621389c9df30ed8aecffbc6b07dcfdc764 100644 (file)
 #define CONFIG_SYS_GENERIC_BOARD
 #define CONFIG_DISPLAY_BOARDINFO_LATE
 
-#define        CONFIG_SYS_TEXT_BASE    0x04000000
+/*
+ * TEXT_BASE needs to be below 16MiB, since this area is scrubbed
+ * for DDR ECC byte filling in the SPL before loading the main
+ * U-Boot into it.
+ */
+#define        CONFIG_SYS_TEXT_BASE    0x00800000
 #define CONFIG_SYS_TCLK                250000000       /* 250MHz */
 
 /*