aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-cns3xxx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-cns3xxx')
-rw-r--r--arch/arm/mach-cns3xxx/Kconfig13
-rw-r--r--arch/arm/mach-cns3xxx/Makefile3
-rw-r--r--arch/arm/mach-cns3xxx/Makefile.boot3
-rw-r--r--arch/arm/mach-cns3xxx/cns3420vb.c204
-rw-r--r--arch/arm/mach-cns3xxx/core.c246
-rw-r--r--arch/arm/mach-cns3xxx/core.h20
-rw-r--r--arch/arm/mach-cns3xxx/devices.c112
-rw-r--r--arch/arm/mach-cns3xxx/devices.h20
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/cns3xxx.h632
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/entry-macro.S18
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/hardware.h22
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/io.h17
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/irqs.h24
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/memory.h26
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/pm.h23
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/system.h29
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/timex.h12
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/uncompress.h55
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/vmalloc.h11
-rw-r--r--arch/arm/mach-cns3xxx/pcie.c389
-rw-r--r--arch/arm/mach-cns3xxx/pm.c124
22 files changed, 2022 insertions, 0 deletions
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
new file mode 100644
index 00000000..29b13f24
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -0,0 +1,13 @@
+menu "CNS3XXX platform type"
+ depends on ARCH_CNS3XXX
+
+config MACH_CNS3420VB
+ bool "Support for CNS3420 Validation Board"
+ select MIGHT_HAVE_PCI
+ help
+ Include support for the Cavium Networks CNS3420 MPCore Platform
+ Baseboard.
+ This is a platform with an on-board ARM11 MPCore and has support
+ for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc.
+
+endmenu
diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile
new file mode 100644
index 00000000..11033f1c
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ARCH_CNS3XXX) += core.o pm.o devices.o
+obj-$(CONFIG_PCI) += pcie.o
+obj-$(CONFIG_MACH_CNS3420VB) += cns3420vb.o
diff --git a/arch/arm/mach-cns3xxx/Makefile.boot b/arch/arm/mach-cns3xxx/Makefile.boot
new file mode 100644
index 00000000..77701286
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00C00000
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
new file mode 100644
index 00000000..08e5c875
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -0,0 +1,204 @@
+/*
+ * Cavium Networks CNS3420 Validation Board
+ *
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 ARM Limited
+ * Copyright 2008 Cavium Networks
+ * Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+#include <mach/irqs.h>
+#include "core.h"
+#include "devices.h"
+
+/*
+ * NOR Flash
+ */
+static struct mtd_partition cns3420_nor_partitions[] = {
+ {
+ .name = "uboot",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .size = 0x004C0000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "filesystem",
+ .size = 0x7000000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "filesystem2",
+ .size = 0x0AE0000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "ubootenv",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+static struct physmap_flash_data cns3420_nor_pdata = {
+ .width = 2,
+ .parts = cns3420_nor_partitions,
+ .nr_parts = ARRAY_SIZE(cns3420_nor_partitions),
+};
+
+static struct resource cns3420_nor_res = {
+ .start = CNS3XXX_FLASH_BASE,
+ .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+};
+
+static struct platform_device cns3420_nor_pdev = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &cns3420_nor_res,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &cns3420_nor_pdata,
+ },
+};
+
+/*
+ * UART
+ */
+static void __init cns3420_early_serial_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ static struct uart_port cns3420_serial_port = {
+ .membase = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
+ .mapbase = CNS3XXX_UART0_BASE,
+ .irq = IRQ_CNS3XXX_UART0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .regshift = 2,
+ .uartclk = 24000000,
+ .line = 0,
+ .type = PORT_16550A,
+ .fifosize = 16,
+ };
+
+ early_serial_setup(&cns3420_serial_port);
+#endif
+}
+
+/*
+ * USB
+ */
+static struct resource cns3xxx_usb_ehci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_USB_BASE,
+ .end = CNS3XXX_USB_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_USB_EHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_usb_ehci_device = {
+ .name = "cns3xxx-ehci",
+ .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
+ .resource = cns3xxx_usb_ehci_resources,
+ .dev = {
+ .dma_mask = &cns3xxx_usb_ehci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource cns3xxx_usb_ohci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_USB_OHCI_BASE,
+ .end = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_USB_OHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_usb_ohci_device = {
+ .name = "cns3xxx-ohci",
+ .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
+ .resource = cns3xxx_usb_ohci_resources,
+ .dev = {
+ .dma_mask = &cns3xxx_usb_ohci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/*
+ * Initialization
+ */
+static struct platform_device *cns3420_pdevs[] __initdata = {
+ &cns3420_nor_pdev,
+ &cns3xxx_usb_ehci_device,
+ &cns3xxx_usb_ohci_device,
+};
+
+static void __init cns3420_init(void)
+{
+ platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs));
+
+ cns3xxx_ahci_init();
+ cns3xxx_sdhci_init();
+
+ pm_power_off = cns3xxx_power_off;
+}
+
+static struct map_desc cns3420_io_desc[] __initdata = {
+ {
+ .virtual = CNS3XXX_UART0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init cns3420_map_io(void)
+{
+ cns3xxx_map_io();
+ iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
+
+ cns3420_early_serial_setup();
+}
+
+MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
+ .boot_params = 0x00000100,
+ .map_io = cns3420_map_io,
+ .init_irq = cns3xxx_init_irq,
+ .timer = &cns3xxx_timer,
+ .init_machine = cns3420_init,
+MACHINE_END
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
new file mode 100644
index 00000000..da30078a
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright 1999 - 2003 ARM Limited
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/gic.h>
+#include <mach/cns3xxx.h>
+#include "core.h"
+
+static struct map_desc cns3xxx_io_desc[] __initdata = {
+ {
+ .virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TIMER1_2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_GPIOA_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_GPIOA_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_GPIOB_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_GPIOB_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_MISC_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_MISC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_PM_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PM_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init cns3xxx_map_io(void)
+{
+ iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
+}
+
+/* used by entry-macro.S */
+void __init cns3xxx_init_irq(void)
+{
+ gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
+ __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
+}
+
+void cns3xxx_power_off(void)
+{
+ u32 __iomem *pm_base = __io(CNS3XXX_PM_BASE_VIRT);
+ u32 clkctrl;
+
+ printk(KERN_INFO "powering system down...\n");
+
+ clkctrl = readl(pm_base + PM_SYS_CLK_CTRL_OFFSET);
+ clkctrl &= 0xfffff1ff;
+ clkctrl |= (0x5 << 9); /* Hibernate */
+ writel(clkctrl, pm_base + PM_SYS_CLK_CTRL_OFFSET);
+
+}
+
+/*
+ * Timer
+ */
+static void __iomem *cns3xxx_tmr1;
+
+static void cns3xxx_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ int pclk = cns3xxx_cpu_clock() / 8;
+ int reload;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ reload = pclk * 20 / (3 * HZ) * 0x25000;
+ writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+ ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* period set, and timer enabled in 'next_event' hook */
+ ctrl |= (1 << 2) | (1 << 9);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ ctrl = 0;
+ }
+
+ writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+}
+
+static int cns3xxx_timer_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ writel(evt, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+ writel(ctrl | (1 << 0), cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ return 0;
+}
+
+static struct clock_event_device cns3xxx_tmr1_clockevent = {
+ .name = "cns3xxx timer1",
+ .shift = 8,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = cns3xxx_timer_set_mode,
+ .set_next_event = cns3xxx_timer_set_next_event,
+ .rating = 350,
+ .cpumask = cpu_all_mask,
+};
+
+static void __init cns3xxx_clockevents_init(unsigned int timer_irq)
+{
+ cns3xxx_tmr1_clockevent.irq = timer_irq;
+ cns3xxx_tmr1_clockevent.mult =
+ div_sc((cns3xxx_cpu_clock() >> 3) * 1000000, NSEC_PER_SEC,
+ cns3xxx_tmr1_clockevent.shift);
+ cns3xxx_tmr1_clockevent.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &cns3xxx_tmr1_clockevent);
+ cns3xxx_tmr1_clockevent.min_delta_ns =
+ clockevent_delta2ns(0xf, &cns3xxx_tmr1_clockevent);
+
+ clockevents_register_device(&cns3xxx_tmr1_clockevent);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &cns3xxx_tmr1_clockevent;
+ u32 __iomem *stat = cns3xxx_tmr1 + TIMER1_2_INTERRUPT_STATUS_OFFSET;
+ u32 val;
+
+ /* Clear the interrupt */
+ val = readl(stat);
+ writel(val & ~(1 << 2), stat);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction cns3xxx_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = cns3xxx_timer_interrupt,
+};
+
+/*
+ * Set up the clock source and clock events devices
+ */
+static void __init __cns3xxx_timer_init(unsigned int timer_irq)
+{
+ u32 val;
+ u32 irq_mask;
+
+ /*
+ * Initialise to a known state (all timers off)
+ */
+
+ /* disable timer1 and timer2 */
+ writel(0, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ /* stop free running timer3 */
+ writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
+
+ /* timer1 */
+ writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
+ writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+
+ writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
+ writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
+
+ /* mask irq, non-mask timer1 overflow */
+ irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+ irq_mask &= ~(1 << 2);
+ irq_mask |= 0x03;
+ writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+ /* down counter */
+ val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ val |= (1 << 9);
+ writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ /* timer2 */
+ writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
+ writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
+
+ /* mask irq */
+ irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+ irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
+ writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+ /* down counter */
+ val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ val |= (1 << 10);
+ writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ /* Make irqs happen for the system timer */
+ setup_irq(timer_irq, &cns3xxx_timer_irq);
+
+ cns3xxx_clockevents_init(timer_irq);
+}
+
+static void __init cns3xxx_timer_init(void)
+{
+ cns3xxx_tmr1 = __io(CNS3XXX_TIMER1_2_3_BASE_VIRT);
+
+ __cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0);
+}
+
+struct sys_timer cns3xxx_timer = {
+ .init = cns3xxx_timer_init,
+};
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h
new file mode 100644
index 00000000..ffeb3a8b
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2004 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#ifndef __CNS3XXX_CORE_H
+#define __CNS3XXX_CORE_H
+
+extern struct sys_timer cns3xxx_timer;
+
+void __init cns3xxx_map_io(void);
+void __init cns3xxx_init_irq(void);
+void cns3xxx_power_off(void);
+
+#endif /* __CNS3XXX_CORE_H */
diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c
new file mode 100644
index 00000000..79d1fb02
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/devices.c
@@ -0,0 +1,112 @@
+/*
+ * CNS3xxx common devices
+ *
+ * Copyright 2008 Cavium Networks
+ * Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file 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 <linux/io.h>
+#include <linux/init.h>
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <mach/cns3xxx.h>
+#include <mach/irqs.h>
+#include <mach/pm.h>
+#include "core.h"
+#include "devices.h"
+
+/*
+ * AHCI
+ */
+static struct resource cns3xxx_ahci_resource[] = {
+ [0] = {
+ .start = CNS3XXX_SATA2_BASE,
+ .end = CNS3XXX_SATA2_BASE + CNS3XXX_SATA2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_SATA,
+ .end = IRQ_CNS3XXX_SATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_ahci_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_ahci_pdev = {
+ .name = "ahci",
+ .id = 0,
+ .resource = cns3xxx_ahci_resource,
+ .num_resources = ARRAY_SIZE(cns3xxx_ahci_resource),
+ .dev = {
+ .dma_mask = &cns3xxx_ahci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init cns3xxx_ahci_init(void)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(MISC_SATA_POWER_MODE);
+ tmp |= 0x1 << 16; /* Disable SATA PHY 0 from SLUMBER Mode */
+ tmp |= 0x1 << 17; /* Disable SATA PHY 1 from SLUMBER Mode */
+ __raw_writel(tmp, MISC_SATA_POWER_MODE);
+
+ /* Enable SATA PHY */
+ cns3xxx_pwr_power_up(0x1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0);
+ cns3xxx_pwr_power_up(0x1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1);
+
+ /* Enable SATA Clock */
+ cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_SATA);
+
+ /* De-Asscer SATA Reset */
+ cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SATA));
+
+ platform_device_register(&cns3xxx_ahci_pdev);
+}
+
+/*
+ * SDHCI
+ */
+static struct resource cns3xxx_sdhci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_SDIO_BASE,
+ .end = CNS3XXX_SDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_SDIO,
+ .end = IRQ_CNS3XXX_SDIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cns3xxx_sdhci_pdev = {
+ .name = "sdhci-cns3xxx",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(cns3xxx_sdhci_resources),
+ .resource = cns3xxx_sdhci_resources,
+};
+
+void __init cns3xxx_sdhci_init(void)
+{
+ u32 __iomem *gpioa = __io(CNS3XXX_MISC_BASE_VIRT + 0x0014);
+ u32 gpioa_pins = __raw_readl(gpioa);
+
+ /* MMC/SD pins share with GPIOA */
+ gpioa_pins |= 0x1fff0004;
+ __raw_writel(gpioa_pins, gpioa);
+
+ cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SDIO));
+ cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO));
+
+ platform_device_register(&cns3xxx_sdhci_pdev);
+}
diff --git a/arch/arm/mach-cns3xxx/devices.h b/arch/arm/mach-cns3xxx/devices.h
new file mode 100644
index 00000000..27e15a10
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/devices.h
@@ -0,0 +1,20 @@
+/*
+ * CNS3xxx common devices
+ *
+ * Copyright 2008 Cavium Networks
+ * Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file 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.
+ */
+
+#ifndef __CNS3XXX_DEVICES_H_
+#define __CNS3XXX_DEVICES_H_
+
+void __init cns3xxx_ahci_init(void);
+void __init cns3xxx_sdhci_init(void);
+
+#endif /* __CNS3XXX_DEVICES_H_ */
diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
new file mode 100644
index 00000000..191c8e57
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
@@ -0,0 +1,632 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#ifndef __MACH_BOARD_CNS3XXXH
+#define __MACH_BOARD_CNS3XXXH
+
+/*
+ * Memory map
+ */
+#define CNS3XXX_FLASH_BASE 0x10000000 /* Flash/SRAM Memory Bank 0 */
+#define CNS3XXX_FLASH_SIZE SZ_256M
+
+#define CNS3XXX_DDR2SDRAM_BASE 0x20000000 /* DDR2 SDRAM Memory */
+
+#define CNS3XXX_SPI_FLASH_BASE 0x60000000 /* SPI Serial Flash Memory */
+
+#define CNS3XXX_SWITCH_BASE 0x70000000 /* Switch and HNAT Control */
+#define CNS3XXX_SWITCH_BASE_VIRT 0xFFF00000
+
+#define CNS3XXX_PPE_BASE 0x70001000 /* HANT */
+#define CNS3XXX_PPE_BASE_VIRT 0xFFF50000
+
+#define CNS3XXX_EMBEDDED_SRAM_BASE 0x70002000 /* HANT Embedded SRAM */
+#define CNS3XXX_EMBEDDED_SRAM_BASE_VIRT 0xFFF60000
+
+#define CNS3XXX_SSP_BASE 0x71000000 /* Synchronous Serial Port - SPI/PCM/I2C */
+#define CNS3XXX_SSP_BASE_VIRT 0xFFF01000
+
+#define CNS3XXX_DMC_BASE 0x72000000 /* DMC Control (DDR2 SDRAM) */
+#define CNS3XXX_DMC_BASE_VIRT 0xFFF02000
+
+#define CNS3XXX_SMC_BASE 0x73000000 /* SMC Control */
+#define CNS3XXX_SMC_BASE_VIRT 0xFFF03000
+
+#define SMC_MEMC_STATUS_OFFSET 0x000
+#define SMC_MEMIF_CFG_OFFSET 0x004
+#define SMC_MEMC_CFG_SET_OFFSET 0x008
+#define SMC_MEMC_CFG_CLR_OFFSET 0x00C
+#define SMC_DIRECT_CMD_OFFSET 0x010
+#define SMC_SET_CYCLES_OFFSET 0x014
+#define SMC_SET_OPMODE_OFFSET 0x018
+#define SMC_REFRESH_PERIOD_0_OFFSET 0x020
+#define SMC_REFRESH_PERIOD_1_OFFSET 0x024
+#define SMC_SRAM_CYCLES0_0_OFFSET 0x100
+#define SMC_NAND_CYCLES0_0_OFFSET 0x100
+#define SMC_OPMODE0_0_OFFSET 0x104
+#define SMC_SRAM_CYCLES0_1_OFFSET 0x120
+#define SMC_NAND_CYCLES0_1_OFFSET 0x120
+#define SMC_OPMODE0_1_OFFSET 0x124
+#define SMC_USER_STATUS_OFFSET 0x200
+#define SMC_USER_CONFIG_OFFSET 0x204
+#define SMC_ECC_STATUS_OFFSET 0x300
+#define SMC_ECC_MEMCFG_OFFSET 0x304
+#define SMC_ECC_MEMCOMMAND1_OFFSET 0x308
+#define SMC_ECC_MEMCOMMAND2_OFFSET 0x30C
+#define SMC_ECC_ADDR0_OFFSET 0x310
+#define SMC_ECC_ADDR1_OFFSET 0x314
+#define SMC_ECC_VALUE0_OFFSET 0x318
+#define SMC_ECC_VALUE1_OFFSET 0x31C
+#define SMC_ECC_VALUE2_OFFSET 0x320
+#define SMC_ECC_VALUE3_OFFSET 0x324
+#define SMC_PERIPH_ID_0_OFFSET 0xFE0
+#define SMC_PERIPH_ID_1_OFFSET 0xFE4
+#define SMC_PERIPH_ID_2_OFFSET 0xFE8
+#define SMC_PERIPH_ID_3_OFFSET 0xFEC
+#define SMC_PCELL_ID_0_OFFSET 0xFF0
+#define SMC_PCELL_ID_1_OFFSET 0xFF4
+#define SMC_PCELL_ID_2_OFFSET 0xFF8
+#define SMC_PCELL_ID_3_OFFSET 0xFFC
+
+#define CNS3XXX_GPIOA_BASE 0x74000000 /* GPIO port A */
+#define CNS3XXX_GPIOA_BASE_VIRT 0xFFF04000
+
+#define CNS3XXX_GPIOB_BASE 0x74800000 /* GPIO port B */
+#define CNS3XXX_GPIOB_BASE_VIRT 0xFFF05000
+
+#define CNS3XXX_RTC_BASE 0x75000000 /* Real Time Clock */
+#define CNS3XXX_RTC_BASE_VIRT 0xFFF06000
+
+#define RTC_SEC_OFFSET 0x00
+#define RTC_MIN_OFFSET 0x04
+#define RTC_HOUR_OFFSET 0x08
+#define RTC_DAY_OFFSET 0x0C
+#define RTC_SEC_ALM_OFFSET 0x10
+#define RTC_MIN_ALM_OFFSET 0x14
+#define RTC_HOUR_ALM_OFFSET 0x18
+#define RTC_REC_OFFSET 0x1C
+#define RTC_CTRL_OFFSET 0x20
+#define RTC_INTR_STS_OFFSET 0x34
+
+#define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */
+#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */
+
+#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */
+#define CNS3XXX_PM_BASE_VIRT 0xFFF08000
+
+#define PM_CLK_GATE_OFFSET 0x00
+#define PM_SOFT_RST_OFFSET 0x04
+#define PM_HS_CFG_OFFSET 0x08
+#define PM_CACTIVE_STA_OFFSET 0x0C
+#define PM_PWR_STA_OFFSET 0x10
+#define PM_SYS_CLK_CTRL_OFFSET 0x14
+#define PM_PLL_LCD_I2S_CTRL_OFFSET 0x18
+#define PM_PLL_HM_PD_OFFSET 0x1C
+
+#define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */
+#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000
+
+#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */
+#define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000
+
+#define CNS3XXX_UART2_BASE 0x78800000 /* UART 2 */
+#define CNS3XXX_UART2_BASE_VIRT 0xFFF0B000
+
+#define CNS3XXX_DMAC_BASE 0x79000000 /* Generic DMA Control */
+#define CNS3XXX_DMAC_BASE_VIRT 0xFFF0D000
+
+#define CNS3XXX_CORESIGHT_BASE 0x7A000000 /* CoreSight */
+#define CNS3XXX_CORESIGHT_BASE_VIRT 0xFFF0E000
+
+#define CNS3XXX_CRYPTO_BASE 0x7B000000 /* Crypto */
+#define CNS3XXX_CRYPTO_BASE_VIRT 0xFFF0F000
+
+#define CNS3XXX_I2S_BASE 0x7C000000 /* I2S */
+#define CNS3XXX_I2S_BASE_VIRT 0xFFF10000
+
+#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */
+#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800
+
+#define TIMER1_COUNTER_OFFSET 0x00
+#define TIMER1_AUTO_RELOAD_OFFSET 0x04
+#define TIMER1_MATCH_V1_OFFSET 0x08
+#define TIMER1_MATCH_V2_OFFSET 0x0C
+
+#define TIMER2_COUNTER_OFFSET 0x10
+#define TIMER2_AUTO_RELOAD_OFFSET 0x14
+#define TIMER2_MATCH_V1_OFFSET 0x18
+#define TIMER2_MATCH_V2_OFFSET 0x1C
+
+#define TIMER1_2_CONTROL_OFFSET 0x30
+#define TIMER1_2_INTERRUPT_STATUS_OFFSET 0x34
+#define TIMER1_2_INTERRUPT_MASK_OFFSET 0x38
+
+#define TIMER_FREERUN_OFFSET 0x40
+#define TIMER_FREERUN_CONTROL_OFFSET 0x44
+
+#define CNS3XXX_HCIE_BASE 0x7D000000 /* HCIE Control */
+#define CNS3XXX_HCIE_BASE_VIRT 0xFFF30000
+
+#define CNS3XXX_RAID_BASE 0x7E000000 /* RAID Control */
+#define CNS3XXX_RAID_BASE_VIRT 0xFFF12000
+
+#define CNS3XXX_AXI_IXC_BASE 0x7F000000 /* AXI IXC */
+#define CNS3XXX_AXI_IXC_BASE_VIRT 0xFFF13000
+
+#define CNS3XXX_CLCD_BASE 0x80000000 /* LCD Control */
+#define CNS3XXX_CLCD_BASE_VIRT 0xFFF14000
+
+#define CNS3XXX_USBOTG_BASE 0x81000000 /* USB OTG Control */
+#define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000
+
+#define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */
+
+#define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */
+#define CNS3XXX_SATA2_SIZE SZ_16M
+#define CNS3XXX_SATA2_BASE_VIRT 0xFFF17000
+
+#define CNS3XXX_CAMERA_BASE 0x84000000 /* Camera Interface */
+#define CNS3XXX_CAMERA_BASE_VIRT 0xFFF18000
+
+#define CNS3XXX_SDIO_BASE 0x85000000 /* SDIO */
+#define CNS3XXX_SDIO_BASE_VIRT 0xFFF19000
+
+#define CNS3XXX_I2S_TDM_BASE 0x86000000 /* I2S TDM */
+#define CNS3XXX_I2S_TDM_BASE_VIRT 0xFFF1A000
+
+#define CNS3XXX_2DG_BASE 0x87000000 /* 2D Graphic Control */
+#define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000
+
+#define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */
+
+#define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */
+#define CNS3XXX_L2C_BASE_VIRT 0xFFF27000
+
+#define CNS3XXX_PCIE0_MEM_BASE 0xA0000000 /* PCIe Port 0 IO/Memory Space */
+#define CNS3XXX_PCIE0_MEM_BASE_VIRT 0xE0000000
+
+#define CNS3XXX_PCIE0_HOST_BASE 0xAB000000 /* PCIe Port 0 RC Base */
+#define CNS3XXX_PCIE0_HOST_BASE_VIRT 0xE1000000
+
+#define CNS3XXX_PCIE0_IO_BASE 0xAC000000 /* PCIe Port 0 */
+#define CNS3XXX_PCIE0_IO_BASE_VIRT 0xE2000000
+
+#define CNS3XXX_PCIE0_CFG0_BASE 0xAD000000 /* PCIe Port 0 CFG Type 0 */
+#define CNS3XXX_PCIE0_CFG0_BASE_VIRT 0xE3000000
+
+#define CNS3XXX_PCIE0_CFG1_BASE 0xAE000000 /* PCIe Port 0 CFG Type 1 */
+#define CNS3XXX_PCIE0_CFG1_BASE_VIRT 0xE4000000
+
+#define CNS3XXX_PCIE0_MSG_BASE 0xAF000000 /* PCIe Port 0 Message Space */
+#define CNS3XXX_PCIE0_MSG_BASE_VIRT 0xE5000000
+
+#define CNS3XXX_PCIE1_MEM_BASE 0xB0000000 /* PCIe Port 1 IO/Memory Space */
+#define CNS3XXX_PCIE1_MEM_BASE_VIRT 0xE8000000
+
+#define CNS3XXX_PCIE1_HOST_BASE 0xBB000000 /* PCIe Port 1 RC Base */
+#define CNS3XXX_PCIE1_HOST_BASE_VIRT 0xE9000000
+
+#define CNS3XXX_PCIE1_IO_BASE 0xBC000000 /* PCIe Port 1 */
+#define CNS3XXX_PCIE1_IO_BASE_VIRT 0xEA000000
+
+#define CNS3XXX_PCIE1_CFG0_BASE 0xBD000000 /* PCIe Port 1 CFG Type 0 */
+#define CNS3XXX_PCIE1_CFG0_BASE_VIRT 0xEB000000
+
+#define CNS3XXX_PCIE1_CFG1_BASE 0xBE000000 /* PCIe Port 1 CFG Type 1 */
+#define CNS3XXX_PCIE1_CFG1_BASE_VIRT 0xEC000000
+
+#define CNS3XXX_PCIE1_MSG_BASE 0xBF000000 /* PCIe Port 1 Message Space */
+#define CNS3XXX_PCIE1_MSG_BASE_VIRT 0xED000000
+
+/*
+ * Testchip peripheral and fpga gic regions
+ */
+#define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */
+#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000
+
+#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */
+#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100
+
+#define CNS3XXX_TC11MP_TWD_BASE 0x90000600
+#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600
+
+#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */
+#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000
+
+#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */
+#define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000
+
+/*
+ * Misc block
+ */
+#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs))
+
+#define MISC_MEMORY_REMAP_REG MISC_MEM_MAP(0x00)
+#define MISC_CHIP_CONFIG_REG MISC_MEM_MAP(0x04)
+#define MISC_DEBUG_PROBE_DATA_REG MISC_MEM_MAP(0x08)
+#define MISC_DEBUG_PROBE_SELECTION_REG MISC_MEM_MAP(0x0C)
+#define MISC_IO_PIN_FUNC_SELECTION_REG MISC_MEM_MAP(0x10)
+#define MISC_GPIOA_PIN_ENABLE_REG MISC_MEM_MAP(0x14)
+#define MISC_GPIOB_PIN_ENABLE_REG MISC_MEM_MAP(0x18)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A MISC_MEM_MAP(0x1C)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B MISC_MEM_MAP(0x20)
+#define MISC_GPIOA_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x24)
+#define MISC_GPIOA_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x28)
+#define MISC_GPIOB_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x2C)
+#define MISC_GPIOB_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x30)
+#define MISC_IO_PULL_CTRL_REG MISC_MEM_MAP(0x34)
+#define MISC_E_FUSE_31_0_REG MISC_MEM_MAP(0x40)
+#define MISC_E_FUSE_63_32_REG MISC_MEM_MAP(0x44)
+#define MISC_E_FUSE_95_64_REG MISC_MEM_MAP(0x48)
+#define MISC_E_FUSE_127_96_REG MISC_MEM_MAP(0x4C)
+#define MISC_SOFTWARE_TEST_1_REG MISC_MEM_MAP(0x50)
+#define MISC_SOFTWARE_TEST_2_REG MISC_MEM_MAP(0x54)
+
+#define MISC_SATA_POWER_MODE MISC_MEM_MAP(0x310)
+
+#define MISC_USB_CFG_REG MISC_MEM_MAP(0x800)
+#define MISC_USB_STS_REG MISC_MEM_MAP(0x804)
+#define MISC_USBPHY00_CFG_REG MISC_MEM_MAP(0x808)
+#define MISC_USBPHY01_CFG_REG MISC_MEM_MAP(0x80c)
+#define MISC_USBPHY10_CFG_REG MISC_MEM_MAP(0x810)
+#define MISC_USBPHY11_CFG_REG MISC_MEM_MAP(0x814)
+
+#define MISC_PCIEPHY_CMCTL(x) MISC_MEM_MAP(0x900 + (x) * 0x004)
+#define MISC_PCIEPHY_CTL(x) MISC_MEM_MAP(0x940 + (x) * 0x100)
+#define MISC_PCIE_AXIS_AWMISC(x) MISC_MEM_MAP(0x944 + (x) * 0x100)
+#define MISC_PCIE_AXIS_ARMISC(x) MISC_MEM_MAP(0x948 + (x) * 0x100)
+#define MISC_PCIE_AXIS_RMISC(x) MISC_MEM_MAP(0x94C + (x) * 0x100)
+#define MISC_PCIE_AXIS_BMISC(x) MISC_MEM_MAP(0x950 + (x) * 0x100)
+#define MISC_PCIE_AXIM_RMISC(x) MISC_MEM_MAP(0x954 + (x) * 0x100)
+#define MISC_PCIE_AXIM_BMISC(x) MISC_MEM_MAP(0x958 + (x) * 0x100)
+#define MISC_PCIE_CTRL(x) MISC_MEM_MAP(0x95C + (x) * 0x100)
+#define MISC_PCIE_PM_DEBUG(x) MISC_MEM_MAP(0x960 + (x) * 0x100)
+#define MISC_PCIE_RFC_DEBUG(x) MISC_MEM_MAP(0x964 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGL(x) MISC_MEM_MAP(0x968 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGH(x) MISC_MEM_MAP(0x96C + (x) * 0x100)
+#define MISC_PCIE_DIAG_DEBUGH(x) MISC_MEM_MAP(0x970 + (x) * 0x100)
+#define MISC_PCIE_W1CLR(x) MISC_MEM_MAP(0x974 + (x) * 0x100)
+#define MISC_PCIE_INT_MASK(x) MISC_MEM_MAP(0x978 + (x) * 0x100)
+#define MISC_PCIE_INT_STATUS(x) MISC_MEM_MAP(0x97C + (x) * 0x100)
+
+/*
+ * Power management and clock control
+ */
+#define PMU_MEM_MAP(offs) (void __iomem *)(CNS3XXX_PM_BASE_VIRT + (offs))
+
+#define PM_CLK_GATE_REG PMU_MEM_MAP(0x000)
+#define PM_SOFT_RST_REG PMU_MEM_MAP(0x004)
+#define PM_HS_CFG_REG PMU_MEM_MAP(0x008)
+#define PM_CACTIVE_STA_REG PMU_MEM_MAP(0x00C)
+#define PM_PWR_STA_REG PMU_MEM_MAP(0x010)
+#define PM_CLK_CTRL_REG PMU_MEM_MAP(0x014)
+#define PM_PLL_LCD_I2S_CTRL_REG PMU_MEM_MAP(0x018)
+#define PM_PLL_HM_PD_CTRL_REG PMU_MEM_MAP(0x01C)
+#define PM_REGULAT_CTRL_REG PMU_MEM_MAP(0x020)
+#define PM_WDT_CTRL_REG PMU_MEM_MAP(0x024)
+#define PM_WU_CTRL0_REG PMU_MEM_MAP(0x028)
+#define PM_WU_CTRL1_REG PMU_MEM_MAP(0x02C)
+#define PM_CSR_REG PMU_MEM_MAP(0x030)
+
+/* PM_CLK_GATE_REG */
+#define PM_CLK_GATE_REG_OFFSET_SDIO (25)
+#define PM_CLK_GATE_REG_OFFSET_GPU (24)
+#define PM_CLK_GATE_REG_OFFSET_CIM (23)
+#define PM_CLK_GATE_REG_OFFSET_LCDC (22)
+#define PM_CLK_GATE_REG_OFFSET_I2S (21)
+#define PM_CLK_GATE_REG_OFFSET_RAID (20)
+#define PM_CLK_GATE_REG_OFFSET_SATA (19)
+#define PM_CLK_GATE_REG_OFFSET_PCIE(x) (17 + (x))
+#define PM_CLK_GATE_REG_OFFSET_USB_HOST (16)
+#define PM_CLK_GATE_REG_OFFSET_USB_OTG (15)
+#define PM_CLK_GATE_REG_OFFSET_TIMER (14)
+#define PM_CLK_GATE_REG_OFFSET_CRYPTO (13)
+#define PM_CLK_GATE_REG_OFFSET_HCIE (12)
+#define PM_CLK_GATE_REG_OFFSET_SWITCH (11)
+#define PM_CLK_GATE_REG_OFFSET_GPIO (10)
+#define PM_CLK_GATE_REG_OFFSET_UART3 (9)
+#define PM_CLK_GATE_REG_OFFSET_UART2 (8)
+#define PM_CLK_GATE_REG_OFFSET_UART1 (7)
+#define PM_CLK_GATE_REG_OFFSET_RTC (5)
+#define PM_CLK_GATE_REG_OFFSET_GDMA (4)
+#define PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C (3)
+#define PM_CLK_GATE_REG_OFFSET_SMC_NFI (1)
+#define PM_CLK_GATE_REG_MASK (0x03FFFFBA)
+
+/* PM_SOFT_RST_REG */
+#define PM_SOFT_RST_REG_OFFST_WARM_RST_FLAG (31)
+#define PM_SOFT_RST_REG_OFFST_CPU1 (29)
+#define PM_SOFT_RST_REG_OFFST_CPU0 (28)
+#define PM_SOFT_RST_REG_OFFST_SDIO (25)
+#define PM_SOFT_RST_REG_OFFST_GPU (24)
+#define PM_SOFT_RST_REG_OFFST_CIM (23)
+#define PM_SOFT_RST_REG_OFFST_LCDC (22)
+#define PM_SOFT_RST_REG_OFFST_I2S (21)
+#define PM_SOFT_RST_REG_OFFST_RAID (20)
+#define PM_SOFT_RST_REG_OFFST_SATA (19)
+#define PM_SOFT_RST_REG_OFFST_PCIE(x) (17 + (x))
+#define PM_SOFT_RST_REG_OFFST_USB_HOST (16)
+#define PM_SOFT_RST_REG_OFFST_USB_OTG (15)
+#define PM_SOFT_RST_REG_OFFST_TIMER (14)
+#define PM_SOFT_RST_REG_OFFST_CRYPTO (13)
+#define PM_SOFT_RST_REG_OFFST_HCIE (12)
+#define PM_SOFT_RST_REG_OFFST_SWITCH (11)
+#define PM_SOFT_RST_REG_OFFST_GPIO (10)
+#define PM_SOFT_RST_REG_OFFST_UART3 (9)
+#define PM_SOFT_RST_REG_OFFST_UART2 (8)
+#define PM_SOFT_RST_REG_OFFST_UART1 (7)
+#define PM_SOFT_RST_REG_OFFST_RTC (5)
+#define PM_SOFT_RST_REG_OFFST_GDMA (4)
+#define PM_SOFT_RST_REG_OFFST_SPI_PCM_I2C (3)
+#define PM_SOFT_RST_REG_OFFST_DMC (2)
+#define PM_SOFT_RST_REG_OFFST_SMC_NFI (1)
+#define PM_SOFT_RST_REG_OFFST_GLOBAL (0)
+#define PM_SOFT_RST_REG_MASK (0xF3FFFFBF)
+
+/* PMHS_CFG_REG */
+#define PM_HS_CFG_REG_OFFSET_SDIO (25)
+#define PM_HS_CFG_REG_OFFSET_GPU (24)
+#define PM_HS_CFG_REG_OFFSET_CIM (23)
+#define PM_HS_CFG_REG_OFFSET_LCDC (22)
+#define PM_HS_CFG_REG_OFFSET_I2S (21)
+#define PM_HS_CFG_REG_OFFSET_RAID (20)
+#define PM_HS_CFG_REG_OFFSET_SATA (19)
+#define PM_HS_CFG_REG_OFFSET_PCIE1 (18)
+#define PM_HS_CFG_REG_OFFSET_PCIE0 (17)
+#define PM_HS_CFG_REG_OFFSET_USB_HOST (16)
+#define PM_HS_CFG_REG_OFFSET_USB_OTG (15)
+#define PM_HS_CFG_REG_OFFSET_TIMER (14)
+#define PM_HS_CFG_REG_OFFSET_CRYPTO (13)
+#define PM_HS_CFG_REG_OFFSET_HCIE (12)
+#define PM_HS_CFG_REG_OFFSET_SWITCH (11)
+#define PM_HS_CFG_REG_OFFSET_GPIO (10)
+#define PM_HS_CFG_REG_OFFSET_UART3 (9)
+#define PM_HS_CFG_REG_OFFSET_UART2 (8)
+#define PM_HS_CFG_REG_OFFSET_UART1 (7)
+#define PM_HS_CFG_REG_OFFSET_RTC (5)
+#define PM_HS_CFG_REG_OFFSET_GDMA (4)
+#define PM_HS_CFG_REG_OFFSET_SPI_PCM_I2S (3)
+#define PM_HS_CFG_REG_OFFSET_DMC (2)
+#define PM_HS_CFG_REG_OFFSET_SMC_NFI (1)
+#define PM_HS_CFG_REG_MASK (0x03FFFFBE)
+#define PM_HS_CFG_REG_MASK_SUPPORT (0x01100806)
+
+/* PM_CACTIVE_STA_REG */
+#define PM_CACTIVE_STA_REG_OFFSET_SDIO (25)
+#define PM_CACTIVE_STA_REG_OFFSET_GPU (24)
+#define PM_CACTIVE_STA_REG_OFFSET_CIM (23)
+#define PM_CACTIVE_STA_REG_OFFSET_LCDC (22)
+#define PM_CACTIVE_STA_REG_OFFSET_I2S (21)
+#define PM_CACTIVE_STA_REG_OFFSET_RAID (20)
+#define PM_CACTIVE_STA_REG_OFFSET_SATA (19)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE1 (18)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE0 (17)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_HOST (16)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_OTG (15)
+#define PM_CACTIVE_STA_REG_OFFSET_TIMER (14)
+#define PM_CACTIVE_STA_REG_OFFSET_CRYPTO (13)
+#define PM_CACTIVE_STA_REG_OFFSET_HCIE (12)
+#define PM_CACTIVE_STA_REG_OFFSET_SWITCH (11)
+#define PM_CACTIVE_STA_REG_OFFSET_GPIO (10)
+#define PM_CACTIVE_STA_REG_OFFSET_UART3 (9)
+#define PM_CACTIVE_STA_REG_OFFSET_UART2 (8)
+#define PM_CACTIVE_STA_REG_OFFSET_UART1 (7)
+#define PM_CACTIVE_STA_REG_OFFSET_RTC (5)
+#define PM_CACTIVE_STA_REG_OFFSET_GDMA (4)
+#define PM_CACTIVE_STA_REG_OFFSET_SPI_PCM_I2S (3)
+#define PM_CACTIVE_STA_REG_OFFSET_DMC (2)
+#define PM_CACTIVE_STA_REG_OFFSET_SMC_NFI (1)
+#define PM_CACTIVE_STA_REG_MASK (0x03FFFFBE)
+
+/* PM_PWR_STA_REG */
+#define PM_PWR_STA_REG_REG_OFFSET_SDIO (25)
+#define PM_PWR_STA_REG_REG_OFFSET_GPU (24)
+#define PM_PWR_STA_REG_REG_OFFSET_CIM (23)
+#define PM_PWR_STA_REG_REG_OFFSET_LCDC (22)
+#define PM_PWR_STA_REG_REG_OFFSET_I2S (21)
+#define PM_PWR_STA_REG_REG_OFFSET_RAID (20)
+#define PM_PWR_STA_REG_REG_OFFSET_SATA (19)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE1 (18)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE0 (17)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_HOST (16)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_OTG (15)
+#define PM_PWR_STA_REG_REG_OFFSET_TIMER (14)
+#define PM_PWR_STA_REG_REG_OFFSET_CRYPTO (13)
+#define PM_PWR_STA_REG_REG_OFFSET_HCIE (12)
+#define PM_PWR_STA_REG_REG_OFFSET_SWITCH (11)
+#define PM_PWR_STA_REG_REG_OFFSET_GPIO (10)
+#define PM_PWR_STA_REG_REG_OFFSET_UART3 (9)
+#define PM_PWR_STA_REG_REG_OFFSET_UART2 (8)
+#define PM_PWR_STA_REG_REG_OFFSET_UART1 (7)
+#define PM_PWR_STA_REG_REG_OFFSET_RTC (5)
+#define PM_PWR_STA_REG_REG_OFFSET_GDMA (4)
+#define PM_PWR_STA_REG_REG_OFFSET_SPI_PCM_I2S (3)
+#define PM_PWR_STA_REG_REG_OFFSET_DMC (2)
+#define PM_PWR_STA_REG_REG_OFFSET_SMC_NFI (1)
+#define PM_PWR_STA_REG_REG_MASK (0x03FFFFBE)
+
+/* PM_CLK_CTRL_REG */
+#define PM_CLK_CTRL_REG_OFFSET_I2S_MCLK (31)
+#define PM_CLK_CTRL_REG_OFFSET_DDR2_CHG_EN (30)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF1_EN (29)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF0_EN (28)
+#define PM_CLK_CTRL_REG_OFFSET_TIMER_SIM_MODE (27)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_DIV (24)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_SEL (22)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_DIV (20)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_SEL (16)
+#define PM_CLK_CTRL_REG_OFFSET_MDC_DIV (14)
+#define PM_CLK_CTRL_REG_OFFSET_CRYPTO_CLK_SEL (12)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_PWR_MODE (9)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_DDR2_SEL (7)
+#define PM_CLK_CTRL_REG_OFFSET_DIV_IMMEDIATE (6)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV (4)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL (0)
+
+#define PM_CPU_CLK_DIV(DIV) { \
+ PM_CLK_CTRL_REG &= ~((0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+ PM_CLK_CTRL_REG |= (((DIV)&0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+}
+
+#define PM_PLL_CPU_SEL(CPU) { \
+ PM_CLK_CTRL_REG &= ~((0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+ PM_CLK_CTRL_REG |= (((CPU)&0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+}
+
+/* PM_PLL_LCD_I2S_CTRL_REG */
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_MCLK_SMC_DIV (22)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_R_SEL (17)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_P (11)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_M (3)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_S (0)
+
+/* PM_PLL_HM_PD_CTRL_REG */
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1 (11)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0 (10)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2SCD (6)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2S (5)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_LCD (4)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB (3)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_RGMII (2)
+#define PM_PLL_HM_PD_CTRL_REG_MASK (0x00000C7C)
+
+/* PM_WDT_CTRL_REG */
+#define PM_WDT_CTRL_REG_OFFSET_RESET_CPU_ONLY (0)
+
+/* PM_CSR_REG - Clock Scaling Register*/
+#define PM_CSR_REG_OFFSET_CSR_EN (30)
+#define PM_CSR_REG_OFFSET_CSR_NUM (0)
+
+#define CNS3XXX_PWR_CLK_EN(BLOCK) (0x1<<PM_CLK_GATE_REG_OFFSET_##BLOCK)
+
+/* Software reset*/
+#define CNS3XXX_PWR_SOFTWARE_RST(BLOCK) (0x1<<PM_SOFT_RST_REG_OFFST_##BLOCK)
+
+/*
+ * CNS3XXX support several power saving mode as following,
+ * DFS, IDLE, HALT, DOZE, SLEEP, Hibernate
+ */
+#define CNS3XXX_PWR_CPU_MODE_DFS (0)
+#define CNS3XXX_PWR_CPU_MODE_IDLE (1)
+#define CNS3XXX_PWR_CPU_MODE_HALT (2)
+#define CNS3XXX_PWR_CPU_MODE_DOZE (3)
+#define CNS3XXX_PWR_CPU_MODE_SLEEP (4)
+#define CNS3XXX_PWR_CPU_MODE_HIBERNATE (5)
+
+#define CNS3XXX_PWR_PLL(BLOCK) (0x1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_##BLOCK)
+#define CNS3XXX_PWR_PLL_ALL PM_PLL_HM_PD_CTRL_REG_MASK
+
+/* Change CPU frequency and divider */
+#define CNS3XXX_PWR_PLL_CPU_300MHZ (0)
+#define CNS3XXX_PWR_PLL_CPU_333MHZ (1)
+#define CNS3XXX_PWR_PLL_CPU_366MHZ (2)
+#define CNS3XXX_PWR_PLL_CPU_400MHZ (3)
+#define CNS3XXX_PWR_PLL_CPU_433MHZ (4)
+#define CNS3XXX_PWR_PLL_CPU_466MHZ (5)
+#define CNS3XXX_PWR_PLL_CPU_500MHZ (6)
+#define CNS3XXX_PWR_PLL_CPU_533MHZ (7)
+#define CNS3XXX_PWR_PLL_CPU_566MHZ (8)
+#define CNS3XXX_PWR_PLL_CPU_600MHZ (9)
+#define CNS3XXX_PWR_PLL_CPU_633MHZ (10)
+#define CNS3XXX_PWR_PLL_CPU_666MHZ (11)
+#define CNS3XXX_PWR_PLL_CPU_700MHZ (12)
+
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY1 (0)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY2 (1)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY4 (2)
+
+/* Change DDR2 frequency */
+#define CNS3XXX_PWR_PLL_DDR2_200MHZ (0)
+#define CNS3XXX_PWR_PLL_DDR2_266MHZ (1)
+#define CNS3XXX_PWR_PLL_DDR2_333MHZ (2)
+#define CNS3XXX_PWR_PLL_DDR2_400MHZ (3)
+
+void cns3xxx_pwr_soft_rst(unsigned int block);
+void cns3xxx_pwr_clk_en(unsigned int block);
+int cns3xxx_cpu_clock(void);
+
+/*
+ * ARM11 MPCore interrupt sources (primary GIC)
+ */
+#define IRQ_CNS3XXX_PMU (IRQ_TC11MP_GIC_START + 0)
+#define IRQ_CNS3XXX_SDIO (IRQ_TC11MP_GIC_START + 1)
+#define IRQ_CNS3XXX_L2CC (IRQ_TC11MP_GIC_START + 2)
+#define IRQ_CNS3XXX_RTC (IRQ_TC11MP_GIC_START + 3)
+#define IRQ_CNS3XXX_I2S (IRQ_TC11MP_GIC_START + 4)
+#define IRQ_CNS3XXX_PCM (IRQ_TC11MP_GIC_START + 5)
+#define IRQ_CNS3XXX_SPI (IRQ_TC11MP_GIC_START + 6)
+#define IRQ_CNS3XXX_I2C (IRQ_TC11MP_GIC_START + 7)
+#define IRQ_CNS3XXX_CIM (IRQ_TC11MP_GIC_START + 8)
+#define IRQ_CNS3XXX_GPU (IRQ_TC11MP_GIC_START + 9)
+#define IRQ_CNS3XXX_LCD (IRQ_TC11MP_GIC_START + 10)
+#define IRQ_CNS3XXX_GPIOA (IRQ_TC11MP_GIC_START + 11)
+#define IRQ_CNS3XXX_GPIOB (IRQ_TC11MP_GIC_START + 12)
+#define IRQ_CNS3XXX_UART0 (IRQ_TC11MP_GIC_START + 13)
+#define IRQ_CNS3XXX_UART1 (IRQ_TC11MP_GIC_START + 14)
+#define IRQ_CNS3XXX_UART2 (IRQ_TC11MP_GIC_START + 15)
+#define IRQ_CNS3XXX_ARM11 (IRQ_TC11MP_GIC_START + 16)
+
+#define IRQ_CNS3XXX_SW_STATUS (IRQ_TC11MP_GIC_START + 17)
+#define IRQ_CNS3XXX_SW_R0TXC (IRQ_TC11MP_GIC_START + 18)
+#define IRQ_CNS3XXX_SW_R0RXC (IRQ_TC11MP_GIC_START + 19)
+#define IRQ_CNS3XXX_SW_R0QE (IRQ_TC11MP_GIC_START + 20)
+#define IRQ_CNS3XXX_SW_R0QF (IRQ_TC11MP_GIC_START + 21)
+#define IRQ_CNS3XXX_SW_R1TXC (IRQ_TC11MP_GIC_START + 22)
+#define IRQ_CNS3XXX_SW_R1RXC (IRQ_TC11MP_GIC_START + 23)
+#define IRQ_CNS3XXX_SW_R1QE (IRQ_TC11MP_GIC_START + 24)
+#define IRQ_CNS3XXX_SW_R1QF (IRQ_TC11MP_GIC_START + 25)
+#define IRQ_CNS3XXX_SW_PPE (IRQ_TC11MP_GIC_START + 26)
+
+#define IRQ_CNS3XXX_CRYPTO (IRQ_TC11MP_GIC_START + 27)
+#define IRQ_CNS3XXX_HCIE (IRQ_TC11MP_GIC_START + 28)
+#define IRQ_CNS3XXX_PCIE0_DEVICE (IRQ_TC11MP_GIC_START + 29)
+#define IRQ_CNS3XXX_PCIE1_DEVICE (IRQ_TC11MP_GIC_START + 30)
+#define IRQ_CNS3XXX_USB_OTG (IRQ_TC11MP_GIC_START + 31)
+#define IRQ_CNS3XXX_USB_EHCI (IRQ_TC11MP_GIC_START + 32)
+#define IRQ_CNS3XXX_SATA (IRQ_TC11MP_GIC_START + 33)
+#define IRQ_CNS3XXX_RAID (IRQ_TC11MP_GIC_START + 34)
+#define IRQ_CNS3XXX_SMC (IRQ_TC11MP_GIC_START + 35)
+
+#define IRQ_CNS3XXX_DMAC_ABORT (IRQ_TC11MP_GIC_START + 36)
+#define IRQ_CNS3XXX_DMAC0 (IRQ_TC11MP_GIC_START + 37)
+#define IRQ_CNS3XXX_DMAC1 (IRQ_TC11MP_GIC_START + 38)
+#define IRQ_CNS3XXX_DMAC2 (IRQ_TC11MP_GIC_START + 39)
+#define IRQ_CNS3XXX_DMAC3 (IRQ_TC11MP_GIC_START + 40)
+#define IRQ_CNS3XXX_DMAC4 (IRQ_TC11MP_GIC_START + 41)
+#define IRQ_CNS3XXX_DMAC5 (IRQ_TC11MP_GIC_START + 42)
+#define IRQ_CNS3XXX_DMAC6 (IRQ_TC11MP_GIC_START + 43)
+#define IRQ_CNS3XXX_DMAC7 (IRQ_TC11MP_GIC_START + 44)
+#define IRQ_CNS3XXX_DMAC8 (IRQ_TC11MP_GIC_START + 45)
+#define IRQ_CNS3XXX_DMAC9 (IRQ_TC11MP_GIC_START + 46)
+#define IRQ_CNS3XXX_DMAC10 (IRQ_TC11MP_GIC_START + 47)
+#define IRQ_CNS3XXX_DMAC11 (IRQ_TC11MP_GIC_START + 48)
+#define IRQ_CNS3XXX_DMAC12 (IRQ_TC11MP_GIC_START + 49)
+#define IRQ_CNS3XXX_DMAC13 (IRQ_TC11MP_GIC_START + 50)
+#define IRQ_CNS3XXX_DMAC14 (IRQ_TC11MP_GIC_START + 51)
+#define IRQ_CNS3XXX_DMAC15 (IRQ_TC11MP_GIC_START + 52)
+#define IRQ_CNS3XXX_DMAC16 (IRQ_TC11MP_GIC_START + 53)
+#define IRQ_CNS3XXX_DMAC17 (IRQ_TC11MP_GIC_START + 54)
+
+#define IRQ_CNS3XXX_PCIE0_RC (IRQ_TC11MP_GIC_START + 55)
+#define IRQ_CNS3XXX_PCIE1_RC (IRQ_TC11MP_GIC_START + 56)
+#define IRQ_CNS3XXX_TIMER0 (IRQ_TC11MP_GIC_START + 57)
+#define IRQ_CNS3XXX_TIMER1 (IRQ_TC11MP_GIC_START + 58)
+#define IRQ_CNS3XXX_USB_OHCI (IRQ_TC11MP_GIC_START + 59)
+#define IRQ_CNS3XXX_TIMER2 (IRQ_TC11MP_GIC_START + 60)
+#define IRQ_CNS3XXX_EXTERNAL_PIN0 (IRQ_TC11MP_GIC_START + 61)
+#define IRQ_CNS3XXX_EXTERNAL_PIN1 (IRQ_TC11MP_GIC_START + 62)
+#define IRQ_CNS3XXX_EXTERNAL_PIN2 (IRQ_TC11MP_GIC_START + 63)
+
+#define NR_IRQS_CNS3XXX (IRQ_TC11MP_GIC_START + 64)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_CNS3XXX)
+#undef NR_IRQS
+#define NR_IRQS NR_IRQS_CNS3XXX
+#endif
+
+#endif /* __MACH_BOARD_CNS3XXX_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
new file mode 100644
index 00000000..56d82863
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright 1994-1999 Russell King
+ * Copyright 2008 Cavium Networks
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This file 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.
+ */
+
+ .macro addruart,rp,rv
+ mov \rp, #0x00009000
+ orr \rv, \rp, #0xf0000000 @ virtual base
+ orr \rp, \rp, #0x10000000
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
new file mode 100644
index 00000000..6bd83ed9
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
@@ -0,0 +1,18 @@
+/*
+ * Low-level IRQ helper macros for Cavium Networks platforms
+ *
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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/hardware.h>
+#include <asm/hardware/entry-macro-gic.S>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-cns3xxx/include/mach/hardware.h b/arch/arm/mach-cns3xxx/include/mach/hardware.h
new file mode 100644
index 00000000..57e09836
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/hardware.h
@@ -0,0 +1,22 @@
+/*
+ * This file contains the hardware definitions of the Cavium Networks boards.
+ *
+ * Copyright 2003 ARM Limited.
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* macro to get at IO space when running virtually */
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0x00000000
+#define pcibios_assign_all_busses() 1
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/io.h b/arch/arm/mach-cns3xxx/include/mach/io.h
new file mode 100644
index 00000000..33b6fc1e
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/io.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2008 Cavium Networks
+ * Copyright 2003 ARM Limited
+ *
+ * This file 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.
+ */
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/irqs.h b/arch/arm/mach-cns3xxx/include/mach/irqs.h
new file mode 100644
index 00000000..2ab96f80
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/irqs.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define IRQ_LOCALTIMER 29
+#define IRQ_LOCALWDOG 30
+#define IRQ_TC11MP_GIC_START 32
+
+#include <mach/cns3xxx.h>
+
+#ifndef NR_IRQS
+#error "NR_IRQS not defined by the board-specific files"
+#endif
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h
new file mode 100644
index 00000000..dc16c5c5
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/memory.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#define __phys_to_bus(x) ((x) + PHYS_OFFSET)
+#define __bus_to_phys(x) ((x) - PHYS_OFFSET)
+
+#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/pm.h b/arch/arm/mach-cns3xxx/include/mach/pm.h
new file mode 100644
index 00000000..6eae7f76
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/pm.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2004 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#ifndef __CNS3XXX_PM_H
+#define __CNS3XXX_PM_H
+
+#include <asm/atomic.h>
+
+void cns3xxx_pwr_clk_en(unsigned int block);
+void cns3xxx_pwr_clk_dis(unsigned int block);
+void cns3xxx_pwr_power_up(unsigned int block);
+void cns3xxx_pwr_power_down(unsigned int block);
+
+extern atomic_t usb_pwr_ref;
+
+#endif /* __CNS3XXX_PM_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h
new file mode 100644
index 00000000..58bb03ae
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/system.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/timex.h b/arch/arm/mach-cns3xxx/include/mach/timex.h
new file mode 100644
index 00000000..1fd04217
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/timex.h
@@ -0,0 +1,12 @@
+/*
+ * Cavium Networks architecture timex specifications
+ *
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/arch/arm/mach-cns3xxx/include/mach/uncompress.h b/arch/arm/mach-cns3xxx/include/mach/uncompress.h
new file mode 100644
index 00000000..de8ead9b
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/uncompress.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+
+#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18))
+
+/*
+ * Return the UART base address
+ */
+static inline unsigned long get_uart_base(void)
+{
+ if (machine_is_cns3420vb())
+ return CNS3XXX_UART0_BASE;
+ else
+ return 0;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-cns3xxx/include/mach/vmalloc.h b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h
new file mode 100644
index 00000000..4d381ec0
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2000 Russell King.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#define VMALLOC_END 0xd8000000
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
new file mode 100644
index 00000000..78defd71
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -0,0 +1,389 @@
+/*
+ * PCI-E support for CNS3xxx
+ *
+ * Copyright 2008 Cavium Networks
+ * Richard Liu <richard.liu@caviumnetworks.com>
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <asm/mach/map.h>
+#include <mach/cns3xxx.h>
+#include "core.h"
+
+enum cns3xxx_access_type {
+ CNS3XXX_HOST_TYPE = 0,
+ CNS3XXX_CFG0_TYPE,
+ CNS3XXX_CFG1_TYPE,
+ CNS3XXX_NUM_ACCESS_TYPES,
+};
+
+struct cns3xxx_pcie {
+ struct map_desc cfg_bases[CNS3XXX_NUM_ACCESS_TYPES];
+ unsigned int irqs[2];
+ struct resource res_io;
+ struct resource res_mem;
+ struct hw_pci hw_pci;
+
+ bool linked;
+};
+
+static struct cns3xxx_pcie cns3xxx_pcie[]; /* forward decl. */
+
+static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata)
+{
+ struct pci_sys_data *root = sysdata;
+
+ return &cns3xxx_pcie[root->domain];
+}
+
+static struct cns3xxx_pcie *pdev_to_cnspci(struct pci_dev *dev)
+{
+ return sysdata_to_cnspci(dev->sysdata);
+}
+
+static struct cns3xxx_pcie *pbus_to_cnspci(struct pci_bus *bus)
+{
+ return sysdata_to_cnspci(bus->sysdata);
+}
+
+static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus);
+ int busno = bus->number;
+ int slot = PCI_SLOT(devfn);
+ int offset;
+ enum cns3xxx_access_type type;
+ void __iomem *base;
+
+ /* If there is no link, just show the CNS PCI bridge. */
+ if (!cnspci->linked && (busno > 0 || slot > 0))
+ return NULL;
+
+ /*
+ * The CNS PCI bridge doesn't fit into the PCI hierarchy, though
+ * we still want to access it. For this to work, we must place
+ * the first device on the same bus as the CNS PCI bridge.
+ */
+ if (busno == 0) {
+ if (slot > 1)
+ return NULL;
+ type = slot;
+ } else {
+ type = CNS3XXX_CFG1_TYPE;
+ }
+
+ base = (void __iomem *)cnspci->cfg_bases[type].virtual;
+ offset = ((busno & 0xf) << 20) | (devfn << 12) | (where & 0xffc);
+
+ return base + offset;
+}
+
+static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 v;
+ void __iomem *base;
+ u32 mask = (0x1ull << (size * 8)) - 1;
+ int shift = (where % 4) * 8;
+
+ base = cns3xxx_pci_cfg_base(bus, devfn, where);
+ if (!base) {
+ *val = 0xffffffff;
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ v = __raw_readl(base);
+
+ if (bus->number == 0 && devfn == 0 &&
+ (where & 0xffc) == PCI_CLASS_REVISION) {
+ /*
+ * RC's class is 0xb, but Linux PCI driver needs 0x604
+ * for a PCIe bridge. So we must fixup the class code
+ * to 0x604 here.
+ */
+ v &= 0xff;
+ v |= 0x604 << 16;
+ }
+
+ *val = (v >> shift) & mask;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 v;
+ void __iomem *base;
+ u32 mask = (0x1ull << (size * 8)) - 1;
+ int shift = (where % 4) * 8;
+
+ base = cns3xxx_pci_cfg_base(bus, devfn, where);
+ if (!base)
+ return PCIBIOS_SUCCESSFUL;
+
+ v = __raw_readl(base);
+
+ v &= ~(mask << shift);
+ v |= (val & mask) << shift;
+
+ __raw_writel(v, base);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ struct cns3xxx_pcie *cnspci = sysdata_to_cnspci(sys);
+ struct resource *res_io = &cnspci->res_io;
+ struct resource *res_mem = &cnspci->res_mem;
+ struct resource **sysres = sys->resource;
+
+ BUG_ON(request_resource(&iomem_resource, res_io) ||
+ request_resource(&iomem_resource, res_mem));
+
+ sysres[0] = res_io;
+ sysres[1] = res_mem;
+
+ return 1;
+}
+
+static struct pci_ops cns3xxx_pcie_ops = {
+ .read = cns3xxx_pci_read_config,
+ .write = cns3xxx_pci_write_config,
+};
+
+static struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &cns3xxx_pcie_ops, sys);
+}
+
+static int cns3xxx_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev);
+ int irq = cnspci->irqs[slot];
+
+ pr_info("PCIe map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n",
+ pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn), slot, pin, irq);
+
+ return irq;
+}
+
+static struct cns3xxx_pcie cns3xxx_pcie[] = {
+ [0] = {
+ .cfg_bases = {
+ [CNS3XXX_HOST_TYPE] = {
+ .virtual = CNS3XXX_PCIE0_HOST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_HOST_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG0_TYPE] = {
+ .virtual = CNS3XXX_PCIE0_CFG0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG0_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG1_TYPE] = {
+ .virtual = CNS3XXX_PCIE0_CFG1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ },
+ .res_io = {
+ .name = "PCIe0 I/O space",
+ .start = CNS3XXX_PCIE0_IO_BASE,
+ .end = CNS3XXX_PCIE0_IO_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_IO,
+ },
+ .res_mem = {
+ .name = "PCIe0 non-prefetchable",
+ .start = CNS3XXX_PCIE0_MEM_BASE,
+ .end = CNS3XXX_PCIE0_MEM_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, },
+ .hw_pci = {
+ .domain = 0,
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = cns3xxx_pci_setup,
+ .scan = cns3xxx_pci_scan_bus,
+ .map_irq = cns3xxx_pcie_map_irq,
+ },
+ },
+ [1] = {
+ .cfg_bases = {
+ [CNS3XXX_HOST_TYPE] = {
+ .virtual = CNS3XXX_PCIE1_HOST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_HOST_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG0_TYPE] = {
+ .virtual = CNS3XXX_PCIE1_CFG0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG0_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG1_TYPE] = {
+ .virtual = CNS3XXX_PCIE1_CFG1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ },
+ .res_io = {
+ .name = "PCIe1 I/O space",
+ .start = CNS3XXX_PCIE1_IO_BASE,
+ .end = CNS3XXX_PCIE1_IO_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_IO,
+ },
+ .res_mem = {
+ .name = "PCIe1 non-prefetchable",
+ .start = CNS3XXX_PCIE1_MEM_BASE,
+ .end = CNS3XXX_PCIE1_MEM_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, },
+ .hw_pci = {
+ .domain = 1,
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = cns3xxx_pci_setup,
+ .scan = cns3xxx_pci_scan_bus,
+ .map_irq = cns3xxx_pcie_map_irq,
+ },
+ },
+};
+
+static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
+{
+ int port = cnspci->hw_pci.domain;
+ u32 reg;
+ unsigned long time;
+
+ reg = __raw_readl(MISC_PCIE_CTRL(port));
+ /*
+ * Enable Application Request to 1, it will exit L1 automatically,
+ * but when chip back, it will use another clock, still can use 0x1.
+ */
+ reg |= 0x3;
+ __raw_writel(reg, MISC_PCIE_CTRL(port));
+
+ pr_info("PCIe: Port[%d] Enable PCIe LTSSM\n", port);
+ pr_info("PCIe: Port[%d] Check data link layer...", port);
+
+ time = jiffies;
+ while (1) {
+ reg = __raw_readl(MISC_PCIE_PM_DEBUG(port));
+ if (reg & 0x1) {
+ pr_info("Link up.\n");
+ cnspci->linked = 1;
+ break;
+ } else if (time_after(jiffies, time + 50)) {
+ pr_info("Device not found.\n");
+ break;
+ }
+ }
+}
+
+static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
+{
+ int port = cnspci->hw_pci.domain;
+ struct pci_sys_data sd = {
+ .domain = port,
+ };
+ struct pci_bus bus = {
+ .number = 0,
+ .ops = &cns3xxx_pcie_ops,
+ .sysdata = &sd,
+ };
+ u32 io_base = cnspci->res_io.start >> 16;
+ u32 mem_base = cnspci->res_mem.start >> 16;
+ u32 host_base = cnspci->cfg_bases[CNS3XXX_HOST_TYPE].pfn;
+ u32 cfg0_base = cnspci->cfg_bases[CNS3XXX_CFG0_TYPE].pfn;
+ u32 devfn = 0;
+ u8 tmp8;
+ u16 pos;
+ u16 dc;
+
+ host_base = (__pfn_to_phys(host_base) - 1) >> 16;
+ cfg0_base = (__pfn_to_phys(cfg0_base) - 1) >> 16;
+
+ pci_bus_write_config_byte(&bus, devfn, PCI_PRIMARY_BUS, 0);
+ pci_bus_write_config_byte(&bus, devfn, PCI_SECONDARY_BUS, 1);
+ pci_bus_write_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, 1);
+
+ pci_bus_read_config_byte(&bus, devfn, PCI_PRIMARY_BUS, &tmp8);
+ pci_bus_read_config_byte(&bus, devfn, PCI_SECONDARY_BUS, &tmp8);
+ pci_bus_read_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, &tmp8);
+
+ pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_BASE, mem_base);
+ pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, host_base);
+ pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base);
+ pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, cfg0_base);
+
+ if (!cnspci->linked)
+ return;
+
+ /* Set Device Max_Read_Request_Size to 128 byte */
+ devfn = PCI_DEVFN(1, 0);
+ pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
+ pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
+ dc &= ~(0x3 << 12); /* Clear Device Control Register [14:12] */
+ pci_bus_write_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, dc);
+ pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
+ if (!(dc & (0x3 << 12)))
+ pr_info("PCIe: Set Device Max_Read_Request_Size to 128 byte\n");
+
+ /* Disable PCIe0 Interrupt Mask INTA to INTD */
+ __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(port));
+}
+
+static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+ return 0;
+}
+
+static int __init cns3xxx_pcie_init(void)
+{
+ int i;
+
+ hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0,
+ "imprecise external abort");
+
+ for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
+ iotable_init(cns3xxx_pcie[i].cfg_bases,
+ ARRAY_SIZE(cns3xxx_pcie[i].cfg_bases));
+ cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE(i));
+ cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i));
+ cns3xxx_pcie_check_link(&cns3xxx_pcie[i]);
+ cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]);
+ pci_common_init(&cns3xxx_pcie[i].hw_pci);
+ }
+
+ pci_assign_unassigned_resources();
+
+ return 0;
+}
+device_initcall(cns3xxx_pcie_init);
diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c
new file mode 100644
index 00000000..5e579552
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/pm.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <asm/atomic.h>
+#include <mach/system.h>
+#include <mach/cns3xxx.h>
+#include <mach/pm.h>
+
+void cns3xxx_pwr_clk_en(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_CLK_GATE_REG);
+
+ reg |= (block & PM_CLK_GATE_REG_MASK);
+ __raw_writel(reg, PM_CLK_GATE_REG);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_clk_en);
+
+void cns3xxx_pwr_clk_dis(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_CLK_GATE_REG);
+
+ reg &= ~(block & PM_CLK_GATE_REG_MASK);
+ __raw_writel(reg, PM_CLK_GATE_REG);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_clk_dis);
+
+void cns3xxx_pwr_power_up(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_PLL_HM_PD_CTRL_REG);
+
+ reg &= ~(block & CNS3XXX_PWR_PLL_ALL);
+ __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG);
+
+ /* Wait for 300us for the PLL output clock locked. */
+ udelay(300);
+};
+EXPORT_SYMBOL(cns3xxx_pwr_power_up);
+
+void cns3xxx_pwr_power_down(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_PLL_HM_PD_CTRL_REG);
+
+ /* write '1' to power down */
+ reg |= (block & CNS3XXX_PWR_PLL_ALL);
+ __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG);
+};
+EXPORT_SYMBOL(cns3xxx_pwr_power_down);
+
+static void cns3xxx_pwr_soft_rst_force(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_SOFT_RST_REG);
+
+ /*
+ * bit 0, 28, 29 => program low to reset,
+ * the other else program low and then high
+ */
+ if (block & 0x30000001) {
+ reg &= ~(block & PM_SOFT_RST_REG_MASK);
+ } else {
+ reg &= ~(block & PM_SOFT_RST_REG_MASK);
+ __raw_writel(reg, PM_SOFT_RST_REG);
+ reg |= (block & PM_SOFT_RST_REG_MASK);
+ }
+
+ __raw_writel(reg, PM_SOFT_RST_REG);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_soft_rst_force);
+
+void cns3xxx_pwr_soft_rst(unsigned int block)
+{
+ static unsigned int soft_reset;
+
+ if (soft_reset & block) {
+ /* SPI/I2C/GPIO use the same block, reset once. */
+ return;
+ } else {
+ soft_reset |= block;
+ }
+ cns3xxx_pwr_soft_rst_force(block);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_soft_rst);
+
+void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA.
+ */
+ cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(GLOBAL));
+}
+
+/*
+ * cns3xxx_cpu_clock - return CPU/L2 clock
+ * aclk: cpu clock/2
+ * hclk: cpu clock/4
+ * pclk: cpu clock/8
+ */
+int cns3xxx_cpu_clock(void)
+{
+ u32 reg = __raw_readl(PM_CLK_CTRL_REG);
+ int cpu;
+ int cpu_sel;
+ int div_sel;
+
+ cpu_sel = (reg >> PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL) & 0xf;
+ div_sel = (reg >> PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV) & 0x3;
+
+ cpu = (300 + ((cpu_sel / 3) * 100) + ((cpu_sel % 3) * 33)) >> div_sel;
+
+ return cpu;
+}
+EXPORT_SYMBOL(cns3xxx_cpu_clock);
+
+atomic_t usb_pwr_ref = ATOMIC_INIT(0);
+EXPORT_SYMBOL(usb_pwr_ref);