[ARM] add Marvell 78xx0 ARM SoC support
authorStanislav Samsonov <samsonov@marvell.com>
Sun, 22 Jun 2008 20:45:10 +0000 (22:45 +0200)
committerLennert Buytenhek <buytenh@marvell.com>
Sun, 22 Jun 2008 20:45:10 +0000 (22:45 +0200)
The Marvell Discovery Duo (MV78xx0) is a family of ARM SoCs featuring
(depending on the model) one or two Feroceon CPU cores with 512K of L2
cache and VFP coprocessors running at (depending on the model) between
800 MHz and 1.2 GHz, and features a DDR2 controller, two PCIe
interfaces that can each run either in x4 or quad x1 mode, three USB
2.0 interfaces, two 3Gb/s SATA II interfaces, a SPI interface, two
TWSI interfaces, a crypto accelerator, IDMA/XOR engines, a SPI
interface, four UARTs, and depending on the model, two or four gigabit
ethernet interfaces.

This patch adds basic support for the platform, and allows booting
on the MV78x00 development board, with functional UARTs, SATA, PCIe,
GigE and USB ports.

Signed-off-by: Stanislav Samsonov <samsonov@marvell.com>
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
24 files changed:
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/mach-mv78xx0/Kconfig [new file with mode: 0644]
arch/arm/mach-mv78xx0/Makefile [new file with mode: 0644]
arch/arm/mach-mv78xx0/Makefile.boot [new file with mode: 0644]
arch/arm/mach-mv78xx0/addr-map.c [new file with mode: 0644]
arch/arm/mach-mv78xx0/common.c [new file with mode: 0644]
arch/arm/mach-mv78xx0/common.h [new file with mode: 0644]
arch/arm/mach-mv78xx0/db78x00-bp-setup.c [new file with mode: 0644]
arch/arm/mach-mv78xx0/irq.c [new file with mode: 0644]
arch/arm/mach-mv78xx0/pcie.c [new file with mode: 0644]
arch/arm/mm/Kconfig
include/asm-arm/arch-mv78xx0/debug-macro.S [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/dma.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/entry-macro.S [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/hardware.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/io.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/irqs.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/memory.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/mv78xx0.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/system.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/timex.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/uncompress.h [new file with mode: 0644]
include/asm-arm/arch-mv78xx0/vmalloc.h [new file with mode: 0644]

index 3535cae..5bf60d5 100644 (file)
@@ -388,6 +388,16 @@ config ARCH_LOKI
        help
          Support for the Marvell Loki (88RC8480) SoC.
 
+config ARCH_MV78XX0
+       bool "Marvell MV78xx0"
+       select PCI
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+       select PLAT_ORION
+       help
+         Support for the following Marvell MV78xx0 series SoCs:
+         MV781x0, MV782x0.
+
 config ARCH_MXC
        bool "Freescale MXC/iMX-based"
        select ARCH_MTD_XIP
@@ -528,6 +538,8 @@ source "arch/arm/mach-ixp23xx/Kconfig"
 
 source "arch/arm/mach-loki/Kconfig"
 
+source "arch/arm/mach-mv78xx0/Kconfig"
+
 source "arch/arm/mach-pxa/Kconfig"
 
 source "arch/arm/mach-sa1100/Kconfig"
index 1459b38..b53237b 100644 (file)
@@ -142,6 +142,7 @@ endif
  machine-$(CONFIG_ARCH_ORION5X)           := orion5x
  machine-$(CONFIG_ARCH_MSM7X00A)   := msm
  machine-$(CONFIG_ARCH_LOKI)       := loki
+ machine-$(CONFIG_ARCH_MV78XX0)    := mv78xx0
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig
new file mode 100644 (file)
index 0000000..d83cb86
--- /dev/null
@@ -0,0 +1,13 @@
+if ARCH_MV78XX0
+
+menu "Marvell MV78xx0 Implementations"
+
+config MACH_DB78X00_BP
+       bool "Marvell DB-78x00-BP Development Board"
+       help
+         Say 'Y' here if you want your kernel to support the
+         Marvell DB-78x00-BP Development Board.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-mv78xx0/Makefile b/arch/arm/mach-mv78xx0/Makefile
new file mode 100644 (file)
index 0000000..ec16c05
--- /dev/null
@@ -0,0 +1,2 @@
+obj-y                          += common.o addr-map.o irq.o pcie.o
+obj-$(CONFIG_MACH_DB78X00_BP)  += db78x00-bp-setup.o
diff --git a/arch/arm/mach-mv78xx0/Makefile.boot b/arch/arm/mach-mv78xx0/Makefile.boot
new file mode 100644 (file)
index 0000000..67039c3
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c
new file mode 100644 (file)
index 0000000..4004b67
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * arch/arm/mach-mv78xx0/addr-map.c
+ *
+ * Address map functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <asm/io.h>
+#include "common.h"
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR             0
+#define TARGET_DEV_BUS         1
+#define TARGET_PCIE0           4
+#define TARGET_PCIE1           8
+#define TARGET_PCIE(i)         ((i) ? TARGET_PCIE1 : TARGET_PCIE0)
+#define ATTR_DEV_SPI_ROM       0x1f
+#define ATTR_DEV_BOOT          0x2f
+#define ATTR_DEV_CS3           0x37
+#define ATTR_DEV_CS2           0x3b
+#define ATTR_DEV_CS1           0x3d
+#define ATTR_DEV_CS0           0x3e
+#define ATTR_PCIE_IO(l)                (0xf0 & ~(0x10 << (l)))
+#define ATTR_PCIE_MEM(l)       (0xf8 & ~(0x10 << (l)))
+
+/*
+ * Helpers to get DDR bank info
+ */
+#define DDR_BASE_CS_OFF(n)     (0x0000 + ((n) << 3))
+#define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN0_OFF(n)            (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
+#define WIN8_OFF(n)            (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
+#define WIN_CTRL_OFF           0x0000
+#define WIN_BASE_OFF           0x0004
+#define WIN_REMAP_LO_OFF       0x0008
+#define WIN_REMAP_HI_OFF       0x000c
+
+
+struct mbus_dram_target_info mv78xx0_mbus_dram_info;
+
+static void __init __iomem *win_cfg_base(int win)
+{
+       /*
+        * Find the control register base address for this window.
+        *
+        * BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's)
+        * MBUS bridge depending on which CPU core we're running on,
+        * so we don't need to take that into account here.
+        */
+
+       return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win));
+}
+
+static int __init cpu_win_can_remap(int win)
+{
+       if (win < 8)
+               return 1;
+
+       return 0;
+}
+
+static void __init setup_cpu_win(int win, u32 base, u32 size,
+                                u8 target, u8 attr, int remap)
+{
+       void __iomem *addr = win_cfg_base(win);
+       u32 ctrl;
+
+       base &= 0xffff0000;
+       ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
+
+       writel(base, addr + WIN_BASE_OFF);
+       writel(ctrl, addr + WIN_CTRL_OFF);
+       if (cpu_win_can_remap(win)) {
+               if (remap < 0)
+                       remap = base;
+
+               writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF);
+               writel(0, addr + WIN_REMAP_HI_OFF);
+       }
+}
+
+void __init mv78xx0_setup_cpu_mbus(void)
+{
+       void __iomem *addr;
+       int i;
+       int cs;
+
+       /*
+        * First, disable and clear windows.
+        */
+       for (i = 0; i < 14; i++) {
+               addr = win_cfg_base(i);
+
+               writel(0, addr + WIN_BASE_OFF);
+               writel(0, addr + WIN_CTRL_OFF);
+               if (cpu_win_can_remap(i)) {
+                       writel(0, addr + WIN_REMAP_LO_OFF);
+                       writel(0, addr + WIN_REMAP_HI_OFF);
+               }
+       }
+
+       /*
+        * Setup MBUS dram target info.
+        */
+       mv78xx0_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+       if (mv78xx0_core_index() == 0)
+               addr = (void __iomem *)DDR_WINDOW_CPU0_BASE;
+       else
+               addr = (void __iomem *)DDR_WINDOW_CPU1_BASE;
+
+       for (i = 0, cs = 0; i < 4; i++) {
+               u32 base = readl(addr + DDR_BASE_CS_OFF(i));
+               u32 size = readl(addr + DDR_SIZE_CS_OFF(i));
+
+               /*
+                * Chip select enabled?
+                */
+               if (size & 1) {
+                       struct mbus_dram_window *w;
+
+                       w = &mv78xx0_mbus_dram_info.cs[cs++];
+                       w->cs_index = i;
+                       w->mbus_attr = 0xf & ~(1 << i);
+                       w->base = base & 0xffff0000;
+                       w->size = (size | 0x0000ffff) + 1;
+               }
+       }
+       mv78xx0_mbus_dram_info.num_cs = cs;
+}
+
+void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
+                                     int maj, int min)
+{
+       setup_cpu_win(window, base, size, TARGET_PCIE(maj),
+                     ATTR_PCIE_IO(min), -1);
+}
+
+void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
+                                      int maj, int min)
+{
+       setup_cpu_win(window, base, size, TARGET_PCIE(maj),
+                     ATTR_PCIE_MEM(min), -1);
+}
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
new file mode 100644 (file)
index 0000000..d27b83b
--- /dev/null
@@ -0,0 +1,754 @@
+/*
+ * arch/arm/mach-mv78xx0/common.c
+ *
+ * Core functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mbus.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/arch/mv78xx0.h>
+#include <asm/plat-orion/cache-feroceon-l2.h>
+#include <asm/plat-orion/ehci-orion.h>
+#include <asm/plat-orion/orion_nand.h>
+#include <asm/plat-orion/time.h>
+#include "common.h"
+
+
+/*****************************************************************************
+ * Common bits
+ ****************************************************************************/
+int mv78xx0_core_index(void)
+{
+       u32 extra;
+
+       /*
+        * Read Extra Features register.
+        */
+       __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));
+
+       return !!(extra & 0x00004000);
+}
+
+static int get_hclk(void)
+{
+       int hclk;
+
+       /*
+        * HCLK tick rate is configured by DEV_D[7:5] pins.
+        */
+       switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
+       case 0:
+               hclk = 166666667;
+               break;
+       case 1:
+               hclk = 200000000;
+               break;
+       case 2:
+               hclk = 266666667;
+               break;
+       case 3:
+               hclk = 333333333;
+               break;
+       case 4:
+               hclk = 400000000;
+               break;
+       default:
+               panic("unknown HCLK PLL setting: %.8x\n",
+                       readl(SAMPLE_AT_RESET_LOW));
+       }
+
+       return hclk;
+}
+
+static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
+{
+       u32 cfg;
+
+       /*
+        * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
+        * PCLK/L2CLK by bits [19:14].
+        */
+       if (core_index == 0) {
+               cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
+       } else {
+               cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
+       }
+
+       /*
+        * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
+        * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
+        */
+       *pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;
+
+       /*
+        * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
+        * ratio (1, 2, 3).
+        */
+       *l2clk = *pclk / (((cfg >> 4) & 3) + 1);
+}
+
+static int get_tclk(void)
+{
+       int tclk;
+
+       /*
+        * TCLK tick rate is configured by DEV_A[2:0] strap pins.
+        */
+       switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
+       case 1:
+               tclk = 166666667;
+               break;
+       case 3:
+               tclk = 200000000;
+               break;
+       default:
+               panic("unknown TCLK PLL setting: %.8x\n",
+                       readl(SAMPLE_AT_RESET_HIGH));
+       }
+
+       return tclk;
+}
+
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc mv78xx0_io_desc[] __initdata = {
+       {
+               .virtual        = MV78XX0_CORE_REGS_VIRT_BASE,
+               .pfn            = 0,
+               .length         = MV78XX0_CORE_REGS_SIZE,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = MV78XX0_PCIE_IO_VIRT_BASE(0),
+               .pfn            = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
+               .length         = MV78XX0_PCIE_IO_SIZE * 8,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = MV78XX0_REGS_VIRT_BASE,
+               .pfn            = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
+               .length         = MV78XX0_REGS_SIZE,
+               .type           = MT_DEVICE,
+       },
+};
+
+void __init mv78xx0_map_io(void)
+{
+       unsigned long phys;
+
+       /*
+        * Map the right set of per-core registers depending on
+        * which core we are running on.
+        */
+       if (mv78xx0_core_index() == 0) {
+               phys = MV78XX0_CORE0_REGS_PHYS_BASE;
+       } else {
+               phys = MV78XX0_CORE1_REGS_PHYS_BASE;
+       }
+       mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);
+
+       iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
+}
+
+
+/*****************************************************************************
+ * EHCI
+ ****************************************************************************/
+static struct orion_ehci_data mv78xx0_ehci_data = {
+       .dram           = &mv78xx0_mbus_dram_info,
+};
+
+static u64 ehci_dmamask = 0xffffffffUL;
+
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+static struct resource mv78xx0_ehci0_resources[] = {
+       {
+               .start  = USB0_PHYS_BASE,
+               .end    = USB0_PHYS_BASE + 0x0fff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_MV78XX0_USB_0,
+               .end    = IRQ_MV78XX0_USB_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_ehci0 = {
+       .name           = "orion-ehci",
+       .id             = 0,
+       .dev            = {
+               .dma_mask               = &ehci_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &mv78xx0_ehci_data,
+       },
+       .resource       = mv78xx0_ehci0_resources,
+       .num_resources  = ARRAY_SIZE(mv78xx0_ehci0_resources),
+};
+
+void __init mv78xx0_ehci0_init(void)
+{
+       platform_device_register(&mv78xx0_ehci0);
+}
+
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+static struct resource mv78xx0_ehci1_resources[] = {
+       {
+               .start  = USB1_PHYS_BASE,
+               .end    = USB1_PHYS_BASE + 0x0fff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_MV78XX0_USB_1,
+               .end    = IRQ_MV78XX0_USB_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_ehci1 = {
+       .name           = "orion-ehci",
+       .id             = 1,
+       .dev            = {
+               .dma_mask               = &ehci_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &mv78xx0_ehci_data,
+       },
+       .resource       = mv78xx0_ehci1_resources,
+       .num_resources  = ARRAY_SIZE(mv78xx0_ehci1_resources),
+};
+
+void __init mv78xx0_ehci1_init(void)
+{
+       platform_device_register(&mv78xx0_ehci1);
+}
+
+
+/*****************************************************************************
+ * EHCI2
+ ****************************************************************************/
+static struct resource mv78xx0_ehci2_resources[] = {
+       {
+               .start  = USB2_PHYS_BASE,
+               .end    = USB2_PHYS_BASE + 0x0fff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_MV78XX0_USB_2,
+               .end    = IRQ_MV78XX0_USB_2,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_ehci2 = {
+       .name           = "orion-ehci",
+       .id             = 2,
+       .dev            = {
+               .dma_mask               = &ehci_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &mv78xx0_ehci_data,
+       },
+       .resource       = mv78xx0_ehci2_resources,
+       .num_resources  = ARRAY_SIZE(mv78xx0_ehci2_resources),
+};
+
+void __init mv78xx0_ehci2_init(void)
+{
+       platform_device_register(&mv78xx0_ehci2);
+}
+
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data mv78xx0_ge00_shared_data = {
+       .t_clk          = 0,
+       .dram           = &mv78xx0_mbus_dram_info,
+};
+
+static struct resource mv78xx0_ge00_shared_resources[] = {
+       {
+               .name   = "ge00 base",
+               .start  = GE00_PHYS_BASE + 0x2000,
+               .end    = GE00_PHYS_BASE + 0x3fff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device mv78xx0_ge00_shared = {
+       .name           = MV643XX_ETH_SHARED_NAME,
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &mv78xx0_ge00_shared_data,
+       },
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge00_shared_resources,
+};
+
+static struct resource mv78xx0_ge00_resources[] = {
+       {
+               .name   = "ge00 irq",
+               .start  = IRQ_MV78XX0_GE00_SUM,
+               .end    = IRQ_MV78XX0_GE00_SUM,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_ge00 = {
+       .name           = MV643XX_ETH_NAME,
+       .id             = 0,
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge00_resources,
+};
+
+void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
+{
+       eth_data->shared = &mv78xx0_ge00_shared;
+       mv78xx0_ge00.dev.platform_data = eth_data;
+
+       platform_device_register(&mv78xx0_ge00_shared);
+       platform_device_register(&mv78xx0_ge00);
+}
+
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
+       .t_clk          = 0,
+       .dram           = &mv78xx0_mbus_dram_info,
+};
+
+static struct resource mv78xx0_ge01_shared_resources[] = {
+       {
+               .name   = "ge01 base",
+               .start  = GE01_PHYS_BASE + 0x2000,
+               .end    = GE01_PHYS_BASE + 0x3fff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device mv78xx0_ge01_shared = {
+       .name           = MV643XX_ETH_SHARED_NAME,
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &mv78xx0_ge01_shared_data,
+       },
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge01_shared_resources,
+};
+
+static struct resource mv78xx0_ge01_resources[] = {
+       {
+               .name   = "ge01 irq",
+               .start  = IRQ_MV78XX0_GE01_SUM,
+               .end    = IRQ_MV78XX0_GE01_SUM,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_ge01 = {
+       .name           = MV643XX_ETH_NAME,
+       .id             = 1,
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge01_resources,
+};
+
+void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
+{
+       eth_data->shared = &mv78xx0_ge01_shared;
+       eth_data->shared_smi = &mv78xx0_ge00_shared;
+       mv78xx0_ge01.dev.platform_data = eth_data;
+
+       platform_device_register(&mv78xx0_ge01_shared);
+       platform_device_register(&mv78xx0_ge01);
+}
+
+
+/*****************************************************************************
+ * GE10
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
+       .t_clk          = 0,
+       .dram           = &mv78xx0_mbus_dram_info,
+};
+
+static struct resource mv78xx0_ge10_shared_resources[] = {
+       {
+               .name   = "ge10 base",
+               .start  = GE10_PHYS_BASE + 0x2000,
+               .end    = GE10_PHYS_BASE + 0x3fff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device mv78xx0_ge10_shared = {
+       .name           = MV643XX_ETH_SHARED_NAME,
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &mv78xx0_ge10_shared_data,
+       },
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge10_shared_resources,
+};
+
+static struct resource mv78xx0_ge10_resources[] = {
+       {
+               .name   = "ge10 irq",
+               .start  = IRQ_MV78XX0_GE10_SUM,
+               .end    = IRQ_MV78XX0_GE10_SUM,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_ge10 = {
+       .name           = MV643XX_ETH_NAME,
+       .id             = 2,
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge10_resources,
+};
+
+void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
+{
+       eth_data->shared = &mv78xx0_ge10_shared;
+       eth_data->shared_smi = &mv78xx0_ge00_shared;
+       mv78xx0_ge10.dev.platform_data = eth_data;
+
+       platform_device_register(&mv78xx0_ge10_shared);
+       platform_device_register(&mv78xx0_ge10);
+}
+
+
+/*****************************************************************************
+ * GE11
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
+       .t_clk          = 0,
+       .dram           = &mv78xx0_mbus_dram_info,
+};
+
+static struct resource mv78xx0_ge11_shared_resources[] = {
+       {
+               .name   = "ge11 base",
+               .start  = GE11_PHYS_BASE + 0x2000,
+               .end    = GE11_PHYS_BASE + 0x3fff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device mv78xx0_ge11_shared = {
+       .name           = MV643XX_ETH_SHARED_NAME,
+       .id             = 3,
+       .dev            = {
+               .platform_data  = &mv78xx0_ge11_shared_data,
+       },
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge11_shared_resources,
+};
+
+static struct resource mv78xx0_ge11_resources[] = {
+       {
+               .name   = "ge11 irq",
+               .start  = IRQ_MV78XX0_GE11_SUM,
+               .end    = IRQ_MV78XX0_GE11_SUM,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_ge11 = {
+       .name           = MV643XX_ETH_NAME,
+       .id             = 3,
+       .num_resources  = 1,
+       .resource       = mv78xx0_ge11_resources,
+};
+
+void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
+{
+       eth_data->shared = &mv78xx0_ge11_shared;
+       eth_data->shared_smi = &mv78xx0_ge00_shared;
+       mv78xx0_ge11.dev.platform_data = eth_data;
+
+       platform_device_register(&mv78xx0_ge11_shared);
+       platform_device_register(&mv78xx0_ge11);
+}
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct resource mv78xx0_sata_resources[] = {
+       {
+               .name   = "sata base",
+               .start  = SATA_PHYS_BASE,
+               .end    = SATA_PHYS_BASE + 0x5000 - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "sata irq",
+               .start  = IRQ_MV78XX0_SATA,
+               .end    = IRQ_MV78XX0_SATA,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_sata = {
+       .name           = "sata_mv",
+       .id             = 0,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(mv78xx0_sata_resources),
+       .resource       = mv78xx0_sata_resources,
+};
+
+void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
+{
+       sata_data->dram = &mv78xx0_mbus_dram_info;
+       mv78xx0_sata.dev.platform_data = sata_data;
+       platform_device_register(&mv78xx0_sata);
+}
+
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+static struct plat_serial8250_port mv78xx0_uart0_data[] = {
+       {
+               .mapbase        = UART0_PHYS_BASE,
+               .membase        = (char *)UART0_VIRT_BASE,
+               .irq            = IRQ_MV78XX0_UART_0,
+               .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = 0,
+       }, {
+       },
+};
+
+static struct resource mv78xx0_uart0_resources[] = {
+       {
+               .start          = UART0_PHYS_BASE,
+               .end            = UART0_PHYS_BASE + 0xff,
+               .flags          = IORESOURCE_MEM,
+       }, {
+               .start          = IRQ_MV78XX0_UART_0,
+               .end            = IRQ_MV78XX0_UART_0,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_uart0 = {
+       .name                   = "serial8250",
+       .id                     = 0,
+       .dev                    = {
+               .platform_data  = mv78xx0_uart0_data,
+       },
+       .resource               = mv78xx0_uart0_resources,
+       .num_resources          = ARRAY_SIZE(mv78xx0_uart0_resources),
+};
+
+void __init mv78xx0_uart0_init(void)
+{
+       platform_device_register(&mv78xx0_uart0);
+}
+
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+static struct plat_serial8250_port mv78xx0_uart1_data[] = {
+       {
+               .mapbase        = UART1_PHYS_BASE,
+               .membase        = (char *)UART1_VIRT_BASE,
+               .irq            = IRQ_MV78XX0_UART_1,
+               .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = 0,
+       }, {
+       },
+};
+
+static struct resource mv78xx0_uart1_resources[] = {
+       {
+               .start          = UART1_PHYS_BASE,
+               .end            = UART1_PHYS_BASE + 0xff,
+               .flags          = IORESOURCE_MEM,
+       }, {
+               .start          = IRQ_MV78XX0_UART_1,
+               .end            = IRQ_MV78XX0_UART_1,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_uart1 = {
+       .name                   = "serial8250",
+       .id                     = 1,
+       .dev                    = {
+               .platform_data  = mv78xx0_uart1_data,
+       },
+       .resource               = mv78xx0_uart1_resources,
+       .num_resources          = ARRAY_SIZE(mv78xx0_uart1_resources),
+};
+
+void __init mv78xx0_uart1_init(void)
+{
+       platform_device_register(&mv78xx0_uart1);
+}
+
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+static struct plat_serial8250_port mv78xx0_uart2_data[] = {
+       {
+               .mapbase        = UART2_PHYS_BASE,
+               .membase        = (char *)UART2_VIRT_BASE,
+               .irq            = IRQ_MV78XX0_UART_2,
+               .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = 0,
+       }, {
+       },
+};
+
+static struct resource mv78xx0_uart2_resources[] = {
+       {
+               .start          = UART2_PHYS_BASE,
+               .end            = UART2_PHYS_BASE + 0xff,
+               .flags          = IORESOURCE_MEM,
+       }, {
+               .start          = IRQ_MV78XX0_UART_2,
+               .end            = IRQ_MV78XX0_UART_2,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_uart2 = {
+       .name                   = "serial8250",
+       .id                     = 2,
+       .dev                    = {
+               .platform_data  = mv78xx0_uart2_data,
+       },
+       .resource               = mv78xx0_uart2_resources,
+       .num_resources          = ARRAY_SIZE(mv78xx0_uart2_resources),
+};
+
+void __init mv78xx0_uart2_init(void)
+{
+       platform_device_register(&mv78xx0_uart2);
+}
+
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+static struct plat_serial8250_port mv78xx0_uart3_data[] = {
+       {
+               .mapbase        = UART3_PHYS_BASE,
+               .membase        = (char *)UART3_VIRT_BASE,
+               .irq            = IRQ_MV78XX0_UART_3,
+               .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = 0,
+       }, {
+       },
+};
+
+static struct resource mv78xx0_uart3_resources[] = {
+       {
+               .start          = UART3_PHYS_BASE,
+               .end            = UART3_PHYS_BASE + 0xff,
+               .flags          = IORESOURCE_MEM,
+       }, {
+               .start          = IRQ_MV78XX0_UART_3,
+               .end            = IRQ_MV78XX0_UART_3,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mv78xx0_uart3 = {
+       .name                   = "serial8250",
+       .id                     = 3,
+       .dev                    = {
+               .platform_data  = mv78xx0_uart3_data,
+       },
+       .resource               = mv78xx0_uart3_resources,
+       .num_resources          = ARRAY_SIZE(mv78xx0_uart3_resources),
+};
+
+void __init mv78xx0_uart3_init(void)
+{
+       platform_device_register(&mv78xx0_uart3);
+}
+
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+static void mv78xx0_timer_init(void)
+{
+       orion_time_init(IRQ_MV78XX0_TIMER_1, get_tclk());
+}
+
+struct sys_timer mv78xx0_timer = {
+       .init = mv78xx0_timer_init,
+};
+
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+static int __init is_l2_writethrough(void)
+{
+       return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
+}
+
+void __init mv78xx0_init(void)
+{
+       int core_index;
+       int hclk;
+       int pclk;
+       int l2clk;
+       int tclk;
+
+       core_index = mv78xx0_core_index();
+       hclk = get_hclk();
+       get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
+       tclk = get_tclk();
+
+       printk(KERN_INFO "MV78xx0 core #%d, ", core_index);
+       printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
+       printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
+       printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
+       printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
+
+       mv78xx0_setup_cpu_mbus();
+
+#ifdef CONFIG_CACHE_FEROCEON_L2
+       feroceon_l2_init(is_l2_writethrough());
+#endif
+
+       mv78xx0_ge00_shared_data.t_clk = tclk;
+       mv78xx0_ge01_shared_data.t_clk = tclk;
+       mv78xx0_ge10_shared_data.t_clk = tclk;
+       mv78xx0_ge11_shared_data.t_clk = tclk;
+       mv78xx0_uart0_data[0].uartclk = tclk;
+       mv78xx0_uart1_data[0].uartclk = tclk;
+       mv78xx0_uart2_data[0].uartclk = tclk;
+       mv78xx0_uart3_data[0].uartclk = tclk;
+}
diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h
new file mode 100644 (file)
index 0000000..78af5de
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-mv78xx0/common.h
+ *
+ * Core functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_MV78XX0_COMMON_H
+#define __ARCH_MV78XX0_COMMON_H
+
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+/*
+ * Basic MV78xx0 init functions used early by machine-setup.
+ */
+int mv78xx0_core_index(void);
+void mv78xx0_map_io(void);
+void mv78xx0_init(void);
+void mv78xx0_init_irq(void);
+
+extern struct mbus_dram_target_info mv78xx0_mbus_dram_info;
+void mv78xx0_setup_cpu_mbus(void);
+void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
+                              int maj, int min);
+void mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
+                               int maj, int min);
+
+void mv78xx0_ehci0_init(void);
+void mv78xx0_ehci1_init(void);
+void mv78xx0_ehci2_init(void);
+void mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_pcie_init(int init_port0, int init_port1);
+void mv78xx0_sata_init(struct mv_sata_platform_data *sata_data);
+void mv78xx0_uart0_init(void);
+void mv78xx0_uart1_init(void);
+void mv78xx0_uart2_init(void);
+void mv78xx0_uart3_init(void);
+
+extern struct sys_timer mv78xx0_timer;
+
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
new file mode 100644 (file)
index 0000000..0c93d19
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-mv78xx0/db78x00-bp-setup.c
+ *
+ * Marvell DB-78x00-BP Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <asm/arch/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data db78x00_ge00_data = {
+       .phy_addr       = 8,
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge01_data = {
+       .phy_addr       = 9,
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge10_data = {
+       .phy_addr       = -1,
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge11_data = {
+       .phy_addr       = -1,
+};
+
+static struct mv_sata_platform_data db78x00_sata_data = {
+       .n_ports        = 2,
+};
+
+static void __init db78x00_init(void)
+{
+       /*
+        * Basic MV78xx0 setup. Needs to be called early.
+        */
+       mv78xx0_init();
+
+       /*
+        * Partition on-chip peripherals between the two CPU cores.
+        */
+       if (mv78xx0_core_index() == 0) {
+               mv78xx0_ehci0_init();
+               mv78xx0_ehci1_init();
+               mv78xx0_ehci2_init();
+               mv78xx0_ge00_init(&db78x00_ge00_data);
+               mv78xx0_ge01_init(&db78x00_ge01_data);
+               mv78xx0_ge10_init(&db78x00_ge10_data);
+               mv78xx0_ge11_init(&db78x00_ge11_data);
+               mv78xx0_sata_init(&db78x00_sata_data);
+               mv78xx0_uart0_init();
+               mv78xx0_uart2_init();
+       } else {
+               mv78xx0_uart1_init();
+               mv78xx0_uart3_init();
+       }
+}
+
+static int __init db78x00_pci_init(void)
+{
+       if (machine_is_db78x00_bp()) {
+               /*
+                * Assign the x16 PCIe slot on the board to CPU core
+                * #0, and let CPU core #1 have the four x1 slots.
+                */
+               if (mv78xx0_core_index() == 0)
+                       mv78xx0_pcie_init(0, 1);
+               else
+                       mv78xx0_pcie_init(1, 0);
+       }
+
+       return 0;
+}
+subsys_initcall(db78x00_pci_init);
+
+MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board")
+       /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+       .phys_io        = MV78XX0_REGS_PHYS_BASE,
+       .io_pg_offst    = ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .init_machine   = db78x00_init,
+       .map_io         = mv78xx0_map_io,
+       .init_irq       = mv78xx0_init_irq,
+       .timer          = &mv78xx0_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
new file mode 100644 (file)
index 0000000..60f4ee4
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-mv78xx0/irq.c
+ *
+ * MV78xx0 IRQ handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/arch/mv78xx0.h>
+#include <asm/plat-orion/irq.h>
+#include "common.h"
+
+void __init mv78xx0_init_irq(void)
+{
+       orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
+       orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+}
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
new file mode 100644 (file)
index 0000000..b78e144
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * arch/arm/mach-mv78xx0/pcie.c
+ *
+ * PCIe functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mbus.h>
+#include <asm/mach/pci.h>
+#include <asm/plat-orion/pcie.h>
+#include "common.h"
+
+struct pcie_port {
+       u8                      maj;
+       u8                      min;
+       u8                      root_bus_nr;
+       void __iomem            *base;
+       spinlock_t              conf_lock;
+       char                    io_space_name[16];
+       char                    mem_space_name[16];
+       struct resource         res[2];
+};
+
+static struct pcie_port pcie_port[8];
+static int num_pcie_ports;
+static struct resource pcie_io_space;
+static struct resource pcie_mem_space;
+
+
+static void __init mv78xx0_pcie_preinit(void)
+{
+       int i;
+       u32 size_each;
+       u32 start;
+       int win;
+
+       pcie_io_space.name = "PCIe I/O Space";
+       pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
+       pcie_io_space.end =
+               MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1;
+       pcie_io_space.flags = IORESOURCE_IO;
+       if (request_resource(&iomem_resource, &pcie_io_space))
+               panic("can't allocate PCIe I/O space");
+
+       pcie_mem_space.name = "PCIe MEM Space";
+       pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE;
+       pcie_mem_space.end =
+               MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1;
+       pcie_mem_space.flags = IORESOURCE_MEM;
+       if (request_resource(&iomem_resource, &pcie_mem_space))
+               panic("can't allocate PCIe MEM space");
+
+       for (i = 0; i < num_pcie_ports; i++) {
+               struct pcie_port *pp = pcie_port + i;
+
+               snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+                       "PCIe %d.%d I/O", pp->maj, pp->min);
+               pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+               pp->res[0].name = pp->io_space_name;
+               pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i);
+               pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1;
+               pp->res[0].flags = IORESOURCE_IO;
+
+               snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+                       "PCIe %d.%d MEM", pp->maj, pp->min);
+               pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+               pp->res[1].name = pp->mem_space_name;
+               pp->res[1].flags = IORESOURCE_MEM;
+       }
+
+       switch (num_pcie_ports) {
+       case 0:
+               size_each = 0;
+               break;
+
+       case 1:
+               size_each = 0x30000000;
+               break;
+
+       case 2 ... 3:
+               size_each = 0x10000000;
+               break;
+
+       case 4 ... 6:
+               size_each = 0x08000000;
+               break;
+
+       case 7:
+               size_each = 0x04000000;
+               break;
+
+       default:
+               panic("invalid number of PCIe ports");
+       }
+
+       start = MV78XX0_PCIE_MEM_PHYS_BASE;
+       for (i = 0; i < num_pcie_ports; i++) {
+               struct pcie_port *pp = pcie_port + i;
+
+               pp->res[1].start = start;
+               pp->res[1].end = start + size_each - 1;
+               start += size_each;
+       }
+
+       for (i = 0; i < num_pcie_ports; i++) {
+               struct pcie_port *pp = pcie_port + i;
+
+               if (request_resource(&pcie_io_space, &pp->res[0]))
+                       panic("can't allocate PCIe I/O sub-space");
+
+               if (request_resource(&pcie_mem_space, &pp->res[1]))
+                       panic("can't allocate PCIe MEM sub-space");
+       }
+
+       win = 0;
+       for (i = 0; i < num_pcie_ports; i++) {
+               struct pcie_port *pp = pcie_port + i;
+
+               mv78xx0_setup_pcie_io_win(win++, pp->res[0].start,
+                       pp->res[0].end - pp->res[0].start + 1,
+                       pp->maj, pp->min);
+
+               mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start,
+                       pp->res[1].end - pp->res[1].start + 1,
+                       pp->maj, pp->min);
+       }
+}
+
+static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+       struct pcie_port *pp;
+
+       if (nr >= num_pcie_ports)
+               return 0;
+
+       pp = &pcie_port[nr];
+       pp->root_bus_nr = sys->busnr;
+
+       /*
+        * Generic PCIe unit setup.
+        */
+       orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
+       orion_pcie_setup(pp->base, &mv78xx0_mbus_dram_info);
+
+       sys->resource[0] = &pp->res[0];
+       sys->resource[1] = &pp->res[1];
+       sys->resource[2] = NULL;
+
+       return 1;
+}
+
+static struct pcie_port *bus_to_port(int bus)
+{
+       int i;
+
+       for (i = num_pcie_ports - 1; i >= 0; i--) {
+               int rbus = pcie_port[i].root_bus_nr;
+               if (rbus != -1 && rbus <= bus)
+                       break;
+       }
+
+       return i >= 0 ? pcie_port + i : NULL;
+}
+
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
+{
+       /*
+        * Don't go out when trying to access nonexisting devices
+        * on the local bus.
+        */
+       if (bus == pp->root_bus_nr && dev > 1)
+               return 0;
+
+       return 1;
+}
+
+static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+                       int size, u32 *val)
+{
+       struct pcie_port *pp = bus_to_port(bus->number);
+       unsigned long flags;
+       int ret;
+
+       if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
+               *val = 0xffffffff;
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       }
+
+       spin_lock_irqsave(&pp->conf_lock, flags);
+       ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+       spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+       return ret;
+}
+
+static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+                       int where, int size, u32 val)
+{
+       struct pcie_port *pp = bus_to_port(bus->number);
+       unsigned long flags;
+       int ret;
+
+       if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       spin_lock_irqsave(&pp->conf_lock, flags);
+       ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+       spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+       return ret;
+}
+
+static struct pci_ops pcie_ops = {
+       .read = pcie_rd_conf,
+       .write = pcie_wr_conf,
+};
+
+static void __devinit rc_pci_fixup(struct pci_dev *dev)
+{
+       /*
+        * Prevent enumeration of root complex.
+        */
+       if (dev->bus->parent == NULL && dev->devfn == 0) {
+               int i;
+
+               for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+                       dev->resource[i].start = 0;
+                       dev->resource[i].end   = 0;
+                       dev->resource[i].flags = 0;
+               }
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
+
+static struct pci_bus __init *
+mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+       struct pci_bus *bus;
+
+       if (nr < num_pcie_ports) {
+               bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+       } else {
+               bus = NULL;
+               BUG();
+       }
+
+       return bus;
+}
+
+static int __init mv78xx0_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       struct pcie_port *pp = bus_to_port(dev->bus->number);
+
+       return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min;
+}
+
+static struct hw_pci mv78xx0_pci __initdata = {
+       .nr_controllers = 8,
+       .preinit        = mv78xx0_pcie_preinit,
+       .swizzle        = pci_std_swizzle,
+       .setup          = mv78xx0_pcie_setup,
+       .scan           = mv78xx0_pcie_scan_bus,
+       .map_irq        = mv78xx0_pcie_map_irq,
+};
+
+static void __init add_pcie_port(int maj, int min, unsigned long base)
+{
+       printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min);
+
+       if (orion_pcie_link_up((void __iomem *)base)) {
+               struct pcie_port *pp = &pcie_port[num_pcie_ports++];
+
+               printk("link up\n");
+
+               pp->maj = maj;
+               pp->min = min;
+               pp->root_bus_nr = -1;
+               pp->base = (void __iomem *)base;
+               spin_lock_init(&pp->conf_lock);
+               memset(pp->res, 0, sizeof(pp->res));
+       } else {
+               printk("link down, ignoring\n");
+       }
+}
+
+void __init mv78xx0_pcie_init(int init_port0, int init_port1)
+{
+       if (init_port0) {
+               add_pcie_port(0, 0, PCIE00_VIRT_BASE);
+               if (!orion_pcie_x4_mode((void __iomem *)PCIE00_VIRT_BASE)) {
+                       add_pcie_port(0, 1, PCIE01_VIRT_BASE);
+                       add_pcie_port(0, 2, PCIE02_VIRT_BASE);
+                       add_pcie_port(0, 3, PCIE03_VIRT_BASE);
+               }
+       }
+
+       if (init_port1) {
+               add_pcie_port(1, 0, PCIE10_VIRT_BASE);
+               if (!orion_pcie_x4_mode((void __iomem *)PCIE10_VIRT_BASE)) {
+                       add_pcie_port(1, 1, PCIE11_VIRT_BASE);
+                       add_pcie_port(1, 2, PCIE12_VIRT_BASE);
+                       add_pcie_port(1, 3, PCIE13_VIRT_BASE);
+               }
+       }
+
+       pci_common_init(&mv78xx0_pci);
+}
index a7a6efe..236603b 100644 (file)
@@ -365,7 +365,7 @@ config CPU_XSC3
 # Feroceon
 config CPU_FEROCEON
        bool
-       depends on ARCH_ORION5X || ARCH_LOKI || ARCH_KIRKWOOD
+       depends on ARCH_ORION5X || ARCH_LOKI || ARCH_KIRKWOOD || ARCH_MV78XX0
        default y
        select CPU_32v5
        select CPU_ABRT_EV5T
@@ -716,7 +716,7 @@ config OUTER_CACHE
 
 config CACHE_FEROCEON_L2
        bool "Enable the Feroceon L2 cache controller"
-       depends on ARCH_KIRKWOOD
+       depends on ARCH_KIRKWOOD || ARCH_MV78XX0
        default y
        select OUTER_CACHE
        help
diff --git a/include/asm-arm/arch-mv78xx0/debug-macro.S b/include/asm-arm/arch-mv78xx0/debug-macro.S
new file mode 100644 (file)
index 0000000..d0595bd
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * include/asm-arm/arch-mv78xx0/debug-macro.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <asm/arch/mv78xx0.h>
+
+       .macro  addruart,rx
+       mrc     p15, 0, \rx, c1, c0
+       tst     \rx, #1                                 @ MMU enabled?
+       ldreq   \rx, =MV78XX0_REGS_PHYS_BASE
+       ldrne   \rx, =MV78XX0_REGS_VIRT_BASE
+       orr     \rx, \rx, #0x00012000
+       .endm
+
+#define UART_SHIFT     2
+#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-mv78xx0/dma.h b/include/asm-arm/arch-mv78xx0/dma.h
new file mode 100644 (file)
index 0000000..40a8c17
--- /dev/null
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/asm-arm/arch-mv78xx0/entry-macro.S b/include/asm-arm/arch-mv78xx0/entry-macro.S
new file mode 100644 (file)
index 0000000..e9a606b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * include/asm-arm/arch-mv78xx0/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Marvell MV78xx0 platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/arch/mv78xx0.h>
+
+       .macro  disable_fiq
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
+       .macro  get_irqnr_preamble, base, tmp
+       ldr     \base, =IRQ_VIRT_BASE
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       @ check low interrupts
+       ldr     \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
+       ldr     \tmp, [\base, #IRQ_MASK_LOW_OFF]
+       mov     \irqnr, #31
+       ands    \irqstat, \irqstat, \tmp
+
+       @ if no low interrupts set, check high interrupts
+       ldreq   \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
+       ldreq   \tmp, [\base, #IRQ_MASK_HIGH_OFF]
+       moveq   \irqnr, #63
+       andeqs  \irqstat, \irqstat, \tmp
+
+       @ find first active interrupt source
+       clzne   \irqstat, \irqstat
+       subne   \irqnr, \irqnr, \irqstat
+       .endm
diff --git a/include/asm-arm/arch-mv78xx0/hardware.h b/include/asm-arm/arch-mv78xx0/hardware.h
new file mode 100644 (file)
index 0000000..8e17926
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * include/asm-arm/arch-mv78xx0/hardware.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "mv78xx0.h"
+
+#define pcibios_assign_all_busses()    1
+
+#define PCIBIOS_MIN_IO                 0x00001000
+#define PCIBIOS_MIN_MEM                        0x01000000
+#define PCIMEM_BASE                    MV78XX0_PCIE_MEM_PHYS_BASE /* mem base for VGA */
+
+
+#endif
diff --git a/include/asm-arm/arch-mv78xx0/io.h b/include/asm-arm/arch-mv78xx0/io.h
new file mode 100644 (file)
index 0000000..415d4c9
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * include/asm-arm/arch-mv78xx0/io.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "mv78xx0.h"
+
+#define IO_SPACE_LIMIT         0xffffffff
+
+static inline void __iomem *__io(unsigned long addr)
+{
+       return (void __iomem *)((addr - MV78XX0_PCIE_IO_PHYS_BASE(0))
+                                       + MV78XX0_PCIE_IO_VIRT_BASE(0));
+}
+
+#define __io(a)                        __io(a)
+#define __mem_pci(a)           (a)
+
+
+#endif
diff --git a/include/asm-arm/arch-mv78xx0/irqs.h b/include/asm-arm/arch-mv78xx0/irqs.h
new file mode 100644 (file)
index 0000000..7593045
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * include/asm-arm/arch-mv78xx0/irqs.h
+ *
+ * IRQ definitions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#include "mv78xx0.h"   /* need GPIO_MAX */
+
+/*
+ * MV78xx0 Low Interrupt Controller
+ */
+#define IRQ_MV78XX0_ERR                0
+#define IRQ_MV78XX0_SPI                1
+#define IRQ_MV78XX0_I2C_0      2
+#define IRQ_MV78XX0_I2C_1      3
+#define IRQ_MV78XX0_IDMA_0     4
+#define IRQ_MV78XX0_IDMA_1     5
+#define IRQ_MV78XX0_IDMA_2     6
+#define IRQ_MV78XX0_IDMA_3     7
+#define IRQ_MV78XX0_TIMER_0    8
+#define IRQ_MV78XX0_TIMER_1    9
+#define IRQ_MV78XX0_TIMER_2    10
+#define IRQ_MV78XX0_TIMER_3    11
+#define IRQ_MV78XX0_UART_0     12
+#define IRQ_MV78XX0_UART_1     13
+#define IRQ_MV78XX0_UART_2     14
+#define IRQ_MV78XX0_UART_3     15
+#define IRQ_MV78XX0_USB_0      16
+#define IRQ_MV78XX0_USB_1      17
+#define IRQ_MV78XX0_USB_2      18
+#define IRQ_MV78XX0_CRYPTO     19
+#define IRQ_MV78XX0_SDIO_0     20
+#define IRQ_MV78XX0_SDIO_1     21
+#define IRQ_MV78XX0_XOR_0      22
+#define IRQ_MV78XX0_XOR_1      23
+#define IRQ_MV78XX0_I2S_0      24
+#define IRQ_MV78XX0_I2S_1      25
+#define IRQ_MV78XX0_SATA       26
+#define IRQ_MV78XX0_TDMI       27
+
+/*
+ * MV78xx0 High Interrupt Controller
+ */
+#define IRQ_MV78XX0_PCIE_00    32
+#define IRQ_MV78XX0_PCIE_01    33
+#define IRQ_MV78XX0_PCIE_02    34
+#define IRQ_MV78XX0_PCIE_03    35
+#define IRQ_MV78XX0_PCIE_10    36
+#define IRQ_MV78XX0_PCIE_11    37
+#define IRQ_MV78XX0_PCIE_12    38
+#define IRQ_MV78XX0_PCIE_13    39
+#define IRQ_MV78XX0_GE00_SUM   40
+#define IRQ_MV78XX0_GE00_RX    41
+#define IRQ_MV78XX0_GE00_TX    42
+#define IRQ_MV78XX0_GE00_MISC  43
+#define IRQ_MV78XX0_GE01_SUM   44
+#define IRQ_MV78XX0_GE01_RX    45
+#define IRQ_MV78XX0_GE01_TX    46
+#define IRQ_MV78XX0_GE01_MISC  47
+#define IRQ_MV78XX0_GE10_SUM   48
+#define IRQ_MV78XX0_GE10_RX    49
+#define IRQ_MV78XX0_GE10_TX    50
+#define IRQ_MV78XX0_GE10_MISC  51
+#define IRQ_MV78XX0_GE11_SUM   52
+#define IRQ_MV78XX0_GE11_RX    53
+#define IRQ_MV78XX0_GE11_TX    54
+#define IRQ_MV78XX0_GE11_MISC  55
+#define IRQ_MV78XX0_GPIO_0_7   56
+#define IRQ_MV78XX0_GPIO_8_15  57
+#define IRQ_MV78XX0_GPIO_16_23 58
+#define IRQ_MV78XX0_GPIO_24_31 59
+#define IRQ_MV78XX0_DB_IN      60
+#define IRQ_MV78XX0_DB_OUT     61
+
+/*
+ * MV78XX0 General Purpose Pins
+ */
+#define IRQ_MV78XX0_GPIO_START 64
+#define NR_GPIO_IRQS           GPIO_MAX
+
+#define NR_IRQS                        (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/include/asm-arm/arch-mv78xx0/memory.h b/include/asm-arm/arch-mv78xx0/memory.h
new file mode 100644 (file)
index 0000000..721a6b1
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * include/asm-arm/arch-mv78xx0/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET            UL(0x00000000)
+
+#define __virt_to_bus(x)       __virt_to_phys(x)
+#define __bus_to_virt(x)       __phys_to_virt(x)
+
+
+#endif
diff --git a/include/asm-arm/arch-mv78xx0/mv78xx0.h b/include/asm-arm/arch-mv78xx0/mv78xx0.h
new file mode 100644 (file)
index 0000000..9f5d83c
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * include/asm-arm/arch-mv78xx0/mv78xx0.h
+ *
+ * Generic definitions for Marvell MV78xx0 SoC flavors:
+ *  MV781x0 and MV782x0.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_MV78XX0_H
+#define __ASM_ARCH_MV78XX0_H
+
+/*
+ * Marvell MV78xx0 address maps.
+ *
+ * phys
+ * c0000000    PCIe Memory space
+ * f0800000    PCIe #0 I/O space
+ * f0900000    PCIe #1 I/O space
+ * f0a00000    PCIe #2 I/O space
+ * f0b00000    PCIe #3 I/O space
+ * f0c00000    PCIe #4 I/O space
+ * f0d00000    PCIe #5 I/O space
+ * f0e00000    PCIe #6 I/O space
+ * f0f00000    PCIe #7 I/O space
+ * f1000000    on-chip peripheral registers
+ *
+ * virt                phys            size
+ * fe400000    f102x000        16K     core-specific peripheral registers
+ * fe700000    f0800000        1M      PCIe #0 I/O space
+ * fe800000    f0900000        1M      PCIe #1 I/O space
+ * fe900000    f0a00000        1M      PCIe #2 I/O space
+ * fea00000    f0b00000        1M      PCIe #3 I/O space
+ * feb00000    f0c00000        1M      PCIe #4 I/O space
+ * fec00000    f0d00000        1M      PCIe #5 I/O space
+ * fed00000    f0e00000        1M      PCIe #6 I/O space
+ * fee00000    f0f00000        1M      PCIe #7 I/O space
+ * fef00000    f1000000        1M      on-chip peripheral registers
+ */
+#define MV78XX0_CORE0_REGS_PHYS_BASE   0xf1020000
+#define MV78XX0_CORE1_REGS_PHYS_BASE   0xf1024000
+#define MV78XX0_CORE_REGS_VIRT_BASE    0xfe400000
+#define MV78XX0_CORE_REGS_SIZE         SZ_16K
+
+#define MV78XX0_PCIE_IO_PHYS_BASE(i)   (0xf0800000 + ((i) << 20))
+#define MV78XX0_PCIE_IO_VIRT_BASE(i)   (0xfe700000 + ((i) << 20))
+#define MV78XX0_PCIE_IO_SIZE           SZ_1M
+
+#define MV78XX0_REGS_PHYS_BASE         0xf1000000
+#define MV78XX0_REGS_VIRT_BASE         0xfef00000
+#define MV78XX0_REGS_SIZE              SZ_1M
+
+#define MV78XX0_PCIE_MEM_PHYS_BASE     0xc0000000
+#define MV78XX0_PCIE_MEM_SIZE          0x30000000
+
+/*
+ * Core-specific peripheral registers.
+ */
+#define BRIDGE_VIRT_BASE       (MV78XX0_CORE_REGS_VIRT_BASE)
+#define  CPU_CONTROL           (BRIDGE_VIRT_BASE | 0x0104)
+#define   L2_WRITETHROUGH      0x00020000
+#define  RSTOUTn_MASK          (BRIDGE_VIRT_BASE | 0x0108)
+#define   SOFT_RESET_OUT_EN    0x00000004
+#define  SYSTEM_SOFT_RESET     (BRIDGE_VIRT_BASE | 0x010c)
+#define   SOFT_RESET           0x00000001
+#define  BRIDGE_CAUSE          (BRIDGE_VIRT_BASE | 0x0110)
+#define  BRIDGE_MASK           (BRIDGE_VIRT_BASE | 0x0114)
+#define   BRIDGE_INT_TIMER0    0x0002
+#define   BRIDGE_INT_TIMER1    0x0004
+#define   BRIDGE_INT_TIMER1_CLR        (~0x0004)
+#define  IRQ_VIRT_BASE         (BRIDGE_VIRT_BASE | 0x0200)
+#define   IRQ_CAUSE_LOW_OFF    0x0004
+#define   IRQ_CAUSE_HIGH_OFF   0x0008
+#define   IRQ_MASK_LOW_OFF     0x0010
+#define   IRQ_MASK_HIGH_OFF    0x0014
+#define  TIMER_VIRT_BASE       (BRIDGE_VIRT_BASE | 0x0300)
+
+/*
+ * Register Map
+ */
+#define DDR_VIRT_BASE          (MV78XX0_REGS_VIRT_BASE | 0x00000)
+#define  DDR_WINDOW_CPU0_BASE  (DDR_VIRT_BASE | 0x1500)
+#define  DDR_WINDOW_CPU1_BASE  (DDR_VIRT_BASE | 0x1700)
+
+#define DEV_BUS_PHYS_BASE      (MV78XX0_REGS_PHYS_BASE | 0x10000)
+#define DEV_BUS_VIRT_BASE      (MV78XX0_REGS_VIRT_BASE | 0x10000)
+#define  SAMPLE_AT_RESET_LOW   (DEV_BUS_VIRT_BASE | 0x0030)
+#define  SAMPLE_AT_RESET_HIGH  (DEV_BUS_VIRT_BASE | 0x0034)
+#define  UART0_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x2000)
+#define  UART0_VIRT_BASE       (DEV_BUS_VIRT_BASE | 0x2000)
+#define  UART1_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x2100)
+#define  UART1_VIRT_BASE       (DEV_BUS_VIRT_BASE | 0x2100)
+#define  UART2_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x2200)
+#define  UART2_VIRT_BASE       (DEV_BUS_VIRT_BASE | 0x2200)
+#define  UART3_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x2300)
+#define  UART3_VIRT_BASE       (DEV_BUS_VIRT_BASE | 0x2300)
+
+#define GE10_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0x30000)
+#define GE11_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0x34000)
+
+#define PCIE00_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x40000)
+#define PCIE01_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x44000)
+#define PCIE02_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x48000)
+#define PCIE03_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x4c000)
+
+#define USB0_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0x50000)
+#define USB1_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0x51000)
+#define USB2_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0x52000)
+
+#define GE00_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0x70000)
+#define GE01_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0x74000)
+
+#define PCIE10_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x80000)
+#define PCIE11_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x84000)
+#define PCIE12_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x88000)
+#define PCIE13_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE | 0x8c000)
+
+#define SATA_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE | 0xa0000)
+
+
+#define GPIO_MAX               32
+
+
+#endif
diff --git a/include/asm-arm/arch-mv78xx0/system.h b/include/asm-arm/arch-mv78xx0/system.h
new file mode 100644 (file)
index 0000000..7eb47d3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * include/asm-arm/arch-mv78xx0/system.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/mv78xx0.h>
+
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+       /*
+        * Enable soft reset to assert RSTOUTn.
+        */
+       writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
+
+       /*
+        * Assert soft reset.
+        */
+       writel(SOFT_RESET, SYSTEM_SOFT_RESET);
+
+       while (1)
+               ;
+}
+
+
+#endif
diff --git a/include/asm-arm/arch-mv78xx0/timex.h b/include/asm-arm/arch-mv78xx0/timex.h
new file mode 100644 (file)
index 0000000..a854b1c
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * include/asm-arm/arch-mv78xx0/timex.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE                (100 * HZ)
diff --git a/include/asm-arm/arch-mv78xx0/uncompress.h b/include/asm-arm/arch-mv78xx0/uncompress.h
new file mode 100644 (file)
index 0000000..3bfe0a2
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * include/asm-arm/arch-mv78xx0/uncompress.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/serial_reg.h>
+#include <asm/arch/mv78xx0.h>
+
+#define SERIAL_BASE    ((unsigned char *)UART0_PHYS_BASE)
+
+static void putc(const char c)
+{
+       unsigned char *base = SERIAL_BASE;
+       int i;
+
+       for (i = 0; i < 0x1000; i++) {
+               if (base[UART_LSR << 2] & UART_LSR_THRE)
+                       break;
+               barrier();
+       }
+
+       base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+       unsigned char *base = SERIAL_BASE;
+       unsigned char mask;
+       int i;
+
+       mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+       for (i = 0; i < 0x1000; i++) {
+               if ((base[UART_LSR << 2] & mask) == mask)
+                       break;
+               barrier();
+       }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-mv78xx0/vmalloc.h b/include/asm-arm/arch-mv78xx0/vmalloc.h
new file mode 100644 (file)
index 0000000..f2c5121
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * include/asm-arm/arch-mv78xx0/vmalloc.h
+ */
+
+#define VMALLOC_END    0xfe000000