ARM: add base support for Marvell Dove SoC

The Marvell Dove (88AP510) is a high-performance, highly integrated,
low power SoC with high-end ARM-compatible processor (known as PJ4),
graphics processing unit, high-definition video decoding acceleration
hardware, and a broad range of peripherals.

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: Saeed Bishara <saeed@marvell.com>
Signed-off-by: Nicolas Pitre <nico@marvell.com>
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
new file mode 100644
index 0000000..3b9a32a
--- /dev/null
+++ b/arch/arm/mach-dove/Kconfig
@@ -0,0 +1,14 @@
+if ARCH_DOVE
+
+menu "Marvell Dove Implementations"
+
+config MACH_DOVE_DB
+	bool "Marvell DB-MV88AP510 Development Board"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell DB-MV88AP510 Development Board.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-dove/Makefile b/arch/arm/mach-dove/Makefile
new file mode 100644
index 0000000..7ab3be5
--- /dev/null
+++ b/arch/arm/mach-dove/Makefile
@@ -0,0 +1,3 @@
+obj-y				+= common.o addr-map.o irq.o pcie.o
+
+obj-$(CONFIG_MACH_DOVE_DB)	+= dove-db-setup.o
diff --git a/arch/arm/mach-dove/Makefile.boot b/arch/arm/mach-dove/Makefile.boot
new file mode 100644
index 0000000..67039c3
--- /dev/null
+++ b/arch/arm/mach-dove/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c
new file mode 100644
index 0000000..00be4fc
--- /dev/null
+++ b/arch/arm/mach-dove/addr-map.c
@@ -0,0 +1,149 @@
+/*
+ * arch/arm/mach-dove/addr-map.c
+ *
+ * Address map functions for Marvell Dove 88AP510 SoC
+ *
+ * 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 <linux/io.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+#include "common.h"
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR		0x0
+#define TARGET_BOOTROM		0x1
+#define TARGET_CESA		0x3
+#define TARGET_PCIE0		0x4
+#define TARGET_PCIE1		0x8
+#define TARGET_SCRATCHPAD	0xd
+
+#define ATTR_CESA		0x01
+#define ATTR_BOOTROM		0xfd
+#define ATTR_DEV_SPI0_ROM	0xfe
+#define ATTR_DEV_SPI1_ROM	0xfb
+#define ATTR_PCIE_IO		0xe0
+#define ATTR_PCIE_MEM		0xe8
+#define ATTR_SCRATCHPAD		0x0
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN_CTRL(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0x0)
+#define WIN_BASE(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0x4)
+#define WIN_REMAP_LO(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0x8)
+#define WIN_REMAP_HI(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0xc)
+
+struct mbus_dram_target_info dove_mbus_dram_info;
+
+static inline void __iomem *ddr_map_sc(int i)
+{
+	return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
+}
+
+static int cpu_win_can_remap(int win)
+{
+	if (win < 4)
+		return 1;
+
+	return 0;
+}
+
+static void __init setup_cpu_win(int win, u32 base, u32 size,
+				 u8 target, u8 attr, int remap)
+{
+	u32 ctrl;
+
+	base &= 0xffff0000;
+	ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
+
+	writel(base, WIN_BASE(win));
+	writel(ctrl, WIN_CTRL(win));
+	if (cpu_win_can_remap(win)) {
+		if (remap < 0)
+			remap = base;
+		writel(remap & 0xffff0000, WIN_REMAP_LO(win));
+		writel(0, WIN_REMAP_HI(win));
+	}
+}
+
+void __init dove_setup_cpu_mbus(void)
+{
+	int i;
+	int cs;
+
+	/*
+	 * First, disable and clear windows.
+	 */
+	for (i = 0; i < 8; i++) {
+		writel(0, WIN_BASE(i));
+		writel(0, WIN_CTRL(i));
+		if (cpu_win_can_remap(i)) {
+			writel(0, WIN_REMAP_LO(i));
+			writel(0, WIN_REMAP_HI(i));
+		}
+	}
+
+	/*
+	 * Setup windows for PCIe IO+MEM space.
+	 */
+	setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
+		      TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE);
+	setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
+		      TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE);
+	setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
+		      TARGET_PCIE0, ATTR_PCIE_MEM, -1);
+	setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
+		      TARGET_PCIE1, ATTR_PCIE_MEM, -1);
+
+	/*
+	 * Setup window for CESA engine.
+	 */
+	setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
+		      TARGET_CESA, ATTR_CESA, -1);
+
+	/*
+	 * Setup the Window to the BootROM for Standby and Sleep Resume
+	 */
+	setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
+		      TARGET_BOOTROM, ATTR_BOOTROM, -1);
+
+	/*
+	 * Setup the Window to the PMU Scratch Pad space
+	 */
+	setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
+		      TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1);
+
+	/*
+	 * Setup MBUS dram target info.
+	 */
+	dove_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+	for (i = 0, cs = 0; i < 2; i++) {
+		u32 map = readl(ddr_map_sc(i));
+
+		/*
+		 * Chip select enabled?
+		 */
+		if (map & 1) {
+			struct mbus_dram_window *w;
+
+			w = &dove_mbus_dram_info.cs[cs++];
+			w->cs_index = i;
+			w->mbus_attr = 0; /* CS address decoding done inside */
+					  /* the DDR controller, no need to  */
+					  /* provide attributes */
+			w->base = map & 0xff800000;
+			w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
+		}
+	}
+	dove_mbus_dram_info.num_cs = cs;
+}
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
new file mode 100644
index 0000000..a20cf09
--- /dev/null
+++ b/arch/arm/mach-dove/common.c
@@ -0,0 +1,777 @@
+/*
+ * arch/arm/mach-dove/common.c
+ *
+ * Core functions for Marvell Dove 88AP510 System On Chip
+ *
+ * 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/delay.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/mbus.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/gpio.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/timex.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/pci.h>
+#include <mach/dove.h>
+#include <mach/bridge-regs.h>
+#include <asm/mach/arch.h>
+#include <linux/irq.h>
+#include <plat/mv_xor.h>
+#include <plat/ehci-orion.h>
+#include <plat/time.h>
+#include "common.h"
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc dove_io_desc[] __initdata = {
+	{
+		.virtual	= DOVE_SB_REGS_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
+		.length		= DOVE_SB_REGS_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= DOVE_NB_REGS_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
+		.length		= DOVE_NB_REGS_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= DOVE_PCIE0_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
+		.length		= DOVE_PCIE0_IO_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= DOVE_PCIE1_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
+		.length		= DOVE_PCIE1_IO_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init dove_map_io(void)
+{
+	iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc));
+}
+
+/*****************************************************************************
+ * EHCI
+ ****************************************************************************/
+static struct orion_ehci_data dove_ehci_data = {
+	.dram		= &dove_mbus_dram_info,
+	.phy_version	= EHCI_PHY_NA,
+};
+
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+static struct resource dove_ehci0_resources[] = {
+	{
+		.start	= DOVE_USB0_PHYS_BASE,
+		.end	= DOVE_USB0_PHYS_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_USB0,
+		.end	= IRQ_DOVE_USB0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_ehci0 = {
+	.name		= "orion-ehci",
+	.id		= 0,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &dove_ehci_data,
+	},
+	.resource	= dove_ehci0_resources,
+	.num_resources	= ARRAY_SIZE(dove_ehci0_resources),
+};
+
+void __init dove_ehci0_init(void)
+{
+	platform_device_register(&dove_ehci0);
+}
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+static struct resource dove_ehci1_resources[] = {
+	{
+		.start	= DOVE_USB1_PHYS_BASE,
+		.end	= DOVE_USB1_PHYS_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_USB1,
+		.end	= IRQ_DOVE_USB1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_ehci1 = {
+	.name		= "orion-ehci",
+	.id		= 1,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &dove_ehci_data,
+	},
+	.resource	= dove_ehci1_resources,
+	.num_resources	= ARRAY_SIZE(dove_ehci1_resources),
+};
+
+void __init dove_ehci1_init(void)
+{
+	platform_device_register(&dove_ehci1);
+}
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data dove_ge00_shared_data = {
+	.t_clk		= 0,
+	.dram		= &dove_mbus_dram_info,
+};
+
+static struct resource dove_ge00_shared_resources[] = {
+	{
+		.name	= "ge00 base",
+		.start	= DOVE_GE00_PHYS_BASE + 0x2000,
+		.end	= DOVE_GE00_PHYS_BASE + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dove_ge00_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &dove_ge00_shared_data,
+	},
+	.num_resources	= 1,
+	.resource	= dove_ge00_shared_resources,
+};
+
+static struct resource dove_ge00_resources[] = {
+	{
+		.name	= "ge00 irq",
+		.start	= IRQ_DOVE_GE00_SUM,
+		.end	= IRQ_DOVE_GE00_SUM,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_ge00 = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= dove_ge00_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
+
+void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
+{
+	eth_data->shared = &dove_ge00_shared;
+	dove_ge00.dev.platform_data = eth_data;
+
+	platform_device_register(&dove_ge00_shared);
+	platform_device_register(&dove_ge00);
+}
+
+/*****************************************************************************
+ * SoC RTC
+ ****************************************************************************/
+static struct resource dove_rtc_resource[] = {
+	{
+		.start	= DOVE_RTC_PHYS_BASE,
+		.end	= DOVE_RTC_PHYS_BASE + 32 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_RTC,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+void __init dove_rtc_init(void)
+{
+	platform_device_register_simple("rtc-mv", -1, dove_rtc_resource, 2);
+}
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct resource dove_sata_resources[] = {
+	{
+		.name	= "sata base",
+		.start	= DOVE_SATA_PHYS_BASE,
+		.end	= DOVE_SATA_PHYS_BASE + 0x5000 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "sata irq",
+		.start	= IRQ_DOVE_SATA,
+		.end	= IRQ_DOVE_SATA,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_sata = {
+	.name		= "sata_mv",
+	.id		= 0,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(dove_sata_resources),
+	.resource	= dove_sata_resources,
+};
+
+void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
+{
+	sata_data->dram = &dove_mbus_dram_info;
+	dove_sata.dev.platform_data = sata_data;
+	platform_device_register(&dove_sata);
+}
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart0_data[] = {
+	{
+		.mapbase	= DOVE_UART0_PHYS_BASE,
+		.membase	= (char *)DOVE_UART0_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_0,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart0_resources[] = {
+	{
+		.start		= DOVE_UART0_PHYS_BASE,
+		.end		= DOVE_UART0_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_0,
+		.end		= IRQ_DOVE_UART_0,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart0 = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= dove_uart0_data,
+	},
+	.resource		= dove_uart0_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart0_resources),
+};
+
+void __init dove_uart0_init(void)
+{
+	platform_device_register(&dove_uart0);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart1_data[] = {
+	{
+		.mapbase	= DOVE_UART1_PHYS_BASE,
+		.membase	= (char *)DOVE_UART1_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_1,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart1_resources[] = {
+	{
+		.start		= DOVE_UART1_PHYS_BASE,
+		.end		= DOVE_UART1_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_1,
+		.end		= IRQ_DOVE_UART_1,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart1 = {
+	.name			= "serial8250",
+	.id			= 1,
+	.dev			= {
+		.platform_data	= dove_uart1_data,
+	},
+	.resource		= dove_uart1_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart1_resources),
+};
+
+void __init dove_uart1_init(void)
+{
+	platform_device_register(&dove_uart1);
+}
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart2_data[] = {
+	{
+		.mapbase	= DOVE_UART2_PHYS_BASE,
+		.membase	= (char *)DOVE_UART2_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_2,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart2_resources[] = {
+	{
+		.start		= DOVE_UART2_PHYS_BASE,
+		.end		= DOVE_UART2_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_2,
+		.end		= IRQ_DOVE_UART_2,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart2 = {
+	.name			= "serial8250",
+	.id			= 2,
+	.dev			= {
+		.platform_data	= dove_uart2_data,
+	},
+	.resource		= dove_uart2_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart2_resources),
+};
+
+void __init dove_uart2_init(void)
+{
+	platform_device_register(&dove_uart2);
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart3_data[] = {
+	{
+		.mapbase	= DOVE_UART3_PHYS_BASE,
+		.membase	= (char *)DOVE_UART3_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_3,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart3_resources[] = {
+	{
+		.start		= DOVE_UART3_PHYS_BASE,
+		.end		= DOVE_UART3_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_3,
+		.end		= IRQ_DOVE_UART_3,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart3 = {
+	.name			= "serial8250",
+	.id			= 3,
+	.dev			= {
+		.platform_data	= dove_uart3_data,
+	},
+	.resource		= dove_uart3_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart3_resources),
+};
+
+void __init dove_uart3_init(void)
+{
+	platform_device_register(&dove_uart3);
+}
+
+/*****************************************************************************
+ * SPI0
+ ****************************************************************************/
+static struct orion_spi_info dove_spi0_data = {
+	.tclk		= 0,
+};
+
+static struct resource dove_spi0_resources[] = {
+	{
+		.start	= DOVE_SPI0_PHYS_BASE,
+		.end	= DOVE_SPI0_PHYS_BASE + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_SPI0,
+		.end	= IRQ_DOVE_SPI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_spi0 = {
+	.name		= "orion_spi",
+	.id		= 0,
+	.resource	= dove_spi0_resources,
+	.dev		= {
+		.platform_data	= &dove_spi0_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_spi0_resources),
+};
+
+void __init dove_spi0_init(void)
+{
+	platform_device_register(&dove_spi0);
+}
+
+/*****************************************************************************
+ * SPI1
+ ****************************************************************************/
+static struct orion_spi_info dove_spi1_data = {
+	.tclk		= 0,
+};
+
+static struct resource dove_spi1_resources[] = {
+	{
+		.start	= DOVE_SPI1_PHYS_BASE,
+		.end	= DOVE_SPI1_PHYS_BASE + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_SPI1,
+		.end	= IRQ_DOVE_SPI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_spi1 = {
+	.name		= "orion_spi",
+	.id		= 1,
+	.resource	= dove_spi1_resources,
+	.dev		= {
+		.platform_data	= &dove_spi1_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_spi1_resources),
+};
+
+void __init dove_spi1_init(void)
+{
+	platform_device_register(&dove_spi1);
+}
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+static struct mv64xxx_i2c_pdata dove_i2c_data = {
+	.freq_m		= 10, /* assumes 166 MHz TCLK gets 94.3kHz */
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource dove_i2c_resources[] = {
+	{
+		.name	= "i2c base",
+		.start	= DOVE_I2C_PHYS_BASE,
+		.end	= DOVE_I2C_PHYS_BASE + 0x20 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "i2c irq",
+		.start	= IRQ_DOVE_I2C,
+		.end	= IRQ_DOVE_I2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_i2c = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dove_i2c_resources),
+	.resource	= dove_i2c_resources,
+	.dev		= {
+		.platform_data = &dove_i2c_data,
+	},
+};
+
+void __init dove_i2c_init(void)
+{
+	platform_device_register(&dove_i2c);
+}
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+static int get_tclk(void)
+{
+	/* use DOVE_RESET_SAMPLE_HI/LO to detect tclk */
+	return 166666667;
+}
+
+static void dove_timer_init(void)
+{
+	orion_time_init(IRQ_DOVE_BRIDGE, get_tclk());
+}
+
+struct sys_timer dove_timer = {
+	.init = dove_timer_init,
+};
+
+/*****************************************************************************
+ * XOR
+ ****************************************************************************/
+static struct mv_xor_platform_shared_data dove_xor_shared_data = {
+	.dram		= &dove_mbus_dram_info,
+};
+
+/*****************************************************************************
+ * XOR 0
+ ****************************************************************************/
+static u64 dove_xor0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource dove_xor0_shared_resources[] = {
+	{
+		.name	= "xor 0 low",
+		.start	= DOVE_XOR0_PHYS_BASE,
+		.end	= DOVE_XOR0_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "xor 0 high",
+		.start	= DOVE_XOR0_HIGH_PHYS_BASE,
+		.end	= DOVE_XOR0_HIGH_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dove_xor0_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 0,
+	.dev		= {
+		.platform_data = &dove_xor_shared_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_xor0_shared_resources),
+	.resource	= dove_xor0_shared_resources,
+};
+
+static struct resource dove_xor00_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_00,
+		.end	= IRQ_DOVE_XOR_00,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor00_data = {
+	.shared		= &dove_xor0_shared,
+	.hw_id		= 0,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor00_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dove_xor00_resources),
+	.resource	= dove_xor00_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor00_data,
+	},
+};
+
+static struct resource dove_xor01_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_01,
+		.end	= IRQ_DOVE_XOR_01,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor01_data = {
+	.shared		= &dove_xor0_shared,
+	.hw_id		= 1,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor01_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(dove_xor01_resources),
+	.resource	= dove_xor01_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor01_data,
+	},
+};
+
+void __init dove_xor0_init(void)
+{
+	platform_device_register(&dove_xor0_shared);
+
+	/*
+	 * two engines can't do memset simultaneously, this limitation
+	 * satisfied by removing memset support from one of the engines.
+	 */
+	dma_cap_set(DMA_MEMCPY, dove_xor00_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor00_data.cap_mask);
+	platform_device_register(&dove_xor00_channel);
+
+	dma_cap_set(DMA_MEMCPY, dove_xor01_data.cap_mask);
+	dma_cap_set(DMA_MEMSET, dove_xor01_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor01_data.cap_mask);
+	platform_device_register(&dove_xor01_channel);
+}
+
+/*****************************************************************************
+ * XOR 1
+ ****************************************************************************/
+static u64 dove_xor1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource dove_xor1_shared_resources[] = {
+	{
+		.name	= "xor 0 low",
+		.start	= DOVE_XOR1_PHYS_BASE,
+		.end	= DOVE_XOR1_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "xor 0 high",
+		.start	= DOVE_XOR1_HIGH_PHYS_BASE,
+		.end	= DOVE_XOR1_HIGH_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dove_xor1_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 1,
+	.dev		= {
+		.platform_data = &dove_xor_shared_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_xor1_shared_resources),
+	.resource	= dove_xor1_shared_resources,
+};
+
+static struct resource dove_xor10_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_10,
+		.end	= IRQ_DOVE_XOR_10,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor10_data = {
+	.shared		= &dove_xor1_shared,
+	.hw_id		= 0,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor10_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(dove_xor10_resources),
+	.resource	= dove_xor10_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor10_data,
+	},
+};
+
+static struct resource dove_xor11_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_11,
+		.end	= IRQ_DOVE_XOR_11,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor11_data = {
+	.shared		= &dove_xor1_shared,
+	.hw_id		= 1,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor11_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 3,
+	.num_resources	= ARRAY_SIZE(dove_xor11_resources),
+	.resource	= dove_xor11_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor11_data,
+	},
+};
+
+void __init dove_xor1_init(void)
+{
+	platform_device_register(&dove_xor1_shared);
+
+	/*
+	 * two engines can't do memset simultaneously, this limitation
+	 * satisfied by removing memset support from one of the engines.
+	 */
+	dma_cap_set(DMA_MEMCPY, dove_xor10_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor10_data.cap_mask);
+	platform_device_register(&dove_xor10_channel);
+
+	dma_cap_set(DMA_MEMCPY, dove_xor11_data.cap_mask);
+	dma_cap_set(DMA_MEMSET, dove_xor11_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor11_data.cap_mask);
+	platform_device_register(&dove_xor11_channel);
+}
+
+void __init dove_init(void)
+{
+	int tclk;
+
+	tclk = get_tclk();
+
+	printk(KERN_INFO "Dove 88AP510 SoC, ");
+	printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000);
+
+	dove_setup_cpu_mbus();
+
+	dove_ge00_shared_data.t_clk = tclk;
+	dove_uart0_data[0].uartclk = tclk;
+	dove_uart1_data[0].uartclk = tclk;
+	dove_uart2_data[0].uartclk = tclk;
+	dove_uart3_data[0].uartclk = tclk;
+	dove_spi0_data.tclk = tclk;
+	dove_spi1_data.tclk = tclk;
+
+	/* internal devices that every board has */
+	dove_rtc_init();
+	dove_xor0_init();
+	dove_xor1_init();
+}
diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h
new file mode 100644
index 0000000..b29e893
--- /dev/null
+++ b/arch/arm/mach-dove/common.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-dove/common.h
+ *
+ * Core functions for Marvell Dove 88AP510 System On Chip
+ *
+ * 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_DOVE_COMMON_H
+#define __ARCH_DOVE_COMMON_H
+
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+extern struct sys_timer dove_timer;
+extern struct mbus_dram_target_info dove_mbus_dram_info;
+
+/*
+ * Basic Dove init functions used early by machine-setup.
+ */
+void dove_map_io(void);
+void dove_init(void);
+void dove_init_irq(void);
+void dove_setup_cpu_mbus(void);
+void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void dove_sata_init(struct mv_sata_platform_data *sata_data);
+void dove_pcie_init(int init_port0, int init_port1);
+void dove_ehci0_init(void);
+void dove_ehci1_init(void);
+void dove_uart0_init(void);
+void dove_uart1_init(void);
+void dove_uart2_init(void);
+void dove_uart3_init(void);
+void dove_spi0_init(void);
+void dove_spi1_init(void);
+void dove_i2c_init(void);
+
+#endif
diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c
new file mode 100644
index 0000000..f2971b7
--- /dev/null
+++ b/arch/arm/mach-dove/dove-db-setup.c
@@ -0,0 +1,102 @@
+/*
+ * arch/arm/mach-dove/dove-db-setup.c
+ *
+ * Marvell DB-MV88AP510-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/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/timer.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/pci.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/spi/flash.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/dove.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data dove_db_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR_DEFAULT,
+};
+
+static struct mv_sata_platform_data dove_db_sata_data = {
+	.n_ports        = 1,
+};
+
+/*****************************************************************************
+ * SPI Devices:
+ * 	SPI0: 4M Flash ST-M25P32-VMF6P
+ ****************************************************************************/
+static const struct flash_platform_data dove_db_spi_flash_data = {
+	.type		= "m25p64",
+};
+
+static struct spi_board_info __initdata dove_db_spi_flash_info[] = {
+	{
+		.modalias       = "m25p80",
+		.platform_data  = &dove_db_spi_flash_data,
+		.irq            = -1,
+		.max_speed_hz   = 20000000,
+		.bus_num        = 0,
+		.chip_select    = 0,
+	},
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+static int __init dove_db_pci_init(void)
+{
+	if (machine_is_dove_db())
+		dove_pcie_init(1, 1);
+
+	return 0;
+}
+
+subsys_initcall(dove_db_pci_init);
+
+/*****************************************************************************
+ * Board Init
+ ****************************************************************************/
+static void __init dove_db_init(void)
+{
+	/*
+	 * Basic Dove setup. Needs to be called early.
+	 */
+	dove_init();
+
+	dove_ge00_init(&dove_db_ge00_data);
+	dove_ehci0_init();
+	dove_ehci1_init();
+	dove_sata_init(&dove_db_sata_data);
+	dove_spi0_init();
+	dove_spi1_init();
+	dove_uart0_init();
+	dove_uart1_init();
+	dove_i2c_init();
+	spi_register_board_info(dove_db_spi_flash_info,
+				ARRAY_SIZE(dove_db_spi_flash_info));
+}
+
+MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board")
+	.phys_io	= DOVE_SB_REGS_PHYS_BASE,
+	.io_pg_offst	= ((DOVE_SB_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= dove_db_init,
+	.map_io		= dove_map_io,
+	.init_irq	= dove_init_irq,
+	.timer		= &dove_timer,
+MACHINE_END
diff --git a/arch/arm/mach-dove/include/mach/bridge-regs.h b/arch/arm/mach-dove/include/mach/bridge-regs.h
new file mode 100644
index 0000000..214a4c3
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/bridge-regs.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-dove/include/mach/bridge-regs.h
+ *
+ * Mbus-L to Mbus Bridge Registers
+ *
+ * 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_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/dove.h>
+
+#define CPU_CONFIG		(BRIDGE_VIRT_BASE | 0x0000)
+
+#define CPU_CONTROL		(BRIDGE_VIRT_BASE | 0x0104)
+#define  CPU_CTRL_PCIE0_LINK	0x00000001
+#define  CPU_RESET		0x00000002
+#define  CPU_CTRL_PCIE1_LINK	0x00000008
+
+#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	0x0000
+#define IRQ_MASK_LOW_OFF	0x0004
+#define FIQ_MASK_LOW_OFF	0x0008
+#define ENDPOINT_MASK_LOW_OFF	0x000c
+#define IRQ_CAUSE_HIGH_OFF	0x0010
+#define IRQ_MASK_HIGH_OFF	0x0014
+#define FIQ_MASK_HIGH_OFF	0x0018
+#define ENDPOINT_MASK_HIGH_OFF	0x001c
+#define PCIE_INTERRUPT_MASK_OFF	0x0020
+
+#define IRQ_MASK_LOW		(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)
+#define FIQ_MASK_LOW		(IRQ_VIRT_BASE + FIQ_MASK_LOW_OFF)
+#define ENDPOINT_MASK_LOW	(IRQ_VIRT_BASE + ENDPOINT_MASK_LOW_OFF)
+#define IRQ_MASK_HIGH		(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)
+#define FIQ_MASK_HIGH		(IRQ_VIRT_BASE + FIQ_MASK_HIGH_OFF)
+#define ENDPOINT_MASK_HIGH	(IRQ_VIRT_BASE + ENDPOINT_MASK_HIGH_OFF)
+#define PCIE_INTERRUPT_MASK	(IRQ_VIRT_BASE + PCIE_INTERRUPT_MASK_OFF)
+
+#define POWER_MANAGEMENT	(BRIDGE_VIRT_BASE | 0x011c)
+
+#define TIMER_VIRT_BASE		(BRIDGE_VIRT_BASE | 0x0300)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/debug-macro.S b/arch/arm/mach-dove/include/mach/debug-macro.S
new file mode 100644
index 0000000..9b89ec7
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/debug-macro.S
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-dove/include/mach/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 <mach/bridge-regs.h>
+
+	.macro	addruart,rx
+	mrc	p15, 0, \rx, c1, c0
+	tst	\rx, #1					@ MMU enabled?
+	ldreq	\rx, =DOVE_SB_REGS_PHYS_BASE
+	ldrne	\rx, =DOVE_SB_REGS_VIRT_BASE
+	orr	\rx, \rx, #0x00012000
+	.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h
new file mode 100644
index 0000000..f6a0839
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -0,0 +1,180 @@
+/*
+ * arch/arm/mach-dove/include/mach/dove.h
+ *
+ * Generic definitions for Marvell Dove 88AP510 SoC
+ *
+ * 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_DOVE_H
+#define __ASM_ARCH_DOVE_H
+
+#include <mach/vmalloc.h>
+
+/*
+ * Marvell Dove address maps.
+ *
+ * phys		virt		size
+ * c8000000	fdb00000	1M	Cryptographic SRAM
+ * e0000000	@runtime	128M	PCIe-0 Memory space
+ * e8000000	@runtime	128M	PCIe-1 Memory space
+ * f1000000	fde00000	8M	on-chip south-bridge registers
+ * f1800000	fe600000	8M	on-chip north-bridge registers
+ * f2000000	fee00000	1M	PCIe-0 I/O space
+ * f2100000	fef00000	1M	PCIe-1 I/O space
+ */
+
+#define DOVE_CESA_PHYS_BASE		0xc8000000
+#define DOVE_CESA_VIRT_BASE		0xfdb00000
+#define DOVE_CESA_SIZE			SZ_1M
+
+#define DOVE_PCIE0_MEM_PHYS_BASE	0xe0000000
+#define DOVE_PCIE0_MEM_SIZE		SZ_128M
+
+#define DOVE_PCIE1_MEM_PHYS_BASE	0xe8000000
+#define DOVE_PCIE1_MEM_SIZE		SZ_128M
+
+#define DOVE_BOOTROM_PHYS_BASE		0xf8000000
+#define DOVE_BOOTROM_SIZE		SZ_128M
+
+#define DOVE_SCRATCHPAD_PHYS_BASE	0xf0000000
+#define DOVE_SCRATCHPAD_VIRT_BASE	0xfdd00000
+#define DOVE_SCRATCHPAD_SIZE		SZ_1M
+
+#define DOVE_SB_REGS_PHYS_BASE		0xf1000000
+#define DOVE_SB_REGS_VIRT_BASE		0xfde00000
+#define DOVE_SB_REGS_SIZE		SZ_8M
+
+#define DOVE_NB_REGS_PHYS_BASE		0xf1800000
+#define DOVE_NB_REGS_VIRT_BASE		0xfe600000
+#define DOVE_NB_REGS_SIZE		SZ_8M
+
+#define DOVE_PCIE0_IO_PHYS_BASE		0xf2000000
+#define DOVE_PCIE0_IO_VIRT_BASE		0xfee00000
+#define DOVE_PCIE0_IO_BUS_BASE		0x00000000
+#define DOVE_PCIE0_IO_SIZE		SZ_1M
+
+#define DOVE_PCIE1_IO_PHYS_BASE		0xf2100000
+#define DOVE_PCIE1_IO_VIRT_BASE		0xfef00000
+#define DOVE_PCIE1_IO_BUS_BASE		0x00100000
+#define DOVE_PCIE1_IO_SIZE		SZ_1M
+
+/*
+ * Dove Core Registers Map
+ */
+
+/* SPI, I2C, UART */
+#define DOVE_I2C_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x11000)
+#define DOVE_UART0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12000)
+#define DOVE_UART0_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12000)
+#define DOVE_UART1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12100)
+#define DOVE_UART1_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12100)
+#define DOVE_UART2_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12200)
+#define DOVE_UART2_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12200)
+#define DOVE_UART3_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12300)
+#define DOVE_UART3_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12300)
+#define DOVE_SPI0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x10600)
+#define DOVE_SPI1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x14600)
+
+/* North-South Bridge */
+#define BRIDGE_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x20000)
+
+/* Cryptographic Engine */
+#define DOVE_CRYPT_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x30000)
+
+/* PCIe 0 */
+#define DOVE_PCIE0_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x40000)
+
+/* USB */
+#define DOVE_USB0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x50000)
+#define DOVE_USB1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x51000)
+
+/* XOR 0 Engine */
+#define DOVE_XOR0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60800)
+#define DOVE_XOR0_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60800)
+#define DOVE_XOR0_HIGH_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60A00)
+#define DOVE_XOR0_HIGH_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60A00)
+
+/* XOR 1 Engine */
+#define DOVE_XOR1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60900)
+#define DOVE_XOR1_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60900)
+#define DOVE_XOR1_HIGH_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60B00)
+#define DOVE_XOR1_HIGH_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60B00)
+
+/* Gigabit Ethernet */
+#define DOVE_GE00_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x70000)
+
+/* PCIe 1 */
+#define DOVE_PCIE1_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x80000)
+
+/* CAFE */
+#define DOVE_SDIO0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x92000)
+#define DOVE_SDIO1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x90000)
+#define DOVE_CAM_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x94000)
+#define DOVE_CAFE_WIN_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x98000)
+
+/* SATA */
+#define DOVE_SATA_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xa0000)
+
+/* I2S/SPDIF */
+#define DOVE_AUD0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xb0000)
+#define DOVE_AUD1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xb4000)
+
+/* NAND Flash Controller */
+#define DOVE_NFC_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xc0000)
+
+/* MPP, GPIO, Reset Sampling */
+#define DOVE_MPP_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xd0200)
+#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
+#define DOVE_RESET_SAMPLE_LO	(DOVE_MPP_VIRT_BASE | 0x014)
+#define DOVE_RESET_SAMPLE_HI	(DOVE_MPP_VIRT_BASE | 0x018)
+#define DOVE_GPIO_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xd0400)
+#define DOVE_MPP_GENERAL_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xe803c)
+#define  DOVE_AU1_SPDIFO_GPIO_EN	(1 << 1)
+#define  DOVE_NAND_GPIO_EN		(1 << 0)
+#define DOVE_MPP_CTRL4_VIRT_BASE	(DOVE_GPIO_VIRT_BASE + 0x40)
+
+
+/* Power Management */
+#define DOVE_PMU_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xd0000)
+
+/* Real Time Clock */
+#define DOVE_RTC_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xd8500)
+
+/* AC97 */
+#define DOVE_AC97_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xe0000)
+#define DOVE_AC97_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xe0000)
+
+/* Peripheral DMA */
+#define DOVE_PDMA_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xe4000)
+#define DOVE_PDMA_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xe4000)
+
+#define DOVE_GLOBAL_CONFIG_1	(DOVE_SB_REGS_VIRT_BASE | 0xe802C)
+#define  DOVE_TWSI_ENABLE_OPTION1	(1 << 7)
+#define DOVE_GLOBAL_CONFIG_2	(DOVE_SB_REGS_VIRT_BASE | 0xe8030)
+#define  DOVE_TWSI_ENABLE_OPTION2	(1 << 20)
+#define  DOVE_TWSI_ENABLE_OPTION3	(1 << 21)
+#define  DOVE_TWSI_OPTION3_GPIO		(1 << 22)
+#define DOVE_SSP_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xec000)
+#define DOVE_SSP_CTRL_STATUS_1	(DOVE_SB_REGS_VIRT_BASE | 0xe8034)
+#define  DOVE_SSP_ON_AU1		(1 << 0)
+#define  DOVE_SSP_CLOCK_ENABLE		(1 << 1)
+#define  DOVE_SSP_BPB_CLOCK_SRC_SSP	(1 << 11)
+/* Memory Controller */
+#define DOVE_MC_VIRT_BASE	(DOVE_NB_REGS_VIRT_BASE | 0x00000)
+
+/* LCD Controller */
+#define DOVE_LCD_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x10000)
+#define DOVE_LCD1_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x20000)
+#define DOVE_LCD2_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x10000)
+#define DOVE_LCD_DCON_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x30000)
+
+/* Graphic Engine */
+#define DOVE_GPU_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x40000)
+
+/* Video Engine */
+#define DOVE_VPU_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x400000)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/entry-macro.S b/arch/arm/mach-dove/include/mach/entry-macro.S
new file mode 100644
index 0000000..e84c78c
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-dove/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Marvell Dove 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 <mach/bridge-regs.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/arch/arm/mach-dove/include/mach/gpio.h b/arch/arm/mach-dove/include/mach/gpio.h
new file mode 100644
index 0000000..0ee70ff
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/gpio.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-dove/include/mach/gpio.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_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <asm/errno.h>
+#include <mach/irqs.h>
+#include <plat/gpio.h>
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
+
+#define GPIO_MAX	64
+
+#define GPIO_BASE_LO		(DOVE_GPIO_VIRT_BASE + 0x00)
+#define GPIO_BASE_HI		(DOVE_GPIO_VIRT_BASE + 0x20)
+
+#define GPIO_BASE(pin)		((pin < 32) ? GPIO_BASE_LO : GPIO_BASE_HI)
+
+#define GPIO_OUT(pin)		(GPIO_BASE(pin) + 0x00)
+#define GPIO_IO_CONF(pin)	(GPIO_BASE(pin) + 0x04)
+#define GPIO_BLINK_EN(pin)	(GPIO_BASE(pin) + 0x08)
+#define GPIO_IN_POL(pin)	(GPIO_BASE(pin) + 0x0c)
+#define GPIO_DATA_IN(pin)	(GPIO_BASE(pin) + 0x10)
+#define GPIO_EDGE_CAUSE(pin)	(GPIO_BASE(pin) + 0x14)
+#define GPIO_EDGE_MASK(pin)	(GPIO_BASE(pin) + 0x18)
+#define GPIO_LEVEL_MASK(pin)	(GPIO_BASE(pin) + 0x1c)
+
+static inline int gpio_to_irq(int pin)
+{
+	if (pin < NR_GPIO_IRQS)
+		return pin + IRQ_DOVE_GPIO_START;
+
+	return -EINVAL;
+}
+
+static inline int irq_to_gpio(int irq)
+{
+	if (IRQ_DOVE_GPIO_START < irq && irq < NR_IRQS)
+		return irq - IRQ_DOVE_GPIO_START;
+
+	return -EINVAL;
+}
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/hardware.h b/arch/arm/mach-dove/include/mach/hardware.h
new file mode 100644
index 0000000..32b0826
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/hardware.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-dove/include/mach/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 "dove.h"
+
+#define pcibios_assign_all_busses()	1
+
+#define PCIBIOS_MIN_IO			0x1000
+#define PCIBIOS_MIN_MEM			0x01000000
+#define PCIMEM_BASE			DOVE_PCIE0_MEM_PHYS_BASE
+
+
+/* Macros below are required for compatibility with PXA AC'97 driver.	*/
+#define __REG(x)	(*((volatile u32 *)((x) - DOVE_SB_REGS_PHYS_BASE + \
+				DOVE_SB_REGS_VIRT_BASE)))
+#define __PREG(x)	(((u32)&(x)) - DOVE_SB_REGS_VIRT_BASE + \
+		DOVE_SB_REGS_PHYS_BASE)
+#endif
diff --git a/arch/arm/mach-dove/include/mach/io.h b/arch/arm/mach-dove/include/mach/io.h
new file mode 100644
index 0000000..3b3e472
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-dove/include/mach/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 "dove.h"
+
+#define IO_SPACE_LIMIT		0xffffffff
+
+#define __io(a)  ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\
+				   DOVE_PCIE0_IO_VIRT_BASE))
+#define __mem_pci(a)		(a)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/irqs.h b/arch/arm/mach-dove/include/mach/irqs.h
new file mode 100644
index 0000000..4668146
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/irqs.h
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/mach-dove/include/mach/irqs.h
+ *
+ * IRQ definitions for Marvell Dove 88AP510 SoC
+ *
+ * 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
+
+/*
+ * Dove Low Interrupt Controller
+ */
+#define IRQ_DOVE_BRIDGE		0
+#define IRQ_DOVE_H2C		1
+#define IRQ_DOVE_C2H		2
+#define IRQ_DOVE_NAND		3
+#define IRQ_DOVE_PDMA		4
+#define IRQ_DOVE_SPI1		5
+#define IRQ_DOVE_SPI0		6
+#define IRQ_DOVE_UART_0		7
+#define IRQ_DOVE_UART_1		8
+#define IRQ_DOVE_UART_2		9
+#define IRQ_DOVE_UART_3		10
+#define IRQ_DOVE_I2C		11
+#define IRQ_DOVE_GPIO_0_7	12
+#define IRQ_DOVE_GPIO_8_15	13
+#define IRQ_DOVE_GPIO_16_23	14
+#define IRQ_DOVE_PCIE0_ERR	15
+#define IRQ_DOVE_PCIE0		16
+#define IRQ_DOVE_PCIE1_ERR	17
+#define IRQ_DOVE_PCIE1		18
+#define IRQ_DOVE_I2S0		19
+#define IRQ_DOVE_I2S0_ERR	20
+#define IRQ_DOVE_I2S1		21
+#define IRQ_DOVE_I2S1_ERR	22
+#define IRQ_DOVE_USB_ERR	23
+#define IRQ_DOVE_USB0		24
+#define IRQ_DOVE_USB1		25
+#define IRQ_DOVE_GE00_RX	26
+#define IRQ_DOVE_GE00_TX	27
+#define IRQ_DOVE_GE00_MISC	28
+#define IRQ_DOVE_GE00_SUM	29
+#define IRQ_DOVE_GE00_ERR	30
+#define IRQ_DOVE_CRYPTO		31
+
+/*
+ * Dove High Interrupt Controller
+ */
+#define IRQ_DOVE_AC97		32
+#define IRQ_DOVE_PMU		33
+#define IRQ_DOVE_CAM		34
+#define IRQ_DOVE_SDIO0		35
+#define IRQ_DOVE_SDIO1		36
+#define IRQ_DOVE_SDIO0_WAKEUP	37
+#define IRQ_DOVE_SDIO1_WAKEUP	38
+#define IRQ_DOVE_XOR_00		39
+#define IRQ_DOVE_XOR_01		40
+#define IRQ_DOVE_XOR0_ERR	41
+#define IRQ_DOVE_XOR_10		42
+#define IRQ_DOVE_XOR_11		43
+#define IRQ_DOVE_XOR1_ERR	44
+#define IRQ_DOVE_LCD_DCON	45
+#define IRQ_DOVE_LCD1		46
+#define IRQ_DOVE_LCD0		47
+#define IRQ_DOVE_GPU		48
+#define IRQ_DOVE_PERFORM_MNTR	49
+#define IRQ_DOVE_VPRO_DMA1	51
+#define IRQ_DOVE_SSP_TIMER	54
+#define IRQ_DOVE_SSP		55
+#define IRQ_DOVE_MC_L2_ERR	56
+#define IRQ_DOVE_CRYPTO_ERR	59
+#define IRQ_DOVE_GPIO_24_31	60
+#define IRQ_DOVE_HIGH_GPIO	61
+#define IRQ_DOVE_SATA		62
+
+/*
+ * DOVE General Purpose Pins
+ */
+#define IRQ_DOVE_GPIO_START	64
+#define NR_GPIO_IRQS		64
+
+/*
+ * PMU interrupts
+ */
+#define IRQ_DOVE_PMU_START	(IRQ_DOVE_GPIO_START + NR_GPIO_IRQS)
+#define NR_PMU_IRQS		7
+#define IRQ_DOVE_RTC		(IRQ_DOVE_PMU_START + 5)
+
+#define NR_IRQS			(IRQ_DOVE_PMU_START + NR_PMU_IRQS)
+
+/* Required for compatability with PXA AC97 driver.	*/
+#define IRQ_AC97		IRQ_DOVE_AC97
+/* Required for compatability with PXA DMA driver.	*/
+#define IRQ_DMA			IRQ_DOVE_PDMA
+/* Required for compatability with PXA NAND driver 	*/
+#define IRQ_NAND		IRQ_DOVE_NAND
+#endif
diff --git a/arch/arm/mach-dove/include/mach/memory.h b/arch/arm/mach-dove/include/mach/memory.h
new file mode 100644
index 0000000..d668720
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/memory.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-dove/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET		UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h
new file mode 100644
index 0000000..3ad9f94
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/pm.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-dove/include/mach/pm.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_PM_H
+#define __ASM_ARCH_PM_H
+
+#include <asm/errno.h>
+#include <mach/irqs.h>
+
+#define CLOCK_GATING_CONTROL	(DOVE_PMU_VIRT_BASE + 0x38)
+#define  CLOCK_GATING_USB0_MASK		(1 << 0)
+#define  CLOCK_GATING_USB1_MASK		(1 << 1)
+#define  CLOCK_GATING_GBE_MASK		(1 << 2)
+#define  CLOCK_GATING_SATA_MASK		(1 << 3)
+#define  CLOCK_GATING_PCIE0_MASK	(1 << 4)
+#define  CLOCK_GATING_PCIE1_MASK	(1 << 5)
+#define  CLOCK_GATING_SDIO0_MASK	(1 << 8)
+#define  CLOCK_GATING_SDIO1_MASK	(1 << 9)
+#define  CLOCK_GATING_NAND_MASK		(1 << 10)
+#define  CLOCK_GATING_CAMERA_MASK	(1 << 11)
+#define  CLOCK_GATING_I2S0_MASK		(1 << 12)
+#define  CLOCK_GATING_I2S1_MASK		(1 << 13)
+#define  CLOCK_GATING_CRYPTO_MASK	(1 << 15)
+#define  CLOCK_GATING_AC97_MASK		(1 << 21)
+#define  CLOCK_GATING_PDMA_MASK		(1 << 22)
+#define  CLOCK_GATING_XOR0_MASK		(1 << 23)
+#define  CLOCK_GATING_XOR1_MASK		(1 << 24)
+#define  CLOCK_GATING_GIGA_PHY_MASK	(1 << 30)
+
+#define PMU_INTERRUPT_CAUSE	(DOVE_PMU_VIRT_BASE + 0x50)
+#define PMU_INTERRUPT_MASK	(DOVE_PMU_VIRT_BASE + 0x54)
+
+static inline int pmu_to_irq(int pin)
+{
+	if (pin < NR_PMU_IRQS)
+		return pin + IRQ_DOVE_PMU_START;
+
+	return -EINVAL;
+}
+
+static inline int irq_to_pmu(int irq)
+{
+	if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
+		return irq - IRQ_DOVE_PMU_START;
+
+	return -EINVAL;
+}
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/system.h b/arch/arm/mach-dove/include/mach/system.h
new file mode 100644
index 0000000..356afda
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/system.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-dove/include/mach/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 <mach/bridge-regs.h>
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	/*
+	 * 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/arch/arm/mach-dove/include/mach/timex.h b/arch/arm/mach-dove/include/mach/timex.h
new file mode 100644
index 0000000..251d538
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/timex.h
@@ -0,0 +1,9 @@
+/*
+ * arch/arm/mach-dove/include/mach/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/arch/arm/mach-dove/include/mach/uncompress.h b/arch/arm/mach-dove/include/mach/uncompress.h
new file mode 100644
index 0000000..2c5cdd7
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-dove/include/mach/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 <mach/dove.h>
+
+#define UART_THR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x0))
+#define UART_LSR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x14))
+
+#define LSR_THRE	0x20
+
+static void putc(const char c)
+{
+	int i;
+
+	for (i = 0; i < 0x1000; i++) {
+		/* Transmit fifo not full? */
+		if (*UART_LSR & LSR_THRE)
+			break;
+	}
+
+	*UART_THR = c;
+}
+
+static void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-dove/include/mach/vmalloc.h b/arch/arm/mach-dove/include/mach/vmalloc.h
new file mode 100644
index 0000000..8b2c974
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-dove/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END	0xfd800000
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
new file mode 100644
index 0000000..61bfcb3
--- /dev/null
+++ b/arch/arm/mach-dove/irq.c
@@ -0,0 +1,133 @@
+/*
+ * arch/arm/mach-dove/irq.c
+ *
+ * Dove 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/irq.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <asm/mach/arch.h>
+#include <plat/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/pm.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int irqoff;
+	BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO);
+
+	irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 :
+		3 + irq - IRQ_DOVE_GPIO_24_31;
+
+	orion_gpio_irq_handler(irqoff << 3);
+	if (irq == IRQ_DOVE_HIGH_GPIO) {
+		orion_gpio_irq_handler(40);
+		orion_gpio_irq_handler(48);
+		orion_gpio_irq_handler(56);
+	}
+}
+
+static void pmu_irq_mask(unsigned int irq)
+{
+	int pin = irq_to_pmu(irq);
+	u32 u;
+
+	u = readl(PMU_INTERRUPT_MASK);
+	u &= ~(1 << (pin & 31));
+	writel(u, PMU_INTERRUPT_MASK);
+}
+
+static void pmu_irq_unmask(unsigned int irq)
+{
+	int pin = irq_to_pmu(irq);
+	u32 u;
+
+	u = readl(PMU_INTERRUPT_MASK);
+	u |= 1 << (pin & 31);
+	writel(u, PMU_INTERRUPT_MASK);
+}
+
+static void pmu_irq_ack(unsigned int irq)
+{
+	int pin = irq_to_pmu(irq);
+	u32 u;
+
+	u = ~(1 << (pin & 31));
+	writel(u, PMU_INTERRUPT_CAUSE);
+}
+
+static struct irq_chip pmu_irq_chip = {
+	.name		= "pmu_irq",
+	.mask		= pmu_irq_mask,
+	.unmask		= pmu_irq_unmask,
+	.ack		= pmu_irq_ack,
+};
+
+static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned long cause = readl(PMU_INTERRUPT_CAUSE);
+
+	cause &= readl(PMU_INTERRUPT_MASK);
+	if (cause == 0) {
+		do_bad_IRQ(irq, desc);
+		return;
+	}
+
+	for (irq = 0; irq < NR_PMU_IRQS; irq++) {
+		if (!(cause & (1 << irq)))
+			continue;
+		irq = pmu_to_irq(irq);
+		desc = irq_desc + irq;
+		desc_handle_irq(irq, desc);
+	}
+}
+
+void __init dove_init_irq(void)
+{
+	int i;
+
+	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));
+
+	/*
+	 * Mask and clear GPIO IRQ interrupts.
+	 */
+	writel(0, GPIO_LEVEL_MASK(0));
+	writel(0, GPIO_EDGE_MASK(0));
+	writel(0, GPIO_EDGE_CAUSE(0));
+
+	/*
+	 * Mask and clear PMU interrupts
+	 */
+	writel(0, PMU_INTERRUPT_MASK);
+	writel(0, PMU_INTERRUPT_CAUSE);
+
+	for (i = IRQ_DOVE_GPIO_START; i < IRQ_DOVE_PMU_START; i++) {
+		set_irq_chip(i, &orion_gpio_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		irq_desc[i].status |= IRQ_LEVEL;
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
+
+	for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) {
+		set_irq_chip(i, &pmu_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		irq_desc[i].status |= IRQ_LEVEL;
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
+}
diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c
new file mode 100644
index 0000000..502d1ca
--- /dev/null
+++ b/arch/arm/mach-dove/pcie.c
@@ -0,0 +1,238 @@
+/*
+ * arch/arm/mach-dove/pcie.c
+ *
+ * PCIe functions for Marvell Dove 88AP510 SoC
+ *
+ * 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/mach/arch.h>
+#include <asm/setup.h>
+#include <asm/delay.h>
+#include <plat/pcie.h>
+#include <mach/irqs.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+struct pcie_port {
+	u8			index;
+	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[2];
+static int num_pcie_ports;
+
+
+static int __init dove_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, &dove_mbus_dram_info);
+
+	/*
+	 * IORESOURCE_IO
+	 */
+	snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+		 "PCIe %d I/O", pp->index);
+	pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+	pp->res[0].name = pp->io_space_name;
+	if (pp->index == 0) {
+		pp->res[0].start = DOVE_PCIE0_IO_PHYS_BASE;
+		pp->res[0].end = pp->res[0].start + DOVE_PCIE0_IO_SIZE - 1;
+	} else {
+		pp->res[0].start = DOVE_PCIE1_IO_PHYS_BASE;
+		pp->res[0].end = pp->res[0].start + DOVE_PCIE1_IO_SIZE - 1;
+	}
+	pp->res[0].flags = IORESOURCE_IO;
+	if (request_resource(&ioport_resource, &pp->res[0]))
+		panic("Request PCIe IO resource failed\n");
+	sys->resource[0] = &pp->res[0];
+
+	/*
+	 * IORESOURCE_MEM
+	 */
+	snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+		 "PCIe %d MEM", pp->index);
+	pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+	pp->res[1].name = pp->mem_space_name;
+	if (pp->index == 0) {
+		pp->res[1].start = DOVE_PCIE0_MEM_PHYS_BASE;
+		pp->res[1].end = pp->res[1].start + DOVE_PCIE0_MEM_SIZE - 1;
+	} else {
+		pp->res[1].start = DOVE_PCIE1_MEM_PHYS_BASE;
+		pp->res[1].end = pp->res[1].start + DOVE_PCIE1_MEM_SIZE - 1;
+	}
+	pp->res[1].flags = IORESOURCE_MEM;
+	if (request_resource(&iomem_resource, &pp->res[1]))
+		panic("Request PCIe Memory resource failed\n");
+	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 *
+dove_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 dove_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct pcie_port *pp = bus_to_port(dev->bus->number);
+
+	return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0;
+}
+
+static struct hw_pci dove_pci __initdata = {
+	.nr_controllers	= 2,
+	.swizzle	= pci_std_swizzle,
+	.setup		= dove_pcie_setup,
+	.scan		= dove_pcie_scan_bus,
+	.map_irq	= dove_pcie_map_irq,
+};
+
+static void __init add_pcie_port(int index, unsigned long base)
+{
+	printk(KERN_INFO "Dove PCIe port %d: ", index);
+
+	if (orion_pcie_link_up((void __iomem *)base)) {
+		struct pcie_port *pp = &pcie_port[num_pcie_ports++];
+
+		printk(KERN_INFO "link up\n");
+
+		pp->index = index;
+		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(KERN_INFO "link down, ignoring\n");
+	}
+}
+
+void __init dove_pcie_init(int init_port0, int init_port1)
+{
+	if (init_port0)
+		add_pcie_port(0, DOVE_PCIE0_VIRT_BASE);
+
+	if (init_port1)
+		add_pcie_port(1, DOVE_PCIE1_VIRT_BASE);
+
+	pci_common_init(&dove_pci);
+}