diff options
Diffstat (limited to 'arch/arm/mach-kirkwood')
39 files changed, 3524 insertions, 1094 deletions
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 3600cd9f051..df4b26340ae 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -2,24 +2,110 @@ if ARCH_KIRKWOOD menu "Marvell Kirkwood Implementations" -config MACH_DB88F6281_BP - bool "Marvell DB-88F6281-BP Development Board" +config KIRKWOOD_LEGACY + bool + +config MACH_D2NET_V2 + bool "LaCie d2 Network v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie d2 Network v2 NAS. + +config MACH_NET2BIG_V2 + bool "LaCie 2Big Network v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie 2Big Network v2 NAS. + +config MACH_NET5BIG_V2 + bool "LaCie 5Big Network v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie 5Big Network v2 NAS. + +config MACH_OPENRD + select KIRKWOOD_LEGACY + bool + +config MACH_OPENRD_BASE + bool "Marvell OpenRD Base Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Base Board. + +config MACH_OPENRD_CLIENT + bool "Marvell OpenRD Client Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Client Board. + +config MACH_OPENRD_ULTIMATE + bool "Marvell OpenRD Ultimate Board" + select MACH_OPENRD help Say 'Y' here if you want your kernel to support the - Marvell DB-88F6281-BP Development Board. + Marvell OpenRD Ultimate Board. config MACH_RD88F6192_NAS bool "Marvell RD-88F6192-NAS Reference Board" + select KIRKWOOD_LEGACY help Say 'Y' here if you want your kernel to support the Marvell RD-88F6192-NAS Reference Board. config MACH_RD88F6281 bool "Marvell RD-88F6281 Reference Board" + select KIRKWOOD_LEGACY help Say 'Y' here if you want your kernel to support the Marvell RD-88F6281 Reference Board. +config MACH_T5325 + bool "HP t5325 Thin Client" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + HP t5325 Thin Client. + +config MACH_TS219 + bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and + TS-219P+ Turbo NAS devices. + +config MACH_TS41X + bool "QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo NAS" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo + NAS devices. + +comment "Device tree entries" + +config ARCH_KIRKWOOD_DT + bool "Marvell Kirkwood Flattened Device Tree" + select KIRKWOOD_CLK + select OF_IRQ + select ORION_IRQCHIP + select ORION_TIMER + select POWER_SUPPLY + select POWER_RESET + select POWER_RESET_GPIO + select REGULATOR + select REGULATOR_FIXED_VOLTAGE + select USE_OF + help + Say 'Y' here if you want your kernel to support the + Marvell Kirkwood using flattened device tree. + endmenu endif diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index b96c55dad34..3a72c5c6e74 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -1,5 +1,14 @@ -obj-y += common.o addr-map.o irq.o pcie.o +obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o common.o pcie.o +obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o +obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o +obj-$(CONFIG_MACH_T5325) += t5325-setup.o +obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o +obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o + +obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot index 67039c3e0c4..760a0efe758 100644 --- a/arch/arm/mach-kirkwood/Makefile.boot +++ b/arch/arm/mach-kirkwood/Makefile.boot @@ -1,3 +1,3 @@ - zreladdr-y := 0x00008000 + zreladdr-y += 0x00008000 params_phys-y := 0x00000100 initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c deleted file mode 100644 index 5db4f0bbe5e..00000000000 --- a/arch/arm/mach-kirkwood/addr-map.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * arch/arm/mach-kirkwood/addr-map.c - * - * Address map functions for Marvell Kirkwood SoCs - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/mbus.h> -#include <linux/io.h> -#include <mach/hardware.h> -#include "common.h" - -/* - * Generic Address Decode Windows bit settings - */ -#define TARGET_DDR 0 -#define TARGET_DEV_BUS 1 -#define TARGET_PCIE 4 -#define ATTR_DEV_SPI_ROM 0x1e -#define ATTR_DEV_BOOT 0x1d -#define ATTR_DEV_NAND 0x2f -#define ATTR_DEV_CS3 0x37 -#define ATTR_DEV_CS2 0x3b -#define ATTR_DEV_CS1 0x3d -#define ATTR_DEV_CS0 0x3e -#define ATTR_PCIE_IO 0xe0 -#define ATTR_PCIE_MEM 0xe8 - -/* - * Helpers to get DDR bank info - */ -#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) -#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) - -/* - * CPU Address Decode Windows registers - */ -#define WIN_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) -#define WIN_CTRL_OFF 0x0000 -#define WIN_BASE_OFF 0x0004 -#define WIN_REMAP_LO_OFF 0x0008 -#define WIN_REMAP_HI_OFF 0x000c - - -struct mbus_dram_target_info kirkwood_mbus_dram_info; -static int __initdata win_alloc_count; - -static int __init 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) -{ - void __iomem *addr = (void __iomem *)WIN_OFF(win); - u32 ctrl; - - base &= 0xffff0000; - ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; - - writel(base, addr + WIN_BASE_OFF); - writel(ctrl, addr + WIN_CTRL_OFF); - if (cpu_win_can_remap(win)) { - if (remap < 0) - remap = base; - - writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF); - writel(0, addr + WIN_REMAP_HI_OFF); - } -} - -void __init kirkwood_setup_cpu_mbus(void) -{ - void __iomem *addr; - int i; - int cs; - - /* - * First, disable and clear windows. - */ - for (i = 0; i < 8; i++) { - addr = (void __iomem *)WIN_OFF(i); - - writel(0, addr + WIN_BASE_OFF); - writel(0, addr + WIN_CTRL_OFF); - if (cpu_win_can_remap(i)) { - writel(0, addr + WIN_REMAP_LO_OFF); - writel(0, addr + WIN_REMAP_HI_OFF); - } - } - - /* - * Setup windows for PCIe IO+MEM space. - */ - setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, - TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); - setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, - TARGET_PCIE, ATTR_PCIE_MEM, -1); - - /* - * Setup window for NAND controller. - */ - setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, - TARGET_DEV_BUS, ATTR_DEV_NAND, -1); - - win_alloc_count = 3; - - /* - * Setup MBUS dram target info. - */ - kirkwood_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; - - addr = (void __iomem *)DDR_WINDOW_CPU_BASE; - - for (i = 0, cs = 0; i < 4; i++) { - u32 base = readl(addr + DDR_BASE_CS_OFF(i)); - u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); - - /* - * Chip select enabled? - */ - if (size & 1) { - struct mbus_dram_window *w; - - w = &kirkwood_mbus_dram_info.cs[cs++]; - w->cs_index = i; - w->mbus_attr = 0xf & ~(1 << i); - w->base = base & 0xffff0000; - w->size = (size | 0x0000ffff) + 1; - } - } - kirkwood_mbus_dram_info.num_cs = cs; -} - -void __init kirkwood_setup_sram_win(u32 base, u32 size) -{ - setup_cpu_win(win_alloc_count++, base, size, 0x03, 0x00, -1); -} diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c new file mode 100644 index 00000000000..ff18ff20f71 --- /dev/null +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -0,0 +1,223 @@ +/* + * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net> + * + * arch/arm/mach-kirkwood/board-dt.c + * + * Flattened Device Tree board initialization + * + * 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/clk.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_net.h> +#include <linux/of_platform.h> +#include <linux/dma-mapping.h> +#include <linux/irqchip.h> +#include <asm/hardware/cache-feroceon-l2.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/bridge-regs.h> +#include <plat/common.h> +#include <plat/pcie.h> +#include "pm.h" + +static struct map_desc kirkwood_io_desc[] __initdata = { + { + .virtual = (unsigned long) KIRKWOOD_REGS_VIRT_BASE, + .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE), + .length = KIRKWOOD_REGS_SIZE, + .type = MT_DEVICE, + }, +}; + +static void __init kirkwood_map_io(void) +{ + iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); +} + +static struct resource kirkwood_cpufreq_resources[] = { + [0] = { + .start = CPU_CONTROL_PHYS, + .end = CPU_CONTROL_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device kirkwood_cpufreq_device = { + .name = "kirkwood-cpufreq", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources), + .resource = kirkwood_cpufreq_resources, +}; + +static void __init kirkwood_cpufreq_init(void) +{ + platform_device_register(&kirkwood_cpufreq_device); +} + +static struct resource kirkwood_cpuidle_resource[] = { + { + .flags = IORESOURCE_MEM, + .start = DDR_OPERATION_BASE, + .end = DDR_OPERATION_BASE + 3, + }, +}; + +static struct platform_device kirkwood_cpuidle = { + .name = "kirkwood_cpuidle", + .id = -1, + .resource = kirkwood_cpuidle_resource, + .num_resources = 1, +}; + +static void __init kirkwood_cpuidle_init(void) +{ + platform_device_register(&kirkwood_cpuidle); +} + +/* Temporary here since mach-mvebu has a function we can use */ +static void kirkwood_restart(enum reboot_mode 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) + ; +} + +#define MV643XX_ETH_MAC_ADDR_LOW 0x0414 +#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418 + +static void __init kirkwood_dt_eth_fixup(void) +{ + struct device_node *np; + + /* + * The ethernet interfaces forget the MAC address assigned by u-boot + * if the clocks are turned off. Usually, u-boot on kirkwood boards + * has no DT support to properly set local-mac-address property. + * As a workaround, we get the MAC address from mv643xx_eth registers + * and update the port device node if no valid MAC address is set. + */ + for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") { + struct device_node *pnp = of_get_parent(np); + struct clk *clk; + struct property *pmac; + void __iomem *io; + u8 *macaddr; + u32 reg; + + if (!pnp) + continue; + + /* skip disabled nodes or nodes with valid MAC address*/ + if (!of_device_is_available(pnp) || of_get_mac_address(np)) + goto eth_fixup_skip; + + clk = of_clk_get(pnp, 0); + if (IS_ERR(clk)) + goto eth_fixup_skip; + + io = of_iomap(pnp, 0); + if (!io) + goto eth_fixup_no_map; + + /* ensure port clock is not gated to not hang CPU */ + clk_prepare_enable(clk); + + /* store MAC address register contents in local-mac-address */ + pr_err(FW_INFO "%s: local-mac-address is not set\n", + np->full_name); + + pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL); + if (!pmac) + goto eth_fixup_no_mem; + + pmac->value = pmac + 1; + pmac->length = 6; + pmac->name = kstrdup("local-mac-address", GFP_KERNEL); + if (!pmac->name) { + kfree(pmac); + goto eth_fixup_no_mem; + } + + macaddr = pmac->value; + reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH); + macaddr[0] = (reg >> 24) & 0xff; + macaddr[1] = (reg >> 16) & 0xff; + macaddr[2] = (reg >> 8) & 0xff; + macaddr[3] = reg & 0xff; + + reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW); + macaddr[4] = (reg >> 8) & 0xff; + macaddr[5] = reg & 0xff; + + of_update_property(np, pmac); + +eth_fixup_no_mem: + iounmap(io); + clk_disable_unprepare(clk); +eth_fixup_no_map: + clk_put(clk); +eth_fixup_skip: + of_node_put(pnp); + } +} + +/* + * Disable propagation of mbus errors to the CPU local bus, as this + * causes mbus errors (which can occur for example for PCI aborts) to + * throw CPU aborts, which we're not set up to deal with. + */ +static void __init kirkwood_disable_mbus_error_propagation(void) +{ + void __iomem *cpu_config; + + cpu_config = ioremap(CPU_CONFIG_PHYS, 4); + writel(readl(cpu_config) & ~CPU_CONFIG_ERROR_PROP, cpu_config); + iounmap(cpu_config); +} + +static void __init kirkwood_dt_init(void) +{ + kirkwood_disable_mbus_error_propagation(); + + BUG_ON(mvebu_mbus_dt_init(false)); + +#ifdef CONFIG_CACHE_FEROCEON_L2 + feroceon_of_init(); +#endif + kirkwood_cpufreq_init(); + kirkwood_cpuidle_init(); + + kirkwood_pm_init(); + kirkwood_dt_eth_fixup(); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char * const kirkwood_dt_board_compat[] = { + "marvell,kirkwood", + NULL +}; + +DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") + /* Maintainer: Jason Cooper <jason@lakedaemon.net> */ + .map_io = kirkwood_map_io, + .init_machine = kirkwood_dt_init, + .restart = kirkwood_restart, + .dt_compat = kirkwood_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index b3404b7775b..255f33a3903 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -12,34 +12,44 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/serial_8250.h> -#include <linux/mbus.h> -#include <linux/mv643xx_eth.h> #include <linux/ata_platform.h> -#include <linux/spi/orion_spi.h> +#include <linux/mtd/nand.h> +#include <linux/dma-mapping.h> +#include <linux/clk-provider.h> +#include <linux/spinlock.h> +#include <linux/mv643xx_i2c.h> +#include <linux/timex.h> +#include <linux/kexec.h> +#include <linux/reboot.h> #include <net/dsa.h> #include <asm/page.h> -#include <asm/timex.h> #include <asm/mach/map.h> #include <asm/mach/time.h> +#include <asm/hardware/cache-feroceon-l2.h> #include <mach/kirkwood.h> -#include <plat/cache-feroceon-l2.h> -#include <plat/ehci-orion.h> -#include <plat/mv_xor.h> -#include <plat/orion_nand.h> +#include <mach/bridge-regs.h> +#include <linux/platform_data/asoc-kirkwood.h> +#include <linux/platform_data/mmc-mvsdio.h> +#include <linux/platform_data/mtd-orion_nand.h> +#include <linux/platform_data/usb-ehci-orion.h> +#include <plat/common.h> #include <plat/time.h> +#include <linux/platform_data/dma-mv_xor.h> #include "common.h" +#include "pm.h" + +/* These can go away once Kirkwood uses the mvebu-mbus DT binding */ +#define KIRKWOOD_MBUS_NAND_TARGET 0x01 +#define KIRKWOOD_MBUS_NAND_ATTR 0x2f +#define KIRKWOOD_MBUS_SRAM_TARGET 0x03 +#define KIRKWOOD_MBUS_SRAM_ATTR 0x01 /***************************************************************************** * I/O Address Mapping ****************************************************************************/ static struct map_desc kirkwood_io_desc[] __initdata = { { - .virtual = KIRKWOOD_PCIE_IO_VIRT_BASE, - .pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE), - .length = KIRKWOOD_PCIE_IO_SIZE, - .type = MT_DEVICE, - }, { - .virtual = KIRKWOOD_REGS_VIRT_BASE, + .virtual = (unsigned long) KIRKWOOD_REGS_VIRT_BASE, .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE), .length = KIRKWOOD_REGS_SIZE, .type = MT_DEVICE, @@ -51,608 +61,570 @@ void __init kirkwood_map_io(void) iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); } - /***************************************************************************** - * EHCI + * CLK tree ****************************************************************************/ -static struct orion_ehci_data kirkwood_ehci_data = { - .dram = &kirkwood_mbus_dram_info, - .phy_version = EHCI_PHY_NA, -}; -static u64 ehci_dmamask = 0xffffffffUL; +static void enable_sata0(void) +{ + /* Enable PLL and IVREF */ + writel(readl(SATA0_PHY_MODE_2) | 0xf, SATA0_PHY_MODE_2); + /* Enable PHY */ + writel(readl(SATA0_IF_CTRL) & ~0x200, SATA0_IF_CTRL); +} +static void disable_sata0(void) +{ + /* Disable PLL and IVREF */ + writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); + /* Disable PHY */ + writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); +} -/***************************************************************************** - * EHCI0 - ****************************************************************************/ -static struct resource kirkwood_ehci_resources[] = { - { - .start = USB_PHYS_BASE, - .end = USB_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_KIRKWOOD_USB, - .end = IRQ_KIRKWOOD_USB, - .flags = IORESOURCE_IRQ, - }, -}; +static void enable_sata1(void) +{ + /* Enable PLL and IVREF */ + writel(readl(SATA1_PHY_MODE_2) | 0xf, SATA1_PHY_MODE_2); + /* Enable PHY */ + writel(readl(SATA1_IF_CTRL) & ~0x200, SATA1_IF_CTRL); +} -static struct platform_device kirkwood_ehci = { - .name = "orion-ehci", - .id = 0, - .dev = { - .dma_mask = &ehci_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &kirkwood_ehci_data, - }, - .resource = kirkwood_ehci_resources, - .num_resources = ARRAY_SIZE(kirkwood_ehci_resources), -}; +static void disable_sata1(void) +{ + /* Disable PLL and IVREF */ + writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); + /* Disable PHY */ + writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); +} -void __init kirkwood_ehci_init(void) +static void disable_pcie0(void) { - platform_device_register(&kirkwood_ehci); + writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); + while (1) + if (readl(PCIE_STATUS) & 0x1) + break; + writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); } +static void disable_pcie1(void) +{ + u32 dev, rev; -/***************************************************************************** - * GE00 - ****************************************************************************/ -struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = { - .dram = &kirkwood_mbus_dram_info, -}; + kirkwood_pcie_id(&dev, &rev); -static struct resource kirkwood_ge00_shared_resources[] = { - { - .name = "ge00 base", - .start = GE00_PHYS_BASE + 0x2000, - .end = GE00_PHYS_BASE + 0x3fff, - .flags = IORESOURCE_MEM, - }, { - .name = "ge00 err irq", - .start = IRQ_KIRKWOOD_GE00_ERR, - .end = IRQ_KIRKWOOD_GE00_ERR, - .flags = IORESOURCE_IRQ, - }, -}; + if (dev == MV88F6282_DEV_ID) { + writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); + while (1) + if (readl(PCIE1_STATUS) & 0x1) + break; + writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); + } +} -static struct platform_device kirkwood_ge00_shared = { - .name = MV643XX_ETH_SHARED_NAME, - .id = 0, - .dev = { - .platform_data = &kirkwood_ge00_shared_data, - }, - .num_resources = ARRAY_SIZE(kirkwood_ge00_shared_resources), - .resource = kirkwood_ge00_shared_resources, +/* An extended version of the gated clk. This calls fn_en()/fn_dis + * before enabling/disabling the clock. We use this to turn on/off + * PHYs etc. */ +struct clk_gate_fn { + struct clk_gate gate; + void (*fn_en)(void); + void (*fn_dis)(void); }; -static struct resource kirkwood_ge00_resources[] = { - { - .name = "ge00 irq", - .start = IRQ_KIRKWOOD_GE00_SUM, - .end = IRQ_KIRKWOOD_GE00_SUM, - .flags = IORESOURCE_IRQ, - }, -}; +#define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) +#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) -static struct platform_device kirkwood_ge00 = { - .name = MV643XX_ETH_NAME, - .id = 0, - .num_resources = 1, - .resource = kirkwood_ge00_resources, -}; +static int clk_gate_fn_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); + int ret; -void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) + ret = clk_gate_ops.enable(hw); + if (!ret && gate_fn->fn_en) + gate_fn->fn_en(); + + return ret; +} + +static void clk_gate_fn_disable(struct clk_hw *hw) { - eth_data->shared = &kirkwood_ge00_shared; - kirkwood_ge00.dev.platform_data = eth_data; + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); - platform_device_register(&kirkwood_ge00_shared); - platform_device_register(&kirkwood_ge00); + if (gate_fn->fn_dis) + gate_fn->fn_dis(); + + clk_gate_ops.disable(hw); } +static struct clk_ops clk_gate_fn_ops; -/***************************************************************************** - * GE01 - ****************************************************************************/ -struct mv643xx_eth_shared_platform_data kirkwood_ge01_shared_data = { - .dram = &kirkwood_mbus_dram_info, - .shared_smi = &kirkwood_ge00_shared, -}; +static struct clk __init *clk_register_gate_fn(struct device *dev, + const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock, + void (*fn_en)(void), void (*fn_dis)(void)) +{ + struct clk_gate_fn *gate_fn; + struct clk *clk; + struct clk_init_data init; + + gate_fn = kzalloc(sizeof(struct clk_gate_fn), GFP_KERNEL); + if (!gate_fn) { + pr_err("%s: could not allocate gated clk\n", __func__); + return ERR_PTR(-ENOMEM); + } -static struct resource kirkwood_ge01_shared_resources[] = { - { - .name = "ge01 base", - .start = GE01_PHYS_BASE + 0x2000, - .end = GE01_PHYS_BASE + 0x3fff, - .flags = IORESOURCE_MEM, - }, { - .name = "ge01 err irq", - .start = IRQ_KIRKWOOD_GE01_ERR, - .end = IRQ_KIRKWOOD_GE01_ERR, - .flags = IORESOURCE_IRQ, - }, -}; + init.name = name; + init.ops = &clk_gate_fn_ops; + init.flags = flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + /* struct clk_gate assignments */ + gate_fn->gate.reg = reg; + gate_fn->gate.bit_idx = bit_idx; + gate_fn->gate.flags = clk_gate_flags; + gate_fn->gate.lock = lock; + gate_fn->gate.hw.init = &init; + gate_fn->fn_en = fn_en; + gate_fn->fn_dis = fn_dis; + + /* ops is the gate ops, but with our enable/disable functions */ + if (clk_gate_fn_ops.enable != clk_gate_fn_enable || + clk_gate_fn_ops.disable != clk_gate_fn_disable) { + clk_gate_fn_ops = clk_gate_ops; + clk_gate_fn_ops.enable = clk_gate_fn_enable; + clk_gate_fn_ops.disable = clk_gate_fn_disable; + } -static struct platform_device kirkwood_ge01_shared = { - .name = MV643XX_ETH_SHARED_NAME, - .id = 1, - .dev = { - .platform_data = &kirkwood_ge01_shared_data, - }, - .num_resources = ARRAY_SIZE(kirkwood_ge01_shared_resources), - .resource = kirkwood_ge01_shared_resources, -}; + clk = clk_register(dev, &gate_fn->gate.hw); -static struct resource kirkwood_ge01_resources[] = { - { - .name = "ge01 irq", - .start = IRQ_KIRKWOOD_GE01_SUM, - .end = IRQ_KIRKWOOD_GE01_SUM, - .flags = IORESOURCE_IRQ, - }, -}; + if (IS_ERR(clk)) + kfree(gate_fn); -static struct platform_device kirkwood_ge01 = { - .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = 1, - .resource = kirkwood_ge01_resources, -}; + return clk; +} -void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) +static DEFINE_SPINLOCK(gating_lock); +static struct clk *tclk; + +static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) { - eth_data->shared = &kirkwood_ge01_shared; - kirkwood_ge01.dev.platform_data = eth_data; + return clk_register_gate(NULL, name, "tclk", 0, CLOCK_GATING_CTRL, + bit_idx, 0, &gating_lock); +} - platform_device_register(&kirkwood_ge01_shared); - platform_device_register(&kirkwood_ge01); +static struct clk __init *kirkwood_register_gate_fn(const char *name, + u8 bit_idx, + void (*fn_en)(void), + void (*fn_dis)(void)) +{ + return clk_register_gate_fn(NULL, name, "tclk", 0, CLOCK_GATING_CTRL, + bit_idx, 0, &gating_lock, fn_en, fn_dis); } +static struct clk *ge0, *ge1; + +void __init kirkwood_clk_init(void) +{ + struct clk *runit, *sata0, *sata1, *usb0, *sdio; + struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; + + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, + CLK_IS_ROOT, kirkwood_tclk); + + runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); + ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); + ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); + sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, + enable_sata0, disable_sata0); + sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, + enable_sata1, disable_sata1); + usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); + sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); + crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); + xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); + xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); + pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, + NULL, disable_pcie0); + pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, + NULL, disable_pcie1); + audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); + kirkwood_register_gate("tdm", CGC_BIT_TDM); + kirkwood_register_gate("tsu", CGC_BIT_TSU); + + /* clkdev entries, mapping clks to devices */ + orion_clkdev_add(NULL, "orion_spi.0", runit); + orion_clkdev_add(NULL, "orion_spi.1", runit); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); + orion_clkdev_add(NULL, "orion_wdt", tclk); + orion_clkdev_add("0", "sata_mv.0", sata0); + orion_clkdev_add("1", "sata_mv.0", sata1); + orion_clkdev_add(NULL, "orion-ehci.0", usb0); + orion_clkdev_add(NULL, "orion_nand", runit); + orion_clkdev_add(NULL, "mvsdio", sdio); + orion_clkdev_add(NULL, "mv_crypto", crypto); + orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0); + orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1); + orion_clkdev_add("0", "pcie", pex0); + orion_clkdev_add("1", "pcie", pex1); + orion_clkdev_add(NULL, "mvebu-audio", audio); + orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit); + orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".1", runit); + + /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., + * so should never be gated. + */ + clk_prepare_enable(runit); +} /***************************************************************************** - * Ethernet switch + * EHCI0 ****************************************************************************/ -static struct resource kirkwood_switch_resources[] = { - { - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, -}; +void __init kirkwood_ehci_init(void) +{ + orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); +} -static struct platform_device kirkwood_switch_device = { - .name = "dsa", - .id = 0, - .num_resources = 0, - .resource = kirkwood_switch_resources, -}; -void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq) +/***************************************************************************** + * GE00 + ****************************************************************************/ +void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) { - if (irq != NO_IRQ) { - kirkwood_switch_resources[0].start = irq; - kirkwood_switch_resources[0].end = irq; - kirkwood_switch_device.num_resources = 1; - } + orion_ge00_init(eth_data, + GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, + IRQ_KIRKWOOD_GE00_ERR, 1600); + /* The interface forgets the MAC address assigned by u-boot if + the clock is turned off, so claim the clk now. */ + clk_prepare_enable(ge0); +} - d->mii_bus = &kirkwood_ge00_shared.dev; - d->netdev = &kirkwood_ge00.dev; - kirkwood_switch_device.dev.platform_data = d; - platform_device_register(&kirkwood_switch_device); +/***************************************************************************** + * GE01 + ****************************************************************************/ +void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) +{ + orion_ge01_init(eth_data, + GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, + IRQ_KIRKWOOD_GE01_ERR, 1600); + clk_prepare_enable(ge1); } /***************************************************************************** - * SoC RTC + * Ethernet switch ****************************************************************************/ -static struct resource kirkwood_rtc_resource = { - .start = RTC_PHYS_BASE, - .end = RTC_PHYS_BASE + SZ_16 - 1, - .flags = IORESOURCE_MEM, -}; - -void __init kirkwood_rtc_init(void) +void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq) { - platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1); + orion_ge00_switch_init(d, irq); } /***************************************************************************** - * SATA + * NAND flash ****************************************************************************/ -static struct resource kirkwood_sata_resources[] = { - { - .name = "sata base", - .start = SATA_PHYS_BASE, - .end = SATA_PHYS_BASE + 0x5000 - 1, - .flags = IORESOURCE_MEM, - }, { - .name = "sata irq", - .start = IRQ_KIRKWOOD_SATA, - .end = IRQ_KIRKWOOD_SATA, - .flags = IORESOURCE_IRQ, - }, +static struct resource kirkwood_nand_resource = { + .flags = IORESOURCE_MEM, + .start = KIRKWOOD_NAND_MEM_PHYS_BASE, + .end = KIRKWOOD_NAND_MEM_PHYS_BASE + + KIRKWOOD_NAND_MEM_SIZE - 1, }; -static struct platform_device kirkwood_sata = { - .name = "sata_mv", - .id = 0, +static struct orion_nand_data kirkwood_nand_data = { + .cle = 0, + .ale = 1, + .width = 8, +}; + +static struct platform_device kirkwood_nand_flash = { + .name = "orion_nand", + .id = -1, .dev = { - .coherent_dma_mask = 0xffffffff, + .platform_data = &kirkwood_nand_data, }, - .num_resources = ARRAY_SIZE(kirkwood_sata_resources), - .resource = kirkwood_sata_resources, + .resource = &kirkwood_nand_resource, + .num_resources = 1, }; -void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) +void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, + int chip_delay) { - sata_data->dram = &kirkwood_mbus_dram_info; - kirkwood_sata.dev.platform_data = sata_data; - platform_device_register(&kirkwood_sata); + kirkwood_nand_data.parts = parts; + kirkwood_nand_data.nr_parts = nr_parts; + kirkwood_nand_data.chip_delay = chip_delay; + platform_device_register(&kirkwood_nand_flash); } +void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, + int (*dev_ready)(struct mtd_info *)) +{ + kirkwood_nand_data.parts = parts; + kirkwood_nand_data.nr_parts = nr_parts; + kirkwood_nand_data.dev_ready = dev_ready; + platform_device_register(&kirkwood_nand_flash); +} /***************************************************************************** - * SPI + * SoC RTC ****************************************************************************/ -static struct orion_spi_info kirkwood_spi_plat_data = { -}; +static void __init kirkwood_rtc_init(void) +{ + orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC); +} -static struct resource kirkwood_spi_resources[] = { - { - .start = SPI_PHYS_BASE, - .end = SPI_PHYS_BASE + SZ_512 - 1, + +/***************************************************************************** + * SATA + ****************************************************************************/ +void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) +{ + orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); +} + + +/***************************************************************************** + * SD/SDIO/MMC + ****************************************************************************/ +static struct resource mvsdio_resources[] = { + [0] = { + .start = SDIO_PHYS_BASE, + .end = SDIO_PHYS_BASE + SZ_1K - 1, .flags = IORESOURCE_MEM, }, + [1] = { + .start = IRQ_KIRKWOOD_SDIO, + .end = IRQ_KIRKWOOD_SDIO, + .flags = IORESOURCE_IRQ, + }, }; -static struct platform_device kirkwood_spi = { - .name = "orion_spi", - .id = 0, - .resource = kirkwood_spi_resources, +static u64 mvsdio_dmamask = DMA_BIT_MASK(32); + +static struct platform_device kirkwood_sdio = { + .name = "mvsdio", + .id = -1, .dev = { - .platform_data = &kirkwood_spi_plat_data, + .dma_mask = &mvsdio_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), }, - .num_resources = ARRAY_SIZE(kirkwood_spi_resources), + .num_resources = ARRAY_SIZE(mvsdio_resources), + .resource = mvsdio_resources, }; -void __init kirkwood_spi_init() +void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) { - platform_device_register(&kirkwood_spi); + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */ + mvsdio_data->clock = 100000000; + else + mvsdio_data->clock = 200000000; + kirkwood_sdio.dev.platform_data = mvsdio_data; + platform_device_register(&kirkwood_sdio); } /***************************************************************************** - * UART0 + * SPI ****************************************************************************/ -static struct plat_serial8250_port kirkwood_uart0_data[] = { - { - .mapbase = UART0_PHYS_BASE, - .membase = (char *)UART0_VIRT_BASE, - .irq = IRQ_KIRKWOOD_UART_0, - .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = 0, - }, { - }, -}; +void __init kirkwood_spi_init(void) +{ + orion_spi_init(SPI_PHYS_BASE); +} -static struct resource kirkwood_uart0_resources[] = { - { - .start = UART0_PHYS_BASE, - .end = UART0_PHYS_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_KIRKWOOD_UART_0, - .end = IRQ_KIRKWOOD_UART_0, - .flags = IORESOURCE_IRQ, - }, -}; -static struct platform_device kirkwood_uart0 = { - .name = "serial8250", - .id = 0, - .dev = { - .platform_data = kirkwood_uart0_data, - }, - .resource = kirkwood_uart0_resources, - .num_resources = ARRAY_SIZE(kirkwood_uart0_resources), -}; +/***************************************************************************** + * I2C + ****************************************************************************/ +void __init kirkwood_i2c_init(void) +{ + orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8); +} + + +/***************************************************************************** + * UART0 + ****************************************************************************/ void __init kirkwood_uart0_init(void) { - platform_device_register(&kirkwood_uart0); + orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, + IRQ_KIRKWOOD_UART_0, tclk); } /***************************************************************************** * UART1 ****************************************************************************/ -static struct plat_serial8250_port kirkwood_uart1_data[] = { - { - .mapbase = UART1_PHYS_BASE, - .membase = (char *)UART1_VIRT_BASE, - .irq = IRQ_KIRKWOOD_UART_1, - .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = 0, - }, { - }, -}; +void __init kirkwood_uart1_init(void) +{ + orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, + IRQ_KIRKWOOD_UART_1, tclk); +} -static struct resource kirkwood_uart1_resources[] = { - { - .start = UART1_PHYS_BASE, - .end = UART1_PHYS_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_KIRKWOOD_UART_1, - .end = IRQ_KIRKWOOD_UART_1, - .flags = IORESOURCE_IRQ, - }, -}; +/***************************************************************************** + * Cryptographic Engines and Security Accelerator (CESA) + ****************************************************************************/ +void __init kirkwood_crypto_init(void) +{ + orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, + KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); +} -static struct platform_device kirkwood_uart1 = { - .name = "serial8250", - .id = 1, - .dev = { - .platform_data = kirkwood_uart1_data, - }, - .resource = kirkwood_uart1_resources, - .num_resources = ARRAY_SIZE(kirkwood_uart1_resources), -}; -void __init kirkwood_uart1_init(void) +/***************************************************************************** + * XOR0 + ****************************************************************************/ +void __init kirkwood_xor0_init(void) { - platform_device_register(&kirkwood_uart1); + orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, + IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); } /***************************************************************************** - * XOR + * XOR1 ****************************************************************************/ -static struct mv_xor_platform_shared_data kirkwood_xor_shared_data = { - .dram = &kirkwood_mbus_dram_info, -}; +void __init kirkwood_xor1_init(void) +{ + orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, + IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); +} -static u64 kirkwood_xor_dmamask = DMA_32BIT_MASK; +/***************************************************************************** + * Watchdog + ****************************************************************************/ +void __init kirkwood_wdt_init(void) +{ + orion_wdt_init(); +} /***************************************************************************** - * XOR0 + * CPU idle ****************************************************************************/ -static struct resource kirkwood_xor0_shared_resources[] = { +static struct resource kirkwood_cpuidle_resource[] = { { - .name = "xor 0 low", - .start = XOR0_PHYS_BASE, - .end = XOR0_PHYS_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { - .name = "xor 0 high", - .start = XOR0_HIGH_PHYS_BASE, - .end = XOR0_HIGH_PHYS_BASE + 0xff, .flags = IORESOURCE_MEM, + .start = DDR_OPERATION_BASE, + .end = DDR_OPERATION_BASE + 3, }, }; -static struct platform_device kirkwood_xor0_shared = { - .name = MV_XOR_SHARED_NAME, - .id = 0, - .dev = { - .platform_data = &kirkwood_xor_shared_data, - }, - .num_resources = ARRAY_SIZE(kirkwood_xor0_shared_resources), - .resource = kirkwood_xor0_shared_resources, +static struct platform_device kirkwood_cpuidle = { + .name = "kirkwood_cpuidle", + .id = -1, + .resource = kirkwood_cpuidle_resource, + .num_resources = 1, }; -static struct resource kirkwood_xor00_resources[] = { - [0] = { - .start = IRQ_KIRKWOOD_XOR_00, - .end = IRQ_KIRKWOOD_XOR_00, - .flags = IORESOURCE_IRQ, - }, -}; +void __init kirkwood_cpuidle_init(void) +{ + platform_device_register(&kirkwood_cpuidle); +} -static struct mv_xor_platform_data kirkwood_xor00_data = { - .shared = &kirkwood_xor0_shared, - .hw_id = 0, - .pool_size = PAGE_SIZE, -}; +/***************************************************************************** + * Time handling + ****************************************************************************/ +void __init kirkwood_init_early(void) +{ + orion_time_set_base(TIMER_VIRT_BASE); +} -static struct platform_device kirkwood_xor00_channel = { - .name = MV_XOR_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(kirkwood_xor00_resources), - .resource = kirkwood_xor00_resources, - .dev = { - .dma_mask = &kirkwood_xor_dmamask, - .coherent_dma_mask = DMA_64BIT_MASK, - .platform_data = (void *)&kirkwood_xor00_data, - }, -}; +int kirkwood_tclk; -static struct resource kirkwood_xor01_resources[] = { - [0] = { - .start = IRQ_KIRKWOOD_XOR_01, - .end = IRQ_KIRKWOOD_XOR_01, - .flags = IORESOURCE_IRQ, - }, -}; +static int __init kirkwood_find_tclk(void) +{ + u32 dev, rev; -static struct mv_xor_platform_data kirkwood_xor01_data = { - .shared = &kirkwood_xor0_shared, - .hw_id = 1, - .pool_size = PAGE_SIZE, -}; + kirkwood_pcie_id(&dev, &rev); -static struct platform_device kirkwood_xor01_channel = { - .name = MV_XOR_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(kirkwood_xor01_resources), - .resource = kirkwood_xor01_resources, - .dev = { - .dma_mask = &kirkwood_xor_dmamask, - .coherent_dma_mask = DMA_64BIT_MASK, - .platform_data = (void *)&kirkwood_xor01_data, - }, -}; + if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID) + if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0) + return 200000000; -void __init kirkwood_xor0_init(void) -{ - platform_device_register(&kirkwood_xor0_shared); + return 166666667; +} - /* - * two engines can't do memset simultaneously, this limitation - * satisfied by removing memset support from one of the engines. - */ - dma_cap_set(DMA_MEMCPY, kirkwood_xor00_data.cap_mask); - dma_cap_set(DMA_XOR, kirkwood_xor00_data.cap_mask); - platform_device_register(&kirkwood_xor00_channel); +void __init kirkwood_timer_init(void) +{ + kirkwood_tclk = kirkwood_find_tclk(); - dma_cap_set(DMA_MEMCPY, kirkwood_xor01_data.cap_mask); - dma_cap_set(DMA_MEMSET, kirkwood_xor01_data.cap_mask); - dma_cap_set(DMA_XOR, kirkwood_xor01_data.cap_mask); - platform_device_register(&kirkwood_xor01_channel); + orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR, + IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); } - /***************************************************************************** - * XOR1 + * Audio ****************************************************************************/ -static struct resource kirkwood_xor1_shared_resources[] = { - { - .name = "xor 1 low", - .start = XOR1_PHYS_BASE, - .end = XOR1_PHYS_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { - .name = "xor 1 high", - .start = XOR1_HIGH_PHYS_BASE, - .end = XOR1_HIGH_PHYS_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device kirkwood_xor1_shared = { - .name = MV_XOR_SHARED_NAME, - .id = 1, - .dev = { - .platform_data = &kirkwood_xor_shared_data, - }, - .num_resources = ARRAY_SIZE(kirkwood_xor1_shared_resources), - .resource = kirkwood_xor1_shared_resources, -}; - -static struct resource kirkwood_xor10_resources[] = { +static struct resource kirkwood_audio_resources[] = { [0] = { - .start = IRQ_KIRKWOOD_XOR_10, - .end = IRQ_KIRKWOOD_XOR_10, - .flags = IORESOURCE_IRQ, + .start = AUDIO_PHYS_BASE, + .end = AUDIO_PHYS_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, }, -}; - -static struct mv_xor_platform_data kirkwood_xor10_data = { - .shared = &kirkwood_xor1_shared, - .hw_id = 0, - .pool_size = PAGE_SIZE, -}; - -static struct platform_device kirkwood_xor10_channel = { - .name = MV_XOR_NAME, - .id = 2, - .num_resources = ARRAY_SIZE(kirkwood_xor10_resources), - .resource = kirkwood_xor10_resources, - .dev = { - .dma_mask = &kirkwood_xor_dmamask, - .coherent_dma_mask = DMA_64BIT_MASK, - .platform_data = (void *)&kirkwood_xor10_data, - }, -}; - -static struct resource kirkwood_xor11_resources[] = { - [0] = { - .start = IRQ_KIRKWOOD_XOR_11, - .end = IRQ_KIRKWOOD_XOR_11, - .flags = IORESOURCE_IRQ, + [1] = { + .start = IRQ_KIRKWOOD_I2S, + .end = IRQ_KIRKWOOD_I2S, + .flags = IORESOURCE_IRQ, }, }; -static struct mv_xor_platform_data kirkwood_xor11_data = { - .shared = &kirkwood_xor1_shared, - .hw_id = 1, - .pool_size = PAGE_SIZE, +static struct kirkwood_asoc_platform_data kirkwood_audio_data = { + .burst = 128, }; -static struct platform_device kirkwood_xor11_channel = { - .name = MV_XOR_NAME, - .id = 3, - .num_resources = ARRAY_SIZE(kirkwood_xor11_resources), - .resource = kirkwood_xor11_resources, +static struct platform_device kirkwood_audio_device = { + .name = "mvebu-audio", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_audio_resources), + .resource = kirkwood_audio_resources, .dev = { - .dma_mask = &kirkwood_xor_dmamask, - .coherent_dma_mask = DMA_64BIT_MASK, - .platform_data = (void *)&kirkwood_xor11_data, + .platform_data = &kirkwood_audio_data, }, }; -void __init kirkwood_xor1_init(void) +void __init kirkwood_audio_init(void) { - platform_device_register(&kirkwood_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, kirkwood_xor10_data.cap_mask); - dma_cap_set(DMA_XOR, kirkwood_xor10_data.cap_mask); - platform_device_register(&kirkwood_xor10_channel); - - dma_cap_set(DMA_MEMCPY, kirkwood_xor11_data.cap_mask); - dma_cap_set(DMA_MEMSET, kirkwood_xor11_data.cap_mask); - dma_cap_set(DMA_XOR, kirkwood_xor11_data.cap_mask); - platform_device_register(&kirkwood_xor11_channel); + platform_device_register(&kirkwood_audio_device); } - /***************************************************************************** - * Time handling + * CPU Frequency ****************************************************************************/ -int kirkwood_tclk; - -int __init kirkwood_find_tclk(void) -{ - u32 dev, rev; - - kirkwood_pcie_id(&dev, &rev); - if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0) - return 200000000; +static struct resource kirkwood_cpufreq_resources[] = { + [0] = { + .start = CPU_CONTROL_PHYS, + .end = CPU_CONTROL_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; - return 166666667; -} +static struct platform_device kirkwood_cpufreq_device = { + .name = "kirkwood-cpufreq", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources), + .resource = kirkwood_cpufreq_resources, +}; -static void kirkwood_timer_init(void) +void __init kirkwood_cpufreq_init(void) { - kirkwood_tclk = kirkwood_find_tclk(); - orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); + platform_device_register(&kirkwood_cpufreq_device); } -struct sys_timer kirkwood_timer = { - .init = kirkwood_timer_init, -}; - - /***************************************************************************** * General ****************************************************************************/ /* * Identify device ID and revision. */ -static char * __init kirkwood_id(void) +char * __init kirkwood_id(void) { u32 dev, rev; @@ -663,6 +635,8 @@ static char * __init kirkwood_id(void) return "MV88F6281-Z0"; else if (rev == MV88F6281_REV_A0) return "MV88F6281-A0"; + else if (rev == MV88F6281_REV_A1) + return "MV88F6281-A1"; else return "MV88F6281-Rev-Unsupported"; } else if (dev == MV88F6192_DEV_ID) { @@ -670,20 +644,44 @@ static char * __init kirkwood_id(void) return "MV88F6192-Z0"; else if (rev == MV88F6192_REV_A0) return "MV88F6192-A0"; + else if (rev == MV88F6192_REV_A1) + return "MV88F6192-A1"; else return "MV88F6192-Rev-Unsupported"; } else if (dev == MV88F6180_DEV_ID) { if (rev == MV88F6180_REV_A0) return "MV88F6180-Rev-A0"; + else if (rev == MV88F6180_REV_A1) + return "MV88F6180-Rev-A1"; else return "MV88F6180-Rev-Unsupported"; + } else if (dev == MV88F6282_DEV_ID) { + if (rev == MV88F6282_REV_A0) + return "MV88F6282-Rev-A0"; + else if (rev == MV88F6282_REV_A1) + return "MV88F6282-Rev-A1"; + else + return "MV88F6282-Rev-Unsupported"; } else { return "Device-Unknown"; } } -static void __init kirkwood_l2_init(void) +void __init kirkwood_setup_wins(void) { + mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_NAND_TARGET, + KIRKWOOD_MBUS_NAND_ATTR, + KIRKWOOD_NAND_MEM_PHYS_BASE, + KIRKWOOD_NAND_MEM_SIZE); + mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_SRAM_TARGET, + KIRKWOOD_MBUS_SRAM_ATTR, + KIRKWOOD_SRAM_PHYS_BASE, + KIRKWOOD_SRAM_SIZE); +} + +void __init kirkwood_l2_init(void) +{ +#ifdef CONFIG_CACHE_FEROCEON_L2 #ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG); feroceon_l2_init(1); @@ -691,21 +689,58 @@ static void __init kirkwood_l2_init(void) writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG); feroceon_l2_init(0); #endif +#endif } void __init kirkwood_init(void) { - printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n", - kirkwood_id(), kirkwood_tclk); - kirkwood_ge00_shared_data.t_clk = kirkwood_tclk; - kirkwood_ge01_shared_data.t_clk = kirkwood_tclk; - kirkwood_spi_plat_data.tclk = kirkwood_tclk; - kirkwood_uart0_data[0].uartclk = kirkwood_tclk; - kirkwood_uart1_data[0].uartclk = kirkwood_tclk; + pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); - kirkwood_setup_cpu_mbus(); + /* + * Disable propagation of mbus errors to the CPU local bus, + * as this causes mbus errors (which can occur for example + * for PCI aborts) to throw CPU aborts, which we're not set + * up to deal with. + */ + writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); + + BUG_ON(mvebu_mbus_init("marvell,kirkwood-mbus", + BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, + DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ)); + + kirkwood_setup_wins(); -#ifdef CONFIG_CACHE_FEROCEON_L2 kirkwood_l2_init(); + + /* Setup root of clk tree */ + kirkwood_clk_init(); + + /* internal devices that every board has */ + kirkwood_rtc_init(); + kirkwood_wdt_init(); + kirkwood_xor0_init(); + kirkwood_xor1_init(); + kirkwood_crypto_init(); + + kirkwood_pm_init(); + kirkwood_cpuidle_init(); +#ifdef CONFIG_KEXEC + kexec_reinit = kirkwood_enable_pcie; #endif } + +void kirkwood_restart(enum reboot_mode 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) + ; +} diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index fe367c18e72..832a4e2ab8d 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -11,37 +11,64 @@ #ifndef __ARCH_KIRKWOOD_COMMON_H #define __ARCH_KIRKWOOD_COMMON_H +#include <linux/reboot.h> + struct dsa_platform_data; struct mv643xx_eth_platform_data; struct mv_sata_platform_data; +struct mvsdio_platform_data; +struct mtd_partition; +struct mtd_info; +struct kirkwood_asoc_platform_data; + +#define KW_PCIE0 (1 << 0) +#define KW_PCIE1 (1 << 1) /* * Basic Kirkwood init functions used early by machine-setup. */ void kirkwood_map_io(void); void kirkwood_init(void); +void kirkwood_init_early(void); void kirkwood_init_irq(void); -extern struct mbus_dram_target_info kirkwood_mbus_dram_info; -void kirkwood_setup_cpu_mbus(void); -void kirkwood_setup_sram_win(u32 base, u32 size); +void kirkwood_setup_wins(void); +void kirkwood_enable_pcie(void); void kirkwood_pcie_id(u32 *dev, u32 *rev); void kirkwood_ehci_init(void); void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data); void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data); void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq); -void kirkwood_pcie_init(void); -void kirkwood_rtc_init(void); +void kirkwood_pcie_init(unsigned int portmask); void kirkwood_sata_init(struct mv_sata_platform_data *sata_data); +void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data); void kirkwood_spi_init(void); +void kirkwood_i2c_init(void); void kirkwood_uart0_init(void); void kirkwood_uart1_init(void); +void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay); +void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, + int (*dev_ready)(struct mtd_info *)); +void kirkwood_audio_init(void); +void kirkwood_cpuidle_init(void); +void kirkwood_cpufreq_init(void); + +void kirkwood_restart(enum reboot_mode, const char *); +void kirkwood_clk_init(void); + +/* early init functions not converted to fdt yet */ +char *kirkwood_id(void); +void kirkwood_l2_init(void); +void kirkwood_wdt_init(void); void kirkwood_xor0_init(void); void kirkwood_xor1_init(void); +void kirkwood_crypto_init(void); -extern struct sys_timer kirkwood_timer; +extern int kirkwood_tclk; +extern void kirkwood_timer_init(void); +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) #endif diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c new file mode 100644 index 00000000000..453418063c1 --- /dev/null +++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c @@ -0,0 +1,231 @@ +/* + * arch/arm/mach-kirkwood/d2net_v2-setup.c + * + * LaCie d2 Network Space v2 Board Setup + * + * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/mv643xx_eth.h> +#include <linux/input.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/leds.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include <linux/platform_data/leds-kirkwood-ns2.h> +#include "common.h" +#include "mpp.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data d2net_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data d2net_v2_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define D2NET_V2_GPIO_PUSH_BUTTON 34 +#define D2NET_V2_GPIO_POWER_SWITCH_ON 13 +#define D2NET_V2_GPIO_POWER_SWITCH_OFF 15 + +#define D2NET_V2_SWITCH_POWER_ON 0x1 +#define D2NET_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button d2net_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = D2NET_V2_SWITCH_POWER_ON, + .gpio = D2NET_V2_GPIO_POWER_SWITCH_ON, + .desc = "Back power switch (on|auto)", + .active_low = 0, + }, + [1] = { + .type = EV_SW, + .code = D2NET_V2_SWITCH_POWER_OFF, + .gpio = D2NET_V2_GPIO_POWER_SWITCH_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 0, + }, + [2] = { + .code = KEY_POWER, + .gpio = D2NET_V2_GPIO_PUSH_BUTTON, + .desc = "Front Push Button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data d2net_v2_button_data = { + .buttons = d2net_v2_buttons, + .nbuttons = ARRAY_SIZE(d2net_v2_buttons), +}; + +static struct platform_device d2net_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &d2net_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +#define D2NET_V2_GPIO_RED_LED 12 + +static struct gpio_led d2net_v2_gpio_led_pins[] = { + { + .name = "d2net_v2:red:fail", + .gpio = D2NET_V2_GPIO_RED_LED, + }, +}; + +static struct gpio_led_platform_data d2net_v2_gpio_leds_data = { + .num_leds = ARRAY_SIZE(d2net_v2_gpio_led_pins), + .leds = d2net_v2_gpio_led_pins, +}; + +static struct platform_device d2net_v2_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &d2net_v2_gpio_leds_data, + }, +}; + +/***************************************************************************** + * Dual-GPIO CPLD LEDs + ****************************************************************************/ + +#define D2NET_V2_GPIO_BLUE_LED_SLOW 29 +#define D2NET_V2_GPIO_BLUE_LED_CMD 30 + +static struct ns2_led d2net_v2_led_pins[] = { + { + .name = "d2net_v2:blue:sata", + .cmd = D2NET_V2_GPIO_BLUE_LED_CMD, + .slow = D2NET_V2_GPIO_BLUE_LED_SLOW, + }, +}; + +static struct ns2_led_platform_data d2net_v2_leds_data = { + .num_leds = ARRAY_SIZE(d2net_v2_led_pins), + .leds = d2net_v2_led_pins, +}; + +static struct platform_device d2net_v2_leds = { + .name = "leds-ns2", + .id = -1, + .dev = { + .platform_data = &d2net_v2_leds_data, + }, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int d2net_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, /* Red led */ + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA 0 power */ + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* Blue led (slow register) */ + MPP30_GPIO, /* Blue led (command register) */ + MPP34_GPIO, /* Power button (1 = Released, 0 = Pushed) */ + MPP35_GPIO, /* Inhibit power-off */ + 0 +}; + +#define D2NET_V2_GPIO_POWER_OFF 7 + +static void d2net_v2_power_off(void) +{ + gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1); +} + +static void __init d2net_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(d2net_v2_mpp_config); + + lacie_v2_hdd_power_init(1); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&d2net_v2_ge00_data); + kirkwood_sata_init(&d2net_v2_sata_data); + kirkwood_uart0_init(); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); + + platform_device_register(&d2net_v2_leds); + platform_device_register(&d2net_v2_gpio_leds); + platform_device_register(&d2net_v2_gpio_buttons); + + if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = d2net_v2_power_off; + else + pr_err("d2net_v2: failed to configure power-off GPIO\n"); +} + +MACHINE_START(D2NET_V2, "LaCie d2 Network v2") + .atag_offset = 0x100, + .init_machine = d2net_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c deleted file mode 100644 index a14c2948c62..00000000000 --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * arch/arm/mach-kirkwood/db88f6281-bp-setup.c - * - * Marvell DB-88F6281-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/pci.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 <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/pci.h> -#include <mach/kirkwood.h> -#include "common.h" - -static struct mv643xx_eth_platform_data db88f6281_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(8), -}; - -static struct mv_sata_platform_data db88f6281_sata_data = { - .n_ports = 2, -}; - -static void __init db88f6281_init(void) -{ - /* - * Basic setup. Needs to be called early. - */ - kirkwood_init(); - - kirkwood_ehci_init(); - kirkwood_ge00_init(&db88f6281_ge00_data); - kirkwood_rtc_init(); - kirkwood_sata_init(&db88f6281_sata_data); - kirkwood_uart0_init(); -} - -static int __init db88f6281_pci_init(void) -{ - if (machine_is_db88f6281_bp()) - kirkwood_pcie_init(); - - return 0; -} -subsys_initcall(db88f6281_pci_init); - -MACHINE_START(DB88F6281_BP, "Marvell DB-88F6281-BP Development Board") - /* Maintainer: Saeed Bishara <saeed@marvell.com> */ - .phys_io = KIRKWOOD_REGS_PHYS_BASE, - .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .init_machine = db88f6281_init, - .map_io = kirkwood_map_io, - .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, -MACHINE_END diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h new file mode 100644 index 00000000000..1c37082c8b3 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -0,0 +1,86 @@ +/* + * arch/arm/mach-kirkwood/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/kirkwood.h> + +#define CPU_CONFIG (BRIDGE_VIRT_BASE + 0x0100) +#define CPU_CONFIG_PHYS (BRIDGE_PHYS_BASE + 0x0100) +#define CPU_CONFIG_ERROR_PROP 0x00000004 + +#define CPU_CONTROL (BRIDGE_VIRT_BASE + 0x0104) +#define CPU_CONTROL_PHYS (BRIDGE_PHYS_BASE + 0x0104) +#define CPU_RESET 0x00000002 + +#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) +#define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_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_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 IRQ_CAUSE_HIGH_OFF 0x0010 +#define IRQ_MASK_HIGH_OFF 0x0014 + +#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0300) +#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE + 0x0300) + +#define L2_CONFIG_REG (BRIDGE_VIRT_BASE + 0x0128) +#define L2_WRITETHROUGH 0x00000010 + +#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE + 0x11c) +#define CGC_BIT_GE0 (0) +#define CGC_BIT_PEX0 (2) +#define CGC_BIT_USB0 (3) +#define CGC_BIT_SDIO (4) +#define CGC_BIT_TSU (5) +#define CGC_BIT_DUNIT (6) +#define CGC_BIT_RUNIT (7) +#define CGC_BIT_XOR0 (8) +#define CGC_BIT_AUDIO (9) +#define CGC_BIT_SATA0 (14) +#define CGC_BIT_SATA1 (15) +#define CGC_BIT_XOR1 (16) +#define CGC_BIT_CRYPTO (17) +#define CGC_BIT_PEX1 (18) +#define CGC_BIT_GE1 (19) +#define CGC_BIT_TDM (20) +#define CGC_GE0 (1 << 0) +#define CGC_PEX0 (1 << 2) +#define CGC_USB0 (1 << 3) +#define CGC_SDIO (1 << 4) +#define CGC_TSU (1 << 5) +#define CGC_DUNIT (1 << 6) +#define CGC_RUNIT (1 << 7) +#define CGC_XOR0 (1 << 8) +#define CGC_AUDIO (1 << 9) +#define CGC_POWERSAVE (1 << 11) +#define CGC_SATA0 (1 << 14) +#define CGC_SATA1 (1 << 15) +#define CGC_XOR1 (1 << 16) +#define CGC_CRYPTO (1 << 17) +#define CGC_PEX1 (1 << 18) +#define CGC_GE1 (1 << 19) +#define CGC_TDM (1 << 20) +#define CGC_RESERVED (0x6 << 21) + +#define MEMORY_PM_CTRL (BRIDGE_VIRT_BASE + 0x118) +#define MEMORY_PM_CTRL_PHYS (BRIDGE_PHYS_BASE + 0x118) + +#endif diff --git a/arch/arm/mach-kirkwood/include/mach/debug-macro.S b/arch/arm/mach-kirkwood/include/mach/debug-macro.S deleted file mode 100644 index c0cc5b5c82a..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/debug-macro.S +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-kirkwood/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/kirkwood.h> - - .macro addruart,rx - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 @ MMU enabled? - ldreq \rx, =KIRKWOOD_REGS_PHYS_BASE - ldrne \rx, =KIRKWOOD_REGS_VIRT_BASE - orr \rx, \rx, #0x00012000 - .endm - -#define UART_SHIFT 2 -#include <asm/hardware/debug-8250.S> diff --git a/arch/arm/mach-kirkwood/include/mach/entry-macro.S b/arch/arm/mach-kirkwood/include/mach/entry-macro.S index 83e0cba77b3..82db29f7af8 100644 --- a/arch/arm/mach-kirkwood/include/mach/entry-macro.S +++ b/arch/arm/mach-kirkwood/include/mach/entry-macro.S @@ -8,13 +8,7 @@ * warranty of any kind, whether express or implied. */ -#include <mach/kirkwood.h> - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm +#include <mach/bridge-regs.h> .macro get_irqnr_preamble, base, tmp ldr \base, =IRQ_VIRT_BASE diff --git a/arch/arm/mach-kirkwood/include/mach/gpio.h b/arch/arm/mach-kirkwood/include/mach/gpio.h deleted file mode 100644 index 81b335eb62e..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/gpio.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * arch/asm-arm/mach-kirkwood/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 <mach/irqs.h> -#include <plat/gpio.h> -#include <asm-generic/gpio.h> /* cansleep wrappers */ - -#define GPIO_MAX 50 -#define GPIO_OFF(pin) (((pin) >> 5) ? 0x0140 : 0x0100) -#define GPIO_OUT(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x00) -#define GPIO_IO_CONF(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x04) -#define GPIO_BLINK_EN(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x08) -#define GPIO_IN_POL(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x0c) -#define GPIO_DATA_IN(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x10) -#define GPIO_EDGE_CAUSE(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x14) -#define GPIO_EDGE_MASK(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x18) -#define GPIO_LEVEL_MASK(pin) (DEV_BUS_VIRT_BASE + GPIO_OFF(pin) + 0x1c) - -static inline int gpio_to_irq(int pin) -{ - return pin + IRQ_KIRKWOOD_GPIO_START; -} - -static inline int irq_to_gpio(int irq) -{ - return irq - IRQ_KIRKWOOD_GPIO_START; -} - - -#endif diff --git a/arch/arm/mach-kirkwood/include/mach/hardware.h b/arch/arm/mach-kirkwood/include/mach/hardware.h index cde85283f7d..742b74f43e4 100644 --- a/arch/arm/mach-kirkwood/include/mach/hardware.h +++ b/arch/arm/mach-kirkwood/include/mach/hardware.h @@ -11,11 +11,4 @@ #include "kirkwood.h" -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x00001000 -#define PCIBIOS_MIN_MEM 0x01000000 -#define PCIMEM_BASE KIRKWOOD_PCIE_MEM_PHYS_BASE /* mem base for VGA */ - - #endif diff --git a/arch/arm/mach-kirkwood/include/mach/io.h b/arch/arm/mach-kirkwood/include/mach/io.h deleted file mode 100644 index be07be0ef52..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/io.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-kirkwood/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 "kirkwood.h" - -#define IO_SPACE_LIMIT 0xffffffff - -static inline void __iomem *__io(unsigned long addr) -{ - return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_PHYS_BASE) - + KIRKWOOD_PCIE_IO_VIRT_BASE); -} - -#define __io(a) __io(a) -#define __mem_pci(a) (a) - - -#endif diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h index f00a0a45a67..2bf8161e3b5 100644 --- a/arch/arm/mach-kirkwood/include/mach/irqs.h +++ b/arch/arm/mach-kirkwood/include/mach/irqs.h @@ -23,6 +23,7 @@ #define IRQ_KIRKWOOD_XOR_10 7 #define IRQ_KIRKWOOD_XOR_11 8 #define IRQ_KIRKWOOD_PCIE 9 +#define IRQ_KIRKWOOD_PCIE1 10 #define IRQ_KIRKWOOD_GE00_SUM 11 #define IRQ_KIRKWOOD_GE01_SUM 15 #define IRQ_KIRKWOOD_USB 19 @@ -50,6 +51,7 @@ #define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41 #define IRQ_KIRKWOOD_GE00_ERR 46 #define IRQ_KIRKWOOD_GE01_ERR 47 +#define IRQ_KIRKWOOD_RTC 53 /* * KIRKWOOD General Purpose Pins diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index ada480c0e19..92976cef391 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -16,56 +16,108 @@ * Marvell Kirkwood address maps. * * phys - * e0000000 PCIe Memory space + * e0000000 PCIe #0 Memory space + * e8000000 PCIe #1 Memory space * f1000000 on-chip peripheral registers - * f2000000 PCIe I/O space - * f3000000 NAND controller address window + * f2000000 PCIe #0 I/O space + * f3000000 PCIe #1 I/O space + * f4000000 NAND controller address window + * f5000000 Security Accelerator SRAM * * virt phys size - * fee00000 f1000000 1M on-chip peripheral registers - * fef00000 f2000000 1M PCIe I/O space + * fed00000 f1000000 1M on-chip peripheral registers + * fee00000 f2000000 1M PCIe #0 I/O space + * fef00000 f3000000 1M PCIe #1 I/O space */ -#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf3000000 -#define KIRKWOOD_NAND_MEM_SIZE SZ_64K /* 1K is sufficient, but 64K - * is the minimal window size - */ +#define KIRKWOOD_SRAM_PHYS_BASE 0xf5000000 +#define KIRKWOOD_SRAM_SIZE SZ_2K + +#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf4000000 +#define KIRKWOOD_NAND_MEM_SIZE SZ_1K + +#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 +#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00010000 +#define KIRKWOOD_PCIE1_IO_SIZE SZ_64K #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 -#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfef00000 #define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000 -#define KIRKWOOD_PCIE_IO_SIZE SZ_1M +#define KIRKWOOD_PCIE_IO_SIZE SZ_64K #define KIRKWOOD_REGS_PHYS_BASE 0xf1000000 -#define KIRKWOOD_REGS_VIRT_BASE 0xfee00000 +#define KIRKWOOD_REGS_VIRT_BASE IOMEM(0xfed00000) #define KIRKWOOD_REGS_SIZE SZ_1M #define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000 +#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000 #define KIRKWOOD_PCIE_MEM_SIZE SZ_128M +#define KIRKWOOD_PCIE1_MEM_PHYS_BASE 0xe8000000 +#define KIRKWOOD_PCIE1_MEM_BUS_BASE 0xe8000000 +#define KIRKWOOD_PCIE1_MEM_SIZE SZ_128M + /* - * MBUS bridge registers. + * Register Map */ -#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000) -#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104) -#define CPU_RESET 0x00000002 -#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 IRQ_CAUSE_HIGH_OFF 0x0010 -#define IRQ_MASK_HIGH_OFF 0x0014 -#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) -#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) -#define L2_WRITETHROUGH 0x00000010 +#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000) +#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000) +#define DDR_WINDOW_CPU_BASE (DDR_PHYS_BASE + 0x1500) +#define DDR_WINDOW_CPU_SZ (0x20) +#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418) + +#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000) +#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x10000) +#define SAMPLE_AT_RESET (DEV_BUS_VIRT_BASE + 0x0030) +#define DEVICE_ID (DEV_BUS_VIRT_BASE + 0x0034) +#define GPIO_LOW_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x0100) +#define GPIO_HIGH_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x0140) +#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x0300) +#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x0600) +#define I2C_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x1000) +#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2000) +#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2000) +#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2100) +#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2100) + +#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000) +#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000) +#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE) +#define BRIDGE_WINS_SZ (0x80) + +#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000) + +#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x40000) +#define PCIE_LINK_CTRL (PCIE_VIRT_BASE + 0x70) +#define PCIE_STATUS (PCIE_VIRT_BASE + 0x1a04) +#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x44000) +#define PCIE1_LINK_CTRL (PCIE1_VIRT_BASE + 0x70) +#define PCIE1_STATUS (PCIE1_VIRT_BASE + 0x1a04) + +#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x50000) + +#define XOR0_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60800) +#define XOR0_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60800) +#define XOR1_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60900) +#define XOR1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60900) +#define XOR0_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60A00) +#define XOR0_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60A00) +#define XOR1_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60B00) +#define XOR1_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60B00) + +#define GE00_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x70000) +#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x74000) + +#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x80000) +#define SATA_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x80000) +#define SATA0_IF_CTRL (SATA_VIRT_BASE + 0x2050) +#define SATA0_PHY_MODE_2 (SATA_VIRT_BASE + 0x2330) +#define SATA1_IF_CTRL (SATA_VIRT_BASE + 0x4050) +#define SATA1_PHY_MODE_2 (SATA_VIRT_BASE + 0x4330) + +#define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x90000) + +#define AUDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0xA0000) +#define AUDIO_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0xA0000) /* * Supported devices and revisions. @@ -73,48 +125,18 @@ #define MV88F6281_DEV_ID 0x6281 #define MV88F6281_REV_Z0 0 #define MV88F6281_REV_A0 2 +#define MV88F6281_REV_A1 3 #define MV88F6192_DEV_ID 0x6192 #define MV88F6192_REV_Z0 0 #define MV88F6192_REV_A0 2 +#define MV88F6192_REV_A1 3 #define MV88F6180_DEV_ID 0x6180 #define MV88F6180_REV_A0 2 +#define MV88F6180_REV_A1 3 -/* - * Register Map - */ -#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x00000) -#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE | 0x1500) - -#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x10000) -#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x10000) -#define SAMPLE_AT_RESET (DEV_BUS_VIRT_BASE | 0x0030) -#define DEVICE_ID (DEV_BUS_VIRT_BASE | 0x0034) -#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0300) -#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0600) -#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000) -#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000) -#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100) -#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) - -#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000) - -#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000) - -#define XOR0_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60800) -#define XOR0_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60800) -#define XOR1_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60900) -#define XOR1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60900) -#define XOR0_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60A00) -#define XOR0_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60A00) -#define XOR1_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60B00) -#define XOR1_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60B00) - -#define GE00_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x70000) -#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x74000) - -#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x80000) - - +#define MV88F6282_DEV_ID 0x6282 +#define MV88F6282_REV_A0 0 +#define MV88F6282_REV_A1 1 #endif diff --git a/arch/arm/mach-kirkwood/include/mach/memory.h b/arch/arm/mach-kirkwood/include/mach/memory.h deleted file mode 100644 index 45431e13146..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/memory.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/arm/mach-kirkwood/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-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h deleted file mode 100644 index 8510f6cfdab..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/system.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * arch/arm/mach-kirkwood/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/hardware.h> -#include <mach/kirkwood.h> - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -static inline void arch_reset(char mode) -{ - /* - * Enable soft reset to assert RSTOUTn. - */ - writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); - - /* - * Assert soft reset. - */ - writel(SOFT_RESET, SYSTEM_SOFT_RESET); - - while (1) - ; -} - - -#endif diff --git a/arch/arm/mach-kirkwood/include/mach/timex.h b/arch/arm/mach-kirkwood/include/mach/timex.h deleted file mode 100644 index c923cd169b9..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/timex.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/arm/mach-kirkwood/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-kirkwood/include/mach/uncompress.h b/arch/arm/mach-kirkwood/include/mach/uncompress.h index 75d5497df3a..5bca5534021 100644 --- a/arch/arm/mach-kirkwood/include/mach/uncompress.h +++ b/arch/arm/mach-kirkwood/include/mach/uncompress.h @@ -44,4 +44,3 @@ static void flush(void) * nothing to do */ #define arch_decomp_setup() -#define arch_decomp_wdog() diff --git a/arch/arm/mach-kirkwood/include/mach/vmalloc.h b/arch/arm/mach-kirkwood/include/mach/vmalloc.h deleted file mode 100644 index 8f48260dcda..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/vmalloc.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-kirkwood/include/mach/vmalloc.h - */ - -#define VMALLOC_END 0xfe800000 diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c index 06083b23bb4..2c47a8ad0e2 100644 --- a/arch/arm/mach-kirkwood/irq.c +++ b/arch/arm/mach-kirkwood/irq.c @@ -7,51 +7,76 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ - +#include <asm/exception.h> +#include <linux/gpio.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/irq.h> #include <linux/io.h> +#include <mach/bridge-regs.h> +#include <plat/orion-gpio.h> #include <plat/irq.h> -#include <asm/gpio.h> #include "common.h" -static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +static int __initdata gpio0_irqs[4] = { + IRQ_KIRKWOOD_GPIO_LOW_0_7, + IRQ_KIRKWOOD_GPIO_LOW_8_15, + IRQ_KIRKWOOD_GPIO_LOW_16_23, + IRQ_KIRKWOOD_GPIO_LOW_24_31, +}; + +static int __initdata gpio1_irqs[4] = { + IRQ_KIRKWOOD_GPIO_HIGH_0_7, + IRQ_KIRKWOOD_GPIO_HIGH_8_15, + IRQ_KIRKWOOD_GPIO_HIGH_16_23, + 0, +}; + +#ifdef CONFIG_MULTI_IRQ_HANDLER +/* + * Compiling with both non-DT and DT support enabled, will + * break asm irq handler used by non-DT boards. Therefore, + * we provide a C-style irq handler even for non-DT boards, + * if MULTI_IRQ_HANDLER is set. + */ + +static void __iomem *kirkwood_irq_base = IRQ_VIRT_BASE; + +asmlinkage void +__exception_irq_entry kirkwood_legacy_handle_irq(struct pt_regs *regs) { - BUG_ON(irq < IRQ_KIRKWOOD_GPIO_LOW_0_7); - BUG_ON(irq > IRQ_KIRKWOOD_GPIO_HIGH_16_23); + u32 stat; - orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3); + stat = readl_relaxed(kirkwood_irq_base + IRQ_CAUSE_LOW_OFF); + stat &= readl_relaxed(kirkwood_irq_base + IRQ_MASK_LOW_OFF); + if (stat) { + unsigned int hwirq = __fls(stat); + handle_IRQ(hwirq, regs); + return; + } + stat = readl_relaxed(kirkwood_irq_base + IRQ_CAUSE_HIGH_OFF); + stat &= readl_relaxed(kirkwood_irq_base + IRQ_MASK_HIGH_OFF); + if (stat) { + unsigned int hwirq = 32 + __fls(stat); + handle_IRQ(hwirq, regs); + return; + } } +#endif void __init kirkwood_init_irq(void) { - int i; + orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); + orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); - 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)); +#ifdef CONFIG_MULTI_IRQ_HANDLER + set_handle_irq(kirkwood_legacy_handle_irq); +#endif /* - * Mask and clear GPIO IRQ interrupts. + * Initialize gpiolib for GPIOs 0-49. */ - writel(0, GPIO_LEVEL_MASK(0)); - writel(0, GPIO_EDGE_MASK(0)); - writel(0, GPIO_EDGE_CAUSE(0)); - writel(0, GPIO_LEVEL_MASK(32)); - writel(0, GPIO_EDGE_MASK(32)); - writel(0, GPIO_EDGE_CAUSE(32)); - - for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; 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_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); - set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); - set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); - set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); - set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); - set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); - set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, gpio_irq_handler); + orion_gpio_init(NULL, 0, 32, GPIO_LOW_VIRT_BASE, 0, + IRQ_KIRKWOOD_GPIO_START, gpio0_irqs); + orion_gpio_init(NULL, 32, 18, GPIO_HIGH_VIRT_BASE, 0, + IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs); } diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c new file mode 100644 index 00000000000..8e3e4331c38 --- /dev/null +++ b/arch/arm/mach-kirkwood/lacie_v2-common.c @@ -0,0 +1,114 @@ +/* + * arch/arm/mach-kirkwood/lacie_v2-common.c + * + * 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/mtd/physmap.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> +#include <linux/i2c.h> +#include <linux/platform_data/at24.h> +#include <linux/gpio.h> +#include <asm/mach/time.h> +#include <mach/kirkwood.h> +#include <mach/irqs.h> +#include <plat/time.h> +#include "common.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition lacie_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data lacie_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = lacie_v2_flash_parts, + .nr_parts = ARRAY_SIZE(lacie_v2_flash_parts), +}; + +static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &lacie_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +void __init lacie_v2_register_flash(void) +{ + spi_register_board_info(lacie_v2_spi_slave_info, + ARRAY_SIZE(lacie_v2_spi_slave_info)); + kirkwood_spi_init(); +} + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata lacie_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +void __init lacie_v2_register_i2c_devices(void) +{ + kirkwood_i2c_init(); + i2c_register_board_info(0, lacie_v2_i2c_info, + ARRAY_SIZE(lacie_v2_i2c_info)); +} + +/***************************************************************************** + * Hard Disk power + ****************************************************************************/ + +static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 }; + +void __init lacie_v2_hdd_power_init(int hdd_num) +{ + int i; + int err; + + /* Power up all hard disks. */ + for (i = 0; i < hdd_num; i++) { + err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL); + if (err == 0) { + err = gpio_direction_output( + lacie_v2_gpio_hdd_power[i], 1); + /* Free the HDD power GPIOs. This allow user-space to + * configure them via the gpiolib sysfs interface. */ + gpio_free(lacie_v2_gpio_hdd_power[i]); + } + if (err) + pr_err("Failed to power up HDD%d\n", i + 1); + } +} diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h new file mode 100644 index 00000000000..fc64f578536 --- /dev/null +++ b/arch/arm/mach-kirkwood/lacie_v2-common.h @@ -0,0 +1,16 @@ +/* + * arch/arm/mach-kirkwood/lacie_v2-common.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 __ARCH_KIRKWOOD_LACIE_V2_COMMON_H +#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H + +void lacie_v2_register_flash(void); +void lacie_v2_register_i2c_devices(void); +void lacie_v2_hdd_power_init(int hdd_num); + +#endif diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c new file mode 100644 index 00000000000..e96fd71abd7 --- /dev/null +++ b/arch/arm/mach-kirkwood/mpp.c @@ -0,0 +1,43 @@ +/* + * arch/arm/mach-kirkwood/mpp.c + * + * MPP functions for Marvell Kirkwood SoCs + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/gpio.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <plat/mpp.h> +#include "common.h" +#include "mpp.h" + +static unsigned int __init kirkwood_variant(void) +{ + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + + if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) + return MPP_F6281_MASK; + if (dev == MV88F6282_DEV_ID) + return MPP_F6282_MASK; + if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0) + return MPP_F6192_MASK; + if (dev == MV88F6180_DEV_ID) + return MPP_F6180_MASK; + + pr_err("MPP setup: unknown kirkwood variant (dev %#x rev %#x)\n", + dev, rev); + return 0; +} + +void __init kirkwood_mpp_conf(unsigned int *mpp_list) +{ + orion_mpp_conf(mpp_list, kirkwood_variant(), + MPP_MAX, DEV_BUS_VIRT_BASE); +} diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h new file mode 100644 index 00000000000..d5a0d1da2e0 --- /dev/null +++ b/arch/arm/mach-kirkwood/mpp.h @@ -0,0 +1,348 @@ +/* + * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins + * + * Copyright 2009: Marvell Technology Group Ltd. + * + * 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 __KIRKWOOD_MPP_H +#define __KIRKWOOD_MPP_H + +#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281, _F6282) ( \ + /* MPP number */ ((_num) & 0xff) | \ + /* MPP select value */ (((_sel) & 0xf) << 8) | \ + /* may be input signal */ ((!!(_in)) << 12) | \ + /* may be output signal */ ((!!(_out)) << 13) | \ + /* available on F6180 */ ((!!(_F6180)) << 14) | \ + /* available on F6190 */ ((!!(_F6190)) << 15) | \ + /* available on F6192 */ ((!!(_F6192)) << 16) | \ + /* available on F6281 */ ((!!(_F6281)) << 17) | \ + /* available on F6282 */ ((!!(_F6282)) << 18)) + + /* num sel i o 6180 6190 6192 6281 6282 */ + +#define MPP_F6180_MASK MPP( 0, 0x0, 0, 0, 1, 0, 0, 0, 0 ) +#define MPP_F6190_MASK MPP( 0, 0x0, 0, 0, 0, 1, 0, 0, 0 ) +#define MPP_F6192_MASK MPP( 0, 0x0, 0, 0, 0, 0, 1, 0, 0 ) +#define MPP_F6281_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 1, 0 ) +#define MPP_F6282_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP0_GPIO MPP( 0, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP0_NF_IO2 MPP( 0, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP1_GPO MPP( 1, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP1_NF_IO3 MPP( 1, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP2_GPO MPP( 2, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP2_NF_IO4 MPP( 2, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP3_GPO MPP( 3, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP3_NF_IO5 MPP( 3, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP3_SPI_MISO MPP( 3, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP4_GPIO MPP( 4, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP4_NF_IO6 MPP( 4, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP4_UART0_RXD MPP( 4, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP4_LCD_VGA_HSYNC MPP( 4, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP4_PTP_CLK MPP( 4, 0xd, 0, 0, 1, 1, 1, 1, 0 ) + +#define MPP5_GPO MPP( 5, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP5_NF_IO7 MPP( 5, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP5_LCD_VGA_VSYNC MPP( 5, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 0, 1, 1, 1, 1, 0 ) + +#define MPP7_GPO MPP( 7, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP7_LCD_PWM MPP( 7, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP8_GPIO MPP( 8, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP8_TW0_SDA MPP( 8, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP8_MII0_RXERR MPP( 8, 0x4, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP8_PTP_CLK MPP( 8, 0xc, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP8_MII0_COL MPP( 8, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP9_GPIO MPP( 9, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP9_TW0_SCK MPP( 9, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP9_UART0_CTS MPP( 9, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP9_UART1_CTS MPP( 9, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP9_MII0_CRS MPP( 9, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP10_GPO MPP( 10, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 0, 1, 1, 1, 1, 0 ) + +#define MPP11_GPIO MPP( 11, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP11_SPI_MISO MPP( 11, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP11_UART0_RXD MPP( 11, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP11_PTP_CLK MPP( 11, 0xd, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 0, 0, 1, 1, 1, 1 ) + +#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP12_GPIO MPP( 12, 0x0, 1, 1, 0, 0, 0, 1, 0 ) +#define MPP12_SD_CLK MPP( 12, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP12_TW1_SDA MPP( 12, 0xd, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP13_GPIO MPP( 13, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP13_SD_CMD MPP( 13, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP13_AU_SPDIFRMCLK MPP( 13, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP13_LCDPWM MPP( 13, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP14_GPIO MPP( 14, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP14_SD_D0 MPP( 14, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP14_UART1_RXD MPP( 14, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP14_AU_SPDIFI MPP( 14, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP14_AU_I2SDI MPP( 14, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP14_MII0_COL MPP( 14, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP15_GPIO MPP( 15, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP15_SD_D1 MPP( 15, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP15_SPI_CSn MPP( 15, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP16_GPIO MPP( 16, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP16_SD_D2 MPP( 16, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP16_UART0_CTS MPP( 16, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP16_UART1_RXD MPP( 16, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP16_LCD_EXT_REF_CLK MPP( 16, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP16_MII0_CRS MPP( 16, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP17_GPIO MPP( 17, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP17_SD_D3 MPP( 17, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP17_SATA1_ACTn MPP( 17, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP17_TW1_SCK MPP( 17, 0xd, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP18_GPO MPP( 18, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP18_NF_IO0 MPP( 18, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP18_PEX0_CLKREQ MPP( 18, 0x2, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP19_GPO MPP( 19, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP19_NF_IO1 MPP( 19, 0x1, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP20_GPIO MPP( 20, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP20_TSMP0 MPP( 20, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_GE1_TXD0 MPP( 20, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP20_AU_SPDIFI MPP( 20, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_LCD_D0 MPP( 20, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP21_GPIO MPP( 21, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP21_TSMP1 MPP( 21, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP21_GE1_TXD1 MPP( 21, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP21_AU_SPDIFO MPP( 21, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP21_LCD_D1 MPP( 21, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP22_GPIO MPP( 22, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP22_TSMP2 MPP( 22, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_GE1_TXD2 MPP( 22, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP22_AU_SPDIFRMKCLK MPP( 22, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_LCD_D2 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP23_GPIO MPP( 23, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP23_TSMP3 MPP( 23, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP23_GE1_TXD3 MPP( 23, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP23_AU_I2SBCLK MPP( 23, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP23_LCD_D3 MPP( 23, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP24_GPIO MPP( 24, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP24_TSMP4 MPP( 24, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_TDM_SPI_CS0 MPP( 24, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_GE1_RXD0 MPP( 24, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP24_AU_I2SDO MPP( 24, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_LCD_D4 MPP( 24, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP25_GPIO MPP( 25, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP25_TSMP5 MPP( 25, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_GE1_RXD1 MPP( 25, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP25_AU_I2SLRCLK MPP( 25, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_LCD_D5 MPP( 25, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP26_GPIO MPP( 26, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP26_TSMP6 MPP( 26, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_GE1_RXD2 MPP( 26, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP26_AU_I2SMCLK MPP( 26, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_LCD_D6 MPP( 26, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP27_GPIO MPP( 27, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP27_TSMP7 MPP( 27, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_GE1_RXD3 MPP( 27, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP27_AU_I2SDI MPP( 27, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_LCD_D7 MPP( 27, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP28_GPIO MPP( 28, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP28_TSMP8 MPP( 28, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_TDM_CODEC_INTn MPP( 28, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_GE1_COL MPP( 28, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP28_AU_EXTCLK MPP( 28, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_LCD_D8 MPP( 28, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP29_GPIO MPP( 29, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP29_TSMP9 MPP( 29, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP29_TDM_CODEC_RSTn MPP( 29, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP29_GE1_TCLK MPP( 29, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP29_LCD_D9 MPP( 29, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP30_GPIO MPP( 30, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP30_TSMP10 MPP( 30, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP30_TDM_PCLK MPP( 30, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP30_GE1_RXCTL MPP( 30, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP30_LCD_D10 MPP( 30, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP31_GPIO MPP( 31, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP31_TSMP11 MPP( 31, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP31_TDM_FS MPP( 31, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP31_GE1_RXCLK MPP( 31, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP31_LCD_D11 MPP( 31, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP32_GPIO MPP( 32, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP32_TSMP12 MPP( 32, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP32_TDM_DRX MPP( 32, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP32_GE1_TCLKOUT MPP( 32, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP32_LCD_D12 MPP( 32, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP33_GPO MPP( 33, 0x0, 0, 1, 0, 1, 1, 1, 1 ) +#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP33_GE1_TXCTL MPP( 33, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP33_LCD_D13 MPP( 33, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP34_GPIO MPP( 34, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP34_GE1_TXEN MPP( 34, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP34_SATA1_ACTn MPP( 34, 0x5, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP34_LCD_D14 MPP( 34, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP35_GPIO MPP( 35, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP35_GE1_RXERR MPP( 35, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP35_LCD_D15 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP35_MII0_RXERR MPP( 35, 0xc, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP36_GPIO MPP( 36, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP36_TSMP0 MPP( 36, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP36_AU_SPDIFI MPP( 36, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP36_TW1_SDA MPP( 36, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP37_GPIO MPP( 37, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP37_TSMP1 MPP( 37, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP37_AU_SPDIFO MPP( 37, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP37_TW1_SCK MPP( 37, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP38_GPIO MPP( 38, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP38_TSMP2 MPP( 38, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP38_AU_SPDIFRMLCLK MPP( 38, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP38_LCD_D18 MPP( 38, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP39_GPIO MPP( 39, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP39_TSMP3 MPP( 39, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP39_AU_I2SBCLK MPP( 39, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP39_LCD_D19 MPP( 39, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP40_GPIO MPP( 40, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP40_TSMP4 MPP( 40, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP40_AU_I2SDO MPP( 40, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP40_LCD_D20 MPP( 40, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP41_GPIO MPP( 41, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP41_TSMP5 MPP( 41, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP41_AU_I2SLRCLK MPP( 41, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP41_LCD_D21 MPP( 41, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP42_GPIO MPP( 42, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP42_TSMP6 MPP( 42, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP42_AU_I2SMCLK MPP( 42, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP42_LCD_D22 MPP( 42, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP43_GPIO MPP( 43, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP43_TSMP7 MPP( 43, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP43_TDM_CODEC_INTn MPP( 43, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP43_AU_I2SDI MPP( 43, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP43_LCD_D23 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP44_GPIO MPP( 44, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP44_TSMP8 MPP( 44, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP44_TDM_CODEC_RSTn MPP( 44, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP44_AU_EXTCLK MPP( 44, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP44_LCD_CLK MPP( 44, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP45_GPIO MPP( 45, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP45_TSMP9 MPP( 45, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP45_TDM_PCLK MPP( 45, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP245_LCD_E MPP( 45, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP46_GPIO MPP( 46, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP46_TSMP10 MPP( 46, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP46_TDM_FS MPP( 46, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP46_LCD_HSYNC MPP( 46, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP47_GPIO MPP( 47, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP47_TSMP11 MPP( 47, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP47_TDM_DRX MPP( 47, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP47_LCD_VSYNC MPP( 47, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP48_TSMP12 MPP( 48, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP48_LCD_D16 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1, 0 ) +#define MPP49_GPO MPP( 49, 0x0, 0, 1, 0, 0, 0, 0, 1 ) +#define MPP49_TSMP9 MPP( 49, 0x1, 0, 0, 0, 0, 0, 1, 0 ) +#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP49_PTP_CLK MPP( 49, 0x5, 0, 0, 0, 0, 0, 1, 0 ) +#define MPP49_PEX0_CLKREQ MPP( 49, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP49_LCD_D17 MPP( 49, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP_MAX 49 + +void kirkwood_mpp_conf(unsigned int *mpp_list); + +#endif diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c new file mode 100644 index 00000000000..913d032cdb1 --- /dev/null +++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c @@ -0,0 +1,422 @@ +/* + * arch/arm/mach-kirkwood/netxbig_v2-setup.c + * + * LaCie 2Big and 5Big Network v2 board setup + * + * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/mv643xx_eth.h> +#include <linux/input.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/leds.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include <linux/platform_data/leds-kirkwood-netxbig.h> +#include "common.h" +#include "mpp.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data netxbig_v2_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NETXBIG_V2_GPIO_SWITCH_POWER_ON 13 +#define NETXBIG_V2_GPIO_SWITCH_POWER_OFF 15 +#define NETXBIG_V2_GPIO_FUNC_BUTTON 34 + +#define NETXBIG_V2_SWITCH_POWER_ON 0x1 +#define NETXBIG_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button netxbig_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = NETXBIG_V2_SWITCH_POWER_ON, + .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_ON, + .desc = "Back power switch (on|auto)", + .active_low = 1, + }, + [1] = { + .type = EV_SW, + .code = NETXBIG_V2_SWITCH_POWER_OFF, + .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 1, + }, + [2] = { + .code = KEY_OPTION, + .gpio = NETXBIG_V2_GPIO_FUNC_BUTTON, + .desc = "Function button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data netxbig_v2_button_data = { + .buttons = netxbig_v2_buttons, + .nbuttons = ARRAY_SIZE(netxbig_v2_buttons), +}; + +static struct platform_device netxbig_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &netxbig_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO extension LEDs + ****************************************************************************/ + +/* + * The LEDs are controlled by a CPLD and can be configured through a GPIO + * extension bus: + * + * - address register : bit [0-2] -> GPIO [47-49] + * - data register : bit [0-2] -> GPIO [44-46] + * - enable register : GPIO 29 + */ + +static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 }; +static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 }; + +static struct netxbig_gpio_ext netxbig_v2_gpio_ext = { + .addr = netxbig_v2_gpio_ext_addr, + .num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr), + .data = netxbig_v2_gpio_ext_data, + .num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data), + .enable = 29, +}; + +/* + * Address register selection: + * + * addr | register + * ---------------------------- + * 0 | front LED + * 1 | front LED brightness + * 2 | SATA LED brightness + * 3 | SATA0 LED + * 4 | SATA1 LED + * 5 | SATA2 LED + * 6 | SATA3 LED + * 7 | SATA4 LED + * + * Data register configuration: + * + * data | LED brightness + * ------------------------------------------------- + * 0 | min (off) + * - | - + * 7 | max + * + * data | front LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | fix blue on + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + * + * data | SATA LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | SATA activity blink + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | fix blue on + */ + +static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 2, + [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, + [NETXBIG_LED_TIMER1] = 4, + [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, +}; + +static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 1, + [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, + [NETXBIG_LED_TIMER1] = 3, + [NETXBIG_LED_TIMER2] = 7, +}; + +static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 7, + [NETXBIG_LED_SATA] = 1, + [NETXBIG_LED_TIMER1] = 3, + [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, +}; + +static struct netxbig_led_timer netxbig_v2_led_timer[] = { + [0] = { + .delay_on = 500, + .delay_off = 500, + .mode = NETXBIG_LED_TIMER1, + }, + [1] = { + .delay_on = 500, + .delay_off = 1000, + .mode = NETXBIG_LED_TIMER2, + }, +}; + +#define NETXBIG_LED(_name, maddr, mval, baddr) \ + { .name = _name, \ + .mode_addr = maddr, \ + .mode_val = mval, \ + .bright_addr = baddr } + +static struct netxbig_led net2big_v2_leds_ctrl[] = { + NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), + NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1), + NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), + NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), +}; + +static struct netxbig_led_platform_data net2big_v2_leds_data = { + .gpio_ext = &netxbig_v2_gpio_ext, + .timer = netxbig_v2_led_timer, + .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), + .leds = net2big_v2_leds_ctrl, + .num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl), +}; + +static struct netxbig_led net5big_v2_leds_ctrl[] = { + NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), + NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1), + NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata5", 7, netxbig_v2_red_mled, 2), +}; + +static struct netxbig_led_platform_data net5big_v2_leds_data = { + .gpio_ext = &netxbig_v2_gpio_ext, + .timer = netxbig_v2_led_timer, + .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), + .leds = net5big_v2_leds_ctrl, + .num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl), +}; + +static struct platform_device netxbig_v2_leds = { + .name = "leds-netxbig", + .id = -1, + .dev = { + .platform_data = &net2big_v2_leds_data, + }, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int net2big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* GPIO extension ALE */ + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP40_GPIO, /* eSATA presence */ + MPP44_GPIO, /* GPIO extension (data 0) */ + MPP45_GPIO, /* GPIO extension (data 1) */ + MPP46_GPIO, /* GPIO extension (data 2) */ + MPP47_GPIO, /* GPIO extension (addr 0) */ + MPP48_GPIO, /* GPIO extension (addr 1) */ + MPP49_GPIO, /* GPIO extension (addr 2) */ + 0 +}; + +static unsigned int net5big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_GE1_TXD0, + MPP21_GE1_TXD1, + MPP22_GE1_TXD2, + MPP23_GE1_TXD3, + MPP24_GE1_RXD0, + MPP25_GE1_RXD1, + MPP26_GE1_RXD2, + MPP27_GE1_RXD3, + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* GPIO extension ALE */ + MPP30_GE1_RXCTL, + MPP31_GE1_RXCLK, + MPP32_GE1_TCLKOUT, + MPP33_GE1_TXCTL, + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP38_GPIO, /* SATA HDD3 presence */ + MPP39_GPIO, /* SATA HDD4 presence */ + MPP40_GPIO, /* SATA HDD5 presence */ + MPP41_GPIO, /* SATA HDD3 power */ + MPP42_GPIO, /* SATA HDD4 power */ + MPP43_GPIO, /* SATA HDD5 power */ + MPP44_GPIO, /* GPIO extension (data 0) */ + MPP45_GPIO, /* GPIO extension (data 1) */ + MPP46_GPIO, /* GPIO extension (data 2) */ + MPP47_GPIO, /* GPIO extension (addr 0) */ + MPP48_GPIO, /* GPIO extension (addr 1) */ + MPP49_GPIO, /* GPIO extension (addr 2) */ + 0 +}; + +#define NETXBIG_V2_GPIO_POWER_OFF 7 + +static void netxbig_v2_power_off(void) +{ + gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1); +} + +static void __init netxbig_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + if (machine_is_net2big_v2()) + kirkwood_mpp_conf(net2big_v2_mpp_config); + else + kirkwood_mpp_conf(net5big_v2_mpp_config); + + if (machine_is_net2big_v2()) + lacie_v2_hdd_power_init(2); + else + lacie_v2_hdd_power_init(5); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&netxbig_v2_ge00_data); + if (machine_is_net5big_v2()) + kirkwood_ge01_init(&netxbig_v2_ge01_data); + kirkwood_sata_init(&netxbig_v2_sata_data); + kirkwood_uart0_init(); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); + + if (machine_is_net5big_v2()) + netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data; + platform_device_register(&netxbig_v2_leds); + platform_device_register(&netxbig_v2_gpio_buttons); + + if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = netxbig_v2_power_off; + else + pr_err("netxbig_v2: failed to configure power-off GPIO\n"); +} + +#ifdef CONFIG_MACH_NET2BIG_V2 +MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") + .atag_offset = 0x100, + .init_machine = netxbig_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_NET5BIG_V2 +MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") + .atag_offset = 0x100, + .init_machine = netxbig_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c new file mode 100644 index 00000000000..e5cf8410358 --- /dev/null +++ b/arch/arm/mach-kirkwood/openrd-setup.c @@ -0,0 +1,255 @@ +/* + * arch/arm/mach-kirkwood/openrd-setup.c + * + * Marvell OpenRD (Base|Client|Ultimate) 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/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/ata_platform.h> +#include <linux/mv643xx_eth.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include <linux/platform_data/mmc-mvsdio.h> +#include "common.h" +#include "mpp.h" + +static struct mtd_partition openrd_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M, + .mask_flags = MTD_WRITEABLE + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data openrd_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data openrd_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(24), +}; + +static struct mv_sata_platform_data openrd_sata_data = { + .n_ports = 2, +}; + +static struct mvsdio_platform_data openrd_mvsdio_data = { + .gpio_card_detect = 29, /* MPP29 used as SD card detect */ + .gpio_write_protect = -1, +}; + +static unsigned int openrd_mpp_config[] __initdata = { + MPP12_SD_CLK, + MPP13_SD_CMD, + MPP14_SD_D0, + MPP15_SD_D1, + MPP16_SD_D2, + MPP17_SD_D3, + MPP28_GPIO, + MPP29_GPIO, + MPP34_GPIO, + 0 +}; + +/* Configure MPP for UART1 */ +static unsigned int openrd_uart1_mpp_config[] __initdata = { + MPP13_UART1_TXD, + MPP14_UART1_RXD, + 0 +}; + +static struct i2c_board_info i2c_board_info[] __initdata = { + { + I2C_BOARD_INFO("cs42l51", 0x4a), + }, +}; + +static struct platform_device openrd_client_audio_device = { + .name = "openrd-client-audio", + .id = -1, +}; + +static int __initdata uart1; + +static int __init sd_uart_selection(char *str) +{ + uart1 = -EINVAL; + + /* Default is SD. Change if required, for UART */ + if (!str) + return 0; + + if (!strncmp(str, "232", 3)) { + uart1 = 232; + } else if (!strncmp(str, "485", 3)) { + /* OpenRD-Base doesn't have RS485. Treat is as an + * unknown argument & just have default setting - + * which is SD */ + if (machine_is_openrd_base()) { + uart1 = -ENODEV; + return 1; + } + + uart1 = 485; + } + return 1; +} +/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */ +__setup("kw_openrd_init_uart1=", sd_uart_selection); + +static int __init uart1_mpp_config(void) +{ + kirkwood_mpp_conf(openrd_uart1_mpp_config); + + if (gpio_request(34, "SD_UART1_SEL")) { + pr_err("GPIO request 34 failed for SD/UART1 selection\n"); + return -EIO; + } + + if (gpio_request(28, "RS232_RS485_SEL")) { + pr_err("GPIO request 28 failed for RS232/RS485 selection\n"); + gpio_free(34); + return -EIO; + } + + /* Select UART1 + * Pin # 34: 0 => UART1, 1 => SD */ + gpio_direction_output(34, 0); + + /* Select RS232 OR RS485 + * Pin # 28: 0 => RS232, 1 => RS485 */ + if (uart1 == 232) + gpio_direction_output(28, 0); + else + gpio_direction_output(28, 1); + + gpio_free(34); + gpio_free(28); + + return 0; +} + +static void __init openrd_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(openrd_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(openrd_nand_parts, ARRAY_SIZE(openrd_nand_parts), + 25); + + kirkwood_ehci_init(); + + if (machine_is_openrd_ultimate()) { + openrd_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); + openrd_ge01_data.phy_addr = MV643XX_ETH_PHY_ADDR(1); + } + + kirkwood_ge00_init(&openrd_ge00_data); + if (!machine_is_openrd_base()) + kirkwood_ge01_init(&openrd_ge01_data); + + kirkwood_sata_init(&openrd_sata_data); + + kirkwood_i2c_init(); + + if (machine_is_openrd_client() || machine_is_openrd_ultimate()) { + platform_device_register(&openrd_client_audio_device); + i2c_register_board_info(0, i2c_board_info, + ARRAY_SIZE(i2c_board_info)); + kirkwood_audio_init(); + } + + if (uart1 <= 0) { + if (uart1 < 0) + pr_err("Invalid kernel parameter to select UART1. Defaulting to SD. ERROR CODE: %d\n", + uart1); + + /* Select SD + * Pin # 34: 0 => UART1, 1 => SD */ + if (gpio_request(34, "SD_UART1_SEL")) { + pr_err("GPIO request 34 failed for SD/UART1 selection\n"); + } else { + + gpio_direction_output(34, 1); + gpio_free(34); + kirkwood_sdio_init(&openrd_mvsdio_data); + } + } else { + if (!uart1_mpp_config()) + kirkwood_uart1_init(); + } +} + +static int __init openrd_pci_init(void) +{ + if (machine_is_openrd_base() || + machine_is_openrd_client() || + machine_is_openrd_ultimate()) + kirkwood_pcie_init(KW_PCIE0); + + return 0; +} +subsys_initcall(openrd_pci_init); + +#ifdef CONFIG_MACH_OPENRD_BASE +MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board") + /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ + .atag_offset = 0x100, + .init_machine = openrd_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_OPENRD_CLIENT +MACHINE_START(OPENRD_CLIENT, "Marvell OpenRD Client Board") + /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ + .atag_offset = 0x100, + .init_machine = openrd_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_OPENRD_ULTIMATE +MACHINE_START(OPENRD_ULTIMATE, "Marvell OpenRD Ultimate Board") + /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ + .atag_offset = 0x100, + .init_machine = openrd_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 73fccacd1a7..12d86f39f38 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -10,35 +10,82 @@ #include <linux/kernel.h> #include <linux/pci.h> +#include <linux/slab.h> +#include <linux/clk.h> #include <linux/mbus.h> +#include <video/vga.h> #include <asm/irq.h> #include <asm/mach/pci.h> #include <plat/pcie.h> +#include <mach/bridge-regs.h> #include "common.h" +/* These can go away once Kirkwood uses the mvebu-mbus DT binding */ +#define KIRKWOOD_MBUS_PCIE0_MEM_TARGET 0x4 +#define KIRKWOOD_MBUS_PCIE0_MEM_ATTR 0xe8 +#define KIRKWOOD_MBUS_PCIE0_IO_TARGET 0x4 +#define KIRKWOOD_MBUS_PCIE0_IO_ATTR 0xe0 +#define KIRKWOOD_MBUS_PCIE1_MEM_TARGET 0x4 +#define KIRKWOOD_MBUS_PCIE1_MEM_ATTR 0xd8 +#define KIRKWOOD_MBUS_PCIE1_IO_TARGET 0x4 +#define KIRKWOOD_MBUS_PCIE1_IO_ATTR 0xd0 + +static void kirkwood_enable_pcie_clk(const char *port) +{ + struct clk *clk; -#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE) + clk = clk_get_sys("pcie", port); + if (IS_ERR(clk)) { + pr_err("PCIE clock %s missing\n", port); + return; + } + clk_prepare_enable(clk); + clk_put(clk); +} + +/* This function is called very early in the boot when probing the + hardware to determine what we actually are, and what rate tclk is + ticking at. Hence calling kirkwood_enable_pcie_clk() is not + possible since the clk tree has not been created yet. */ +void kirkwood_enable_pcie(void) +{ + u32 curr = readl(CLOCK_GATING_CTRL); + if (!(curr & CGC_PEX0)) + writel(curr | CGC_PEX0, CLOCK_GATING_CTRL); +} -void __init kirkwood_pcie_id(u32 *dev, u32 *rev) +void kirkwood_pcie_id(u32 *dev, u32 *rev) { - *dev = orion_pcie_dev_id(PCIE_BASE); - *rev = orion_pcie_rev(PCIE_BASE); + kirkwood_enable_pcie(); + *dev = orion_pcie_dev_id(PCIE_VIRT_BASE); + *rev = orion_pcie_rev(PCIE_VIRT_BASE); } -static int pcie_valid_config(int bus, int dev) +struct pcie_port { + u8 root_bus_nr; + void __iomem *base; + spinlock_t conf_lock; + int irq; + struct resource res; +}; + +static int pcie_port_map[2]; +static int num_pcie_ports; + +static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* * Don't go out when trying to access -- * 1. nonexisting device on local bus * 2. where there's no device connected (no link) */ - if (bus == 0 && dev == 0) + if (bus == pp->root_bus_nr && dev == 0) return 1; - if (!orion_pcie_link_up(PCIE_BASE)) + if (!orion_pcie_link_up(pp->base)) return 0; - if (bus == 0 && dev != 1) + if (bus == pp->root_bus_nr && dev != 1) return 0; return 1; @@ -50,22 +97,23 @@ static int pcie_valid_config(int bus, int dev) * and then reading the PCIE_CONF_DATA register. Need to make sure these * transactions are atomic. */ -static DEFINE_SPINLOCK(kirkwood_pcie_lock); static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; - if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) { + if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) { *val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; } - spin_lock_irqsave(&kirkwood_pcie_lock, flags); - ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val); - spin_unlock_irqrestore(&kirkwood_pcie_lock, flags); + 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; } @@ -73,15 +121,17 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; - if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) + if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) return PCIBIOS_DEVICE_NOT_FOUND; - spin_lock_irqsave(&kirkwood_pcie_lock, flags); - ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val); - spin_unlock_irqrestore(&kirkwood_pcie_lock, flags); + 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; } @@ -91,59 +141,96 @@ static struct pci_ops pcie_ops = { .write = pcie_wr_conf, }; - -static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) +static void __init pcie0_ioresources_init(struct pcie_port *pp) { - struct resource *res; + pp->base = PCIE_VIRT_BASE; + pp->irq = IRQ_KIRKWOOD_PCIE; /* - * Generic PCIe unit setup. + * IORESOURCE_MEM */ - orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info); + pp->res.name = "PCIe 0 MEM"; + pp->res.start = KIRKWOOD_PCIE_MEM_PHYS_BASE; + pp->res.end = pp->res.start + KIRKWOOD_PCIE_MEM_SIZE - 1; + pp->res.flags = IORESOURCE_MEM; +} - /* - * Request resources. - */ - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("pcie_setup unable to alloc resources"); +static void __init pcie1_ioresources_init(struct pcie_port *pp) +{ + pp->base = PCIE1_VIRT_BASE; + pp->irq = IRQ_KIRKWOOD_PCIE1; /* - * IORESOURCE_IO + * IORESOURCE_MEM */ - res[0].name = "PCIe I/O Space"; - res[0].flags = IORESOURCE_IO; - res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE; - res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; - if (request_resource(&ioport_resource, &res[0])) - panic("Request PCIe IO resource failed\n"); - sys->resource[0] = &res[0]; + pp->res.name = "PCIe 1 MEM"; + pp->res.start = KIRKWOOD_PCIE1_MEM_PHYS_BASE; + pp->res.end = pp->res.start + KIRKWOOD_PCIE1_MEM_SIZE - 1; + pp->res.flags = IORESOURCE_MEM; +} + +static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) +{ + struct pcie_port *pp; + int index; + + if (nr >= num_pcie_ports) + return 0; + + index = pcie_port_map[nr]; + pr_info("PCI: bus%d uses PCIe port %d\n", sys->busnr, index); + + pp = kzalloc(sizeof(*pp), GFP_KERNEL); + if (!pp) + panic("PCIe: failed to allocate pcie_port data"); + sys->private_data = pp; + pp->root_bus_nr = sys->busnr; + spin_lock_init(&pp->conf_lock); + + switch (index) { + case 0: + kirkwood_enable_pcie_clk("0"); + pcie0_ioresources_init(pp); + pci_ioremap_io(SZ_64K * sys->busnr, KIRKWOOD_PCIE_IO_PHYS_BASE); + break; + case 1: + kirkwood_enable_pcie_clk("1"); + pcie1_ioresources_init(pp); + pci_ioremap_io(SZ_64K * sys->busnr, + KIRKWOOD_PCIE1_IO_PHYS_BASE); + break; + default: + panic("PCIe setup: invalid controller %d", index); + } + + if (request_resource(&iomem_resource, &pp->res)) + panic("Request PCIe%d Memory resource failed\n", index); + + pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset); /* - * IORESOURCE_MEM + * Generic PCIe unit setup. */ - res[1].name = "PCIe Memory Space"; - res[1].flags = IORESOURCE_MEM; - res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE; - res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1; - if (request_resource(&iomem_resource, &res[1])) - panic("Request PCIe Memory resource failed\n"); - sys->resource[1] = &res[1]; + orion_pcie_set_local_bus_nr(pp->base, sys->busnr); - sys->resource[2] = NULL; - sys->io_offset = 0; + orion_pcie_setup(pp->base); return 1; } -static void __devinit rc_pci_fixup(struct pci_dev *dev) +/* + * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it + * is operating as a root complex this needs to be switched to + * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on + * the device. Decoding setup is handled by the orion code. + */ +static void rc_pci_fixup(struct pci_dev *dev) { - /* - * Prevent enumeration of root complex. - */ if (dev->bus->parent == NULL && dev->devfn == 0) { int i; + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dev->resource[i].start = 0; dev->resource[i].end = 0; @@ -153,35 +240,57 @@ static void __devinit rc_pci_fixup(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); -static struct pci_bus __init * -kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys) +static int __init kirkwood_pcie_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { - struct pci_bus *bus; - - if (nr == 0) { - bus = pci_scan_bus(sys->busnr, &pcie_ops, sys); - } else { - bus = NULL; - BUG(); - } - - return bus; -} + struct pci_sys_data *sys = dev->sysdata; + struct pcie_port *pp = sys->private_data; -static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - return IRQ_KIRKWOOD_PCIE; + return pp->irq; } static struct hw_pci kirkwood_pci __initdata = { - .nr_controllers = 1, - .swizzle = pci_std_swizzle, .setup = kirkwood_pcie_setup, - .scan = kirkwood_pcie_scan_bus, .map_irq = kirkwood_pcie_map_irq, + .ops = &pcie_ops, }; -void __init kirkwood_pcie_init(void) +static void __init add_pcie_port(int index, void __iomem *base) +{ + pcie_port_map[num_pcie_ports++] = index; + pr_info("Kirkwood PCIe port %d: link %s\n", index, + orion_pcie_link_up(base) ? "up" : "down"); +} + +void __init kirkwood_pcie_init(unsigned int portmask) { + mvebu_mbus_add_window_remap_by_id(KIRKWOOD_MBUS_PCIE0_IO_TARGET, + KIRKWOOD_MBUS_PCIE0_IO_ATTR, + KIRKWOOD_PCIE_IO_PHYS_BASE, + KIRKWOOD_PCIE_IO_SIZE, + KIRKWOOD_PCIE_IO_BUS_BASE); + mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_PCIE0_MEM_TARGET, + KIRKWOOD_MBUS_PCIE0_MEM_ATTR, + KIRKWOOD_PCIE_MEM_PHYS_BASE, + KIRKWOOD_PCIE_MEM_SIZE); + mvebu_mbus_add_window_remap_by_id(KIRKWOOD_MBUS_PCIE1_IO_TARGET, + KIRKWOOD_MBUS_PCIE1_IO_ATTR, + KIRKWOOD_PCIE1_IO_PHYS_BASE, + KIRKWOOD_PCIE1_IO_SIZE, + KIRKWOOD_PCIE1_IO_BUS_BASE); + mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_PCIE1_MEM_TARGET, + KIRKWOOD_MBUS_PCIE1_MEM_ATTR, + KIRKWOOD_PCIE1_MEM_PHYS_BASE, + KIRKWOOD_PCIE1_MEM_SIZE); + + vga_base = KIRKWOOD_PCIE_MEM_PHYS_BASE; + + if (portmask & KW_PCIE0) + add_pcie_port(0, PCIE_VIRT_BASE); + + if (portmask & KW_PCIE1) + add_pcie_port(1, PCIE1_VIRT_BASE); + + kirkwood_pci.nr_controllers = num_pcie_ports; pci_common_init(&kirkwood_pci); } diff --git a/arch/arm/mach-kirkwood/pm.c b/arch/arm/mach-kirkwood/pm.c new file mode 100644 index 00000000000..8e5e0329d04 --- /dev/null +++ b/arch/arm/mach-kirkwood/pm.c @@ -0,0 +1,76 @@ +/* + * Power Management driver for Marvell Kirkwood SoCs + * + * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com> + * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, + * version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/suspend.h> +#include <linux/io.h> +#include <mach/bridge-regs.h> +#include "common.h" + +static void __iomem *ddr_operation_base; +static void __iomem *memory_pm_ctrl; + +static void kirkwood_low_power(void) +{ + u32 mem_pm_ctrl; + + mem_pm_ctrl = readl(memory_pm_ctrl); + + /* Set peripherals to low-power mode */ + writel_relaxed(~0, memory_pm_ctrl); + + /* Set DDR in self-refresh */ + writel_relaxed(0x7, ddr_operation_base); + + /* + * Set CPU in wait-for-interrupt state. + * This disables the CPU core clocks, + * the array clocks, and also the L2 controller. + */ + cpu_do_idle(); + + writel_relaxed(mem_pm_ctrl, memory_pm_ctrl); +} + +static int kirkwood_suspend_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + kirkwood_low_power(); + break; + default: + return -EINVAL; + } + return 0; +} + +static int kirkwood_pm_valid_standby(suspend_state_t state) +{ + return state == PM_SUSPEND_STANDBY; +} + +static const struct platform_suspend_ops kirkwood_suspend_ops = { + .enter = kirkwood_suspend_enter, + .valid = kirkwood_pm_valid_standby, +}; + +void __init kirkwood_pm_init(void) +{ + ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4); + memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4); + + suspend_set_ops(&kirkwood_suspend_ops); +} diff --git a/arch/arm/mach-kirkwood/pm.h b/arch/arm/mach-kirkwood/pm.h new file mode 100644 index 00000000000..21e7530f368 --- /dev/null +++ b/arch/arm/mach-kirkwood/pm.h @@ -0,0 +1,26 @@ +/* + * Power Management driver for Marvell Kirkwood SoCs + * + * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com> + * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, + * version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_KIRKWOOD_PM_H +#define __ARCH_KIRKWOOD_PM_H + +#ifdef CONFIG_PM +void kirkwood_pm_init(void); +#else +static inline void kirkwood_pm_init(void) {}; +#endif + +#endif diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c index b1d1a87a682..e4fd3129d36 100644 --- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c @@ -11,20 +11,15 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/pci.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/gpio.h> #include <linux/spi/flash.h> #include <linux/spi/spi.h> -#include <linux/spi/orion_spi.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/pci.h> #include <mach/kirkwood.h> +#include <plat/orion-gpio.h> #include "common.h" #define RD88F6192_GPIO_USB_VBUS 10 @@ -59,22 +54,24 @@ static void __init rd88f6192_init(void) */ kirkwood_init(); + orion_gpio_set_valid(RD88F6192_GPIO_USB_VBUS, 1); + if (gpio_request(RD88F6192_GPIO_USB_VBUS, "USB VBUS") != 0 || + gpio_direction_output(RD88F6192_GPIO_USB_VBUS, 1) != 0) + pr_err("RD-88F6192-NAS: failed to setup USB VBUS GPIO\n"); + kirkwood_ehci_init(); kirkwood_ge00_init(&rd88f6192_ge00_data); - kirkwood_rtc_init(); kirkwood_sata_init(&rd88f6192_sata_data); spi_register_board_info(rd88F6192_spi_slave_info, ARRAY_SIZE(rd88F6192_spi_slave_info)); kirkwood_spi_init(); kirkwood_uart0_init(); - kirkwood_xor0_init(); - kirkwood_xor1_init(); } static int __init rd88f6192_pci_init(void) { if (machine_is_rd88f6192_nas()) - kirkwood_pcie_init(); + kirkwood_pcie_init(KW_PCIE0); return 0; } @@ -82,11 +79,11 @@ subsys_initcall(rd88f6192_pci_init); MACHINE_START(RD88F6192_NAS, "Marvell RD-88F6192-NAS Development Board") /* Maintainer: Saeed Bishara <saeed@marvell.com> */ - .phys_io = KIRKWOOD_REGS_PHYS_BASE, - .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, + .atag_offset = 0x100, .init_machine = rd88f6192_init, .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, MACHINE_END diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c index 9a0e905d10c..5154bd2a3ad 100644 --- a/arch/arm/mach-kirkwood/rd88f6281-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -11,21 +11,18 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/pci.h> #include <linux/irq.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/nand.h> -#include <linux/timer.h> +#include <linux/mtd/partitions.h> #include <linux/ata_platform.h> #include <linux/mv643xx_eth.h> #include <linux/ethtool.h> #include <net/dsa.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/pci.h> #include <mach/kirkwood.h> -#include <plat/orion_nand.h> +#include <linux/platform_data/mmc-mvsdio.h> #include "common.h" +#include "mpp.h" static struct mtd_partition rd88f6281_nand_parts[] = { { @@ -43,39 +40,13 @@ static struct mtd_partition rd88f6281_nand_parts[] = { }, }; -static struct resource rd88f6281_nand_resource = { - .flags = IORESOURCE_MEM, - .start = KIRKWOOD_NAND_MEM_PHYS_BASE, - .end = KIRKWOOD_NAND_MEM_PHYS_BASE + - KIRKWOOD_NAND_MEM_SIZE - 1, -}; - -static struct orion_nand_data rd88f6281_nand_data = { - .parts = rd88f6281_nand_parts, - .nr_parts = ARRAY_SIZE(rd88f6281_nand_parts), - .cle = 0, - .ale = 1, - .width = 8, - .chip_delay = 25, -}; - -static struct platform_device rd88f6281_nand_flash = { - .name = "orion_nand", - .id = -1, - .dev = { - .platform_data = &rd88f6281_nand_data, - }, - .resource = &rd88f6281_nand_resource, - .num_resources = 1, -}; - static struct mv643xx_eth_platform_data rd88f6281_ge00_data = { .phy_addr = MV643XX_ETH_PHY_NONE, .speed = SPEED_1000, .duplex = DUPLEX_FULL, }; -static struct dsa_platform_data rd88f6281_switch_data = { +static struct dsa_chip_data rd88f6281_switch_chip_data = { .port_names[0] = "lan1", .port_names[1] = "lan2", .port_names[2] = "lan3", @@ -83,6 +54,11 @@ static struct dsa_platform_data rd88f6281_switch_data = { .port_names[5] = "cpu", }; +static struct dsa_platform_data rd88f6281_switch_plat_data = { + .nr_chips = 1, + .chip = &rd88f6281_switch_chip_data, +}; + static struct mv643xx_eth_platform_data rd88f6281_ge01_data = { .phy_addr = MV643XX_ETH_PHY_ADDR(11), }; @@ -91,6 +67,16 @@ static struct mv_sata_platform_data rd88f6281_sata_data = { .n_ports = 2, }; +static struct mvsdio_platform_data rd88f6281_mvsdio_data = { + .gpio_card_detect = 28, + .gpio_write_protect = -1, +}; + +static unsigned int rd88f6281_mpp_config[] __initdata = { + MPP28_GPIO, + 0 +}; + static void __init rd88f6281_init(void) { u32 dev, rev; @@ -99,30 +85,32 @@ static void __init rd88f6281_init(void) * Basic setup. Needs to be called early. */ kirkwood_init(); + kirkwood_mpp_conf(rd88f6281_mpp_config); + kirkwood_nand_init(rd88f6281_nand_parts, + ARRAY_SIZE(rd88f6281_nand_parts), + 25); kirkwood_ehci_init(); kirkwood_ge00_init(&rd88f6281_ge00_data); kirkwood_pcie_id(&dev, &rev); if (rev == MV88F6281_REV_A0) { - rd88f6281_switch_data.sw_addr = 10; + rd88f6281_switch_chip_data.sw_addr = 10; kirkwood_ge01_init(&rd88f6281_ge01_data); } else { - rd88f6281_switch_data.port_names[4] = "wan"; + rd88f6281_switch_chip_data.port_names[4] = "wan"; } - kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ); + kirkwood_ge00_switch_init(&rd88f6281_switch_plat_data, NO_IRQ); - kirkwood_rtc_init(); kirkwood_sata_init(&rd88f6281_sata_data); + kirkwood_sdio_init(&rd88f6281_mvsdio_data); kirkwood_uart0_init(); - - platform_device_register(&rd88f6281_nand_flash); } static int __init rd88f6281_pci_init(void) { if (machine_is_rd88f6281()) - kirkwood_pcie_init(); + kirkwood_pcie_init(KW_PCIE0); return 0; } @@ -130,11 +118,11 @@ subsys_initcall(rd88f6281_pci_init); MACHINE_START(RD88F6281, "Marvell RD-88F6281 Reference Board") /* Maintainer: Saeed Bishara <saeed@marvell.com> */ - .phys_io = KIRKWOOD_REGS_PHYS_BASE, - .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, + .atag_offset = 0x100, .init_machine = rd88f6281_init, .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, MACHINE_END diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c new file mode 100644 index 00000000000..8736f8c9751 --- /dev/null +++ b/arch/arm/mach-kirkwood/t5325-setup.c @@ -0,0 +1,216 @@ +/* + * + * HP t5325 Thin Client setup + * + * Copyright (C) 2010 Martin Michlmayr <tbm@cyrius.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> +#include <linux/i2c.h> +#include <linux/mv643xx_eth.h> +#include <linux/ata_platform.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <sound/alc5623.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include "common.h" +#include "mpp.h" + +static struct mtd_partition hp_t5325_partitions[] = { + { + .name = "u-boot env", + .size = SZ_64K, + .offset = SZ_512K + SZ_256K, + }, + { + .name = "permanent u-boot env", + .size = SZ_64K, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "HP env", + .size = SZ_64K, + .offset = MTDPART_OFS_APPEND, + }, + { + .name = "u-boot", + .size = SZ_512K, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "SSD firmware", + .size = SZ_256K, + .offset = SZ_512K, + }, +}; + +static const struct flash_platform_data hp_t5325_flash = { + .type = "mx25l8005", + .name = "spi_flash", + .parts = hp_t5325_partitions, + .nr_parts = ARRAY_SIZE(hp_t5325_partitions), +}; + +static struct spi_board_info __initdata hp_t5325_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &hp_t5325_flash, + .irq = -1, + }, +}; + +static struct mv643xx_eth_platform_data hp_t5325_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv_sata_platform_data hp_t5325_sata_data = { + .n_ports = 2, +}; + +static struct gpio_keys_button hp_t5325_buttons[] = { + { + .code = KEY_POWER, + .gpio = 45, + .desc = "Power", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data hp_t5325_button_data = { + .buttons = hp_t5325_buttons, + .nbuttons = ARRAY_SIZE(hp_t5325_buttons), +}; + +static struct platform_device hp_t5325_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &hp_t5325_button_data, + } +}; + +static struct platform_device hp_t5325_audio_device = { + .name = "t5325-audio", + .id = -1, +}; + +static unsigned int hp_t5325_mpp_config[] __initdata = { + MPP0_NF_IO2, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP6_SYSRST_OUTn, + MPP7_SPI_SCn, + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_SD_CLK, + MPP13_GPIO, + MPP14_GPIO, + MPP15_GPIO, + MPP16_GPIO, + MPP17_GPIO, + MPP18_NF_IO0, + MPP19_NF_IO1, + MPP20_GPIO, + MPP21_GPIO, + MPP22_GPIO, + MPP23_GPIO, + MPP32_GPIO, + MPP33_GE1_TXCTL, + MPP39_AU_I2SBCLK, + MPP40_AU_I2SDO, + MPP43_AU_I2SDI, + MPP41_AU_I2SLRCLK, + MPP42_AU_I2SMCLK, + MPP45_GPIO, /* Power button */ + MPP48_GPIO, /* Board power off */ + 0 +}; + +static struct alc5623_platform_data alc5621_data = { + .add_ctrl = 0x3700, + .jack_det_ctrl = 0x4810, +}; + +static struct i2c_board_info i2c_board_info[] __initdata = { + { + I2C_BOARD_INFO("alc5621", 0x1a), + .platform_data = &alc5621_data, + }, +}; + +#define HP_T5325_GPIO_POWER_OFF 48 + +static void hp_t5325_power_off(void) +{ + gpio_set_value(HP_T5325_GPIO_POWER_OFF, 1); +} + +static void __init hp_t5325_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(hp_t5325_mpp_config); + + kirkwood_uart0_init(); + spi_register_board_info(hp_t5325_spi_slave_info, + ARRAY_SIZE(hp_t5325_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_i2c_init(); + kirkwood_ge00_init(&hp_t5325_ge00_data); + kirkwood_sata_init(&hp_t5325_sata_data); + kirkwood_ehci_init(); + platform_device_register(&hp_t5325_button_device); + platform_device_register(&hp_t5325_audio_device); + + i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info)); + kirkwood_audio_init(); + + if (gpio_request(HP_T5325_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(HP_T5325_GPIO_POWER_OFF, 0) == 0) + pm_power_off = hp_t5325_power_off; + else + pr_err("t5325: failed to configure power-off GPIO\n"); +} + +static int __init hp_t5325_pci_init(void) +{ + if (machine_is_t5325()) + kirkwood_pcie_init(KW_PCIE0); + + return 0; +} +subsys_initcall(hp_t5325_pci_init); + +MACHINE_START(T5325, "HP t5325 Thin Client") + /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ + .atag_offset = 0x100, + .init_machine = hp_t5325_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c new file mode 100644 index 00000000000..e1267d6b468 --- /dev/null +++ b/arch/arm/mach-kirkwood/ts219-setup.c @@ -0,0 +1,142 @@ +/* + * + * QNAP TS-11x/TS-21x Turbo NAS Board Setup + * + * Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com> + * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/mv643xx_eth.h> +#include <linux/ata_platform.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include "common.h" +#include "mpp.h" +#include "tsx1x-common.h" + +static struct i2c_board_info __initdata qnap_ts219_i2c_rtc = { + I2C_BOARD_INFO("s35390a", 0x30), +}; + +static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv_sata_platform_data qnap_ts219_sata_data = { + .n_ports = 2, +}; + +static struct gpio_keys_button qnap_ts219_buttons[] = { + { + .code = KEY_COPY, + .gpio = 15, + .desc = "USB Copy", + .active_low = 1, + }, + { + .code = KEY_RESTART, + .gpio = 16, + .desc = "Reset", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data qnap_ts219_button_data = { + .buttons = qnap_ts219_buttons, + .nbuttons = ARRAY_SIZE(qnap_ts219_buttons), +}; + +static struct platform_device qnap_ts219_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &qnap_ts219_button_data, + } +}; + +static unsigned int qnap_ts219_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP4_SATA1_ACTn, + MPP5_SATA0_ACTn, + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_UART1_TXD, /* PIC controller */ + MPP14_UART1_RXD, /* PIC controller */ + MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */ + MPP16_GPIO, /* Reset button (on devices with 88F6281) */ + MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ + MPP37_GPIO, /* Reset button (on devices with 88F6282) */ + MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */ + MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */ + 0 +}; + +static void __init qnap_ts219_init(void) +{ + u32 dev, rev; + + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(qnap_ts219_mpp_config); + + kirkwood_uart0_init(); + kirkwood_uart1_init(); /* A PIC controller is connected here. */ + qnap_tsx1x_register_flash(); + kirkwood_i2c_init(); + i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1); + + kirkwood_pcie_id(&dev, &rev); + if (dev == MV88F6282_DEV_ID) { + qnap_ts219_buttons[0].gpio = 43; /* USB Copy button */ + qnap_ts219_buttons[1].gpio = 37; /* Reset button */ + qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); + } + + kirkwood_ge00_init(&qnap_ts219_ge00_data); + kirkwood_sata_init(&qnap_ts219_sata_data); + kirkwood_ehci_init(); + platform_device_register(&qnap_ts219_button_device); + + pm_power_off = qnap_tsx1x_power_off; + +} + +static int __init ts219_pci_init(void) +{ + if (machine_is_ts219()) + kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0); + + return 0; +} +subsys_initcall(ts219_pci_init); + +MACHINE_START(TS219, "QNAP TS-119/TS-219") + /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ + .atag_offset = 0x100, + .init_machine = qnap_ts219_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c new file mode 100644 index 00000000000..81d585806b2 --- /dev/null +++ b/arch/arm/mach-kirkwood/ts41x-setup.c @@ -0,0 +1,186 @@ +/* + * + * QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS Board Setup + * + * Copyright (C) 2009-2010 Martin Michlmayr <tbm@cyrius.com> + * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/mv643xx_eth.h> +#include <linux/ata_platform.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/io.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include "common.h" +#include "mpp.h" +#include "tsx1x-common.h" + +/* for the PCIe reset workaround */ +#include <plat/pcie.h> + + +#define QNAP_TS41X_JUMPER_JP1 45 + +static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = { + I2C_BOARD_INFO("s35390a", 0x30), +}; + +static struct mv643xx_eth_platform_data qnap_ts41x_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data qnap_ts41x_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mv_sata_platform_data qnap_ts41x_sata_data = { + .n_ports = 2, +}; + +static struct gpio_keys_button qnap_ts41x_buttons[] = { + { + .code = KEY_COPY, + .gpio = 43, + .desc = "USB Copy", + .active_low = 1, + }, + { + .code = KEY_RESTART, + .gpio = 37, + .desc = "Reset", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data qnap_ts41x_button_data = { + .buttons = qnap_ts41x_buttons, + .nbuttons = ARRAY_SIZE(qnap_ts41x_buttons), +}; + +static struct platform_device qnap_ts41x_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &qnap_ts41x_button_data, + } +}; + +static unsigned int qnap_ts41x_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_PEX_RST_OUTn, + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_UART1_TXD, /* PIC controller */ + MPP14_UART1_RXD, /* PIC controller */ + MPP15_SATA0_ACTn, + MPP16_SATA1_ACTn, + MPP20_GE1_TXD0, + MPP21_GE1_TXD1, + MPP22_GE1_TXD2, + MPP23_GE1_TXD3, + MPP24_GE1_RXD0, + MPP25_GE1_RXD1, + MPP26_GE1_RXD2, + MPP27_GE1_RXD3, + MPP30_GE1_RXCTL, + MPP31_GE1_RXCLK, + MPP32_GE1_TCLKOUT, + MPP33_GE1_TXCTL, + MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ + MPP37_GPIO, /* Reset button */ + MPP43_GPIO, /* USB Copy button */ + MPP44_GPIO, /* Board ID: 0: TS-419U, 1: TS-419 */ + MPP45_GPIO, /* JP1: 0: LCD, 1: serial console */ + MPP46_GPIO, /* External SATA HDD1 error indicator */ + MPP47_GPIO, /* External SATA HDD2 error indicator */ + MPP48_GPIO, /* External SATA HDD3 error indicator */ + MPP49_GPIO, /* External SATA HDD4 error indicator */ + 0 +}; + +static void __init qnap_ts41x_init(void) +{ + u32 dev, rev; + + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(qnap_ts41x_mpp_config); + + kirkwood_uart0_init(); + kirkwood_uart1_init(); /* A PIC controller is connected here. */ + qnap_tsx1x_register_flash(); + kirkwood_i2c_init(); + i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1); + + kirkwood_pcie_id(&dev, &rev); + if (dev == MV88F6282_DEV_ID) { + qnap_ts41x_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); + qnap_ts41x_ge01_data.phy_addr = MV643XX_ETH_PHY_ADDR(1); + } + kirkwood_ge00_init(&qnap_ts41x_ge00_data); + kirkwood_ge01_init(&qnap_ts41x_ge01_data); + + kirkwood_sata_init(&qnap_ts41x_sata_data); + kirkwood_ehci_init(); + platform_device_register(&qnap_ts41x_button_device); + + pm_power_off = qnap_tsx1x_power_off; + + if (gpio_request(QNAP_TS41X_JUMPER_JP1, "JP1") == 0) + gpio_export(QNAP_TS41X_JUMPER_JP1, 0); +} + +static int __init ts41x_pci_init(void) +{ + if (machine_is_ts41x()) { + u32 dev, rev; + + /* + * Without this explicit reset, the PCIe SATA controller + * (Marvell 88sx7042/sata_mv) is known to stop working + * after a few minutes. + */ + orion_pcie_reset(PCIE_VIRT_BASE); + + kirkwood_pcie_id(&dev, &rev); + if (dev == MV88F6282_DEV_ID) + kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0); + else + kirkwood_pcie_init(KW_PCIE0); + } + return 0; +} +subsys_initcall(ts41x_pci_init); + +MACHINE_START(TS41X, "QNAP TS-41x") + /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ + .atag_offset = 0x100, + .init_machine = qnap_ts41x_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/tsx1x-common.c b/arch/arm/mach-kirkwood/tsx1x-common.c new file mode 100644 index 00000000000..cec87cef76c --- /dev/null +++ b/arch/arm/mach-kirkwood/tsx1x-common.c @@ -0,0 +1,113 @@ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> +#include <linux/serial_reg.h> +#include <mach/kirkwood.h> +#include "common.h" +#include "tsx1x-common.h" + +/* + * QNAP TS-x1x Boards flash + */ + +/**************************************************************************** + * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the + * partitions on the device because we want to keep compatibility with + * the QNAP firmware. + * Layout as used by QNAP: + * 0x00000000-0x00080000 : "U-Boot" + * 0x00200000-0x00400000 : "Kernel" + * 0x00400000-0x00d00000 : "RootFS" + * 0x00d00000-0x01000000 : "RootFS2" + * 0x00080000-0x000c0000 : "U-Boot Config" + * 0x000c0000-0x00200000 : "NAS Config" + * + * We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout + * used by the QNAP TS-109/TS-209. + * + ***************************************************************************/ + +static struct mtd_partition qnap_tsx1x_partitions[] = { + { + .name = "U-Boot", + .size = 0x00080000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Kernel", + .size = 0x00200000, + .offset = 0x00200000, + }, { + .name = "RootFS1", + .size = 0x00900000, + .offset = 0x00400000, + }, { + .name = "RootFS2", + .size = 0x00300000, + .offset = 0x00d00000, + }, { + .name = "U-Boot Config", + .size = 0x00040000, + .offset = 0x00080000, + }, { + .name = "NAS Config", + .size = 0x00140000, + .offset = 0x000c0000, + }, +}; + +static const struct flash_platform_data qnap_tsx1x_flash = { + .type = "m25p128", + .name = "spi_flash", + .parts = qnap_tsx1x_partitions, + .nr_parts = ARRAY_SIZE(qnap_tsx1x_partitions), +}; + +static struct spi_board_info __initdata qnap_tsx1x_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &qnap_tsx1x_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +void __init qnap_tsx1x_register_flash(void) +{ + spi_register_board_info(qnap_tsx1x_spi_slave_info, + ARRAY_SIZE(qnap_tsx1x_spi_slave_info)); + kirkwood_spi_init(); +} + + +/***************************************************************************** + * QNAP TS-x1x specific power off method via UART1-attached PIC + ****************************************************************************/ + +#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) + +void qnap_tsx1x_power_off(void) +{ + /* 19200 baud divisor */ + const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200)); + + pr_info("%s: triggering power-off...\n", __func__); + + /* hijack UART1 and reset into sane state (19200,8n1) */ + writel(0x83, UART1_REG(LCR)); + writel(divisor & 0xff, UART1_REG(DLL)); + writel((divisor >> 8) & 0xff, UART1_REG(DLM)); + writel(0x03, UART1_REG(LCR)); + writel(0x00, UART1_REG(IER)); + writel(0x00, UART1_REG(FCR)); + writel(0x00, UART1_REG(MCR)); + + /* send the power-off command 'A' to PIC */ + writel('A', UART1_REG(TX)); +} + diff --git a/arch/arm/mach-kirkwood/tsx1x-common.h b/arch/arm/mach-kirkwood/tsx1x-common.h new file mode 100644 index 00000000000..7fa037361b5 --- /dev/null +++ b/arch/arm/mach-kirkwood/tsx1x-common.h @@ -0,0 +1,7 @@ +#ifndef __ARCH_KIRKWOOD_TSX1X_COMMON_H +#define __ARCH_KIRKWOOD_TSX1X_COMMON_H + +extern void __init qnap_tsx1x_register_flash(void); +extern void qnap_tsx1x_power_off(void); + +#endif |
