aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-kirkwood/ts41x-setup.c
diff options
context:
space:
mode:
authorMartin Michlmayr <tbm@cyrius.com>2009-11-05 12:45:32 -0500
committerNicolas Pitre <nico@fluxnic.net>2009-11-13 12:14:23 -0500
commitf3a131b90b8f9bbcf46edc3bdd5246a744ba0017 (patch)
treec1c88a86a1d35151eb60e51266f562b2fd57e915 /arch/arm/mach-kirkwood/ts41x-setup.c
parent2bf30108435339c4cf149f9d279d0dc961345393 (diff)
[ARM] Kirkwood: Add support for QNAP TS-41x Turbo NAS
Add support for the QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS. Signed-off-by: Martin Michlmayr <tbm@cyrius.com> Signed-off-by: Nicolas Pitre <nico@marvell.com>
Diffstat (limited to 'arch/arm/mach-kirkwood/ts41x-setup.c')
-rw-r--r--arch/arm/mach-kirkwood/ts41x-setup.c253
1 files changed, 253 insertions, 0 deletions
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
new file mode 100644
index 000000000000..a1972c948503
--- /dev/null
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -0,0 +1,253 @@
1/*
2 *
3 * QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS Board Setup
4 *
5 * Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com>
6 * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/mtd/physmap.h>
18#include <linux/spi/flash.h>
19#include <linux/spi/spi.h>
20#include <linux/spi/orion_spi.h>
21#include <linux/i2c.h>
22#include <linux/mv643xx_eth.h>
23#include <linux/ata_platform.h>
24#include <linux/gpio_keys.h>
25#include <linux/input.h>
26#include <linux/timex.h>
27#include <linux/serial_reg.h>
28#include <linux/pci.h>
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <mach/kirkwood.h>
32#include "common.h"
33#include "mpp.h"
34
35/****************************************************************************
36 * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the
37 * partitions on the device because we want to keep compatability with
38 * the QNAP firmware.
39 * Layout as used by QNAP:
40 * 0x00000000-0x00080000 : "U-Boot"
41 * 0x00200000-0x00400000 : "Kernel"
42 * 0x00400000-0x00d00000 : "RootFS"
43 * 0x00d00000-0x01000000 : "RootFS2"
44 * 0x00080000-0x000c0000 : "U-Boot Config"
45 * 0x000c0000-0x00200000 : "NAS Config"
46 *
47 * We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout
48 * used by the QNAP TS-109/TS-209.
49 *
50 ***************************************************************************/
51
52static struct mtd_partition qnap_ts41x_partitions[] = {
53 {
54 .name = "U-Boot",
55 .size = 0x00080000,
56 .offset = 0,
57 .mask_flags = MTD_WRITEABLE,
58 }, {
59 .name = "Kernel",
60 .size = 0x00200000,
61 .offset = 0x00200000,
62 }, {
63 .name = "RootFS1",
64 .size = 0x00900000,
65 .offset = 0x00400000,
66 }, {
67 .name = "RootFS2",
68 .size = 0x00300000,
69 .offset = 0x00d00000,
70 }, {
71 .name = "U-Boot Config",
72 .size = 0x00040000,
73 .offset = 0x00080000,
74 }, {
75 .name = "NAS Config",
76 .size = 0x00140000,
77 .offset = 0x000c0000,
78 },
79};
80
81static const struct flash_platform_data qnap_ts41x_flash = {
82 .type = "m25p128",
83 .name = "spi_flash",
84 .parts = qnap_ts41x_partitions,
85 .nr_parts = ARRAY_SIZE(qnap_ts41x_partitions),
86};
87
88static struct spi_board_info __initdata qnap_ts41x_spi_slave_info[] = {
89 {
90 .modalias = "m25p80",
91 .platform_data = &qnap_ts41x_flash,
92 .irq = -1,
93 .max_speed_hz = 20000000,
94 .bus_num = 0,
95 .chip_select = 0,
96 },
97};
98
99static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = {
100 I2C_BOARD_INFO("s35390a", 0x30),
101};
102
103static struct mv643xx_eth_platform_data qnap_ts41x_ge00_data = {
104 .phy_addr = MV643XX_ETH_PHY_ADDR(8),
105};
106
107static struct mv643xx_eth_platform_data qnap_ts41x_ge01_data = {
108 .phy_addr = MV643XX_ETH_PHY_ADDR(0),
109};
110
111static struct mv_sata_platform_data qnap_ts41x_sata_data = {
112 .n_ports = 2,
113};
114
115static struct gpio_keys_button qnap_ts41x_buttons[] = {
116 {
117 .code = KEY_COPY,
118 .gpio = 43,
119 .desc = "USB Copy",
120 .active_low = 1,
121 },
122 {
123 .code = KEY_RESTART,
124 .gpio = 37,
125 .desc = "Reset",
126 .active_low = 1,
127 },
128};
129
130static struct gpio_keys_platform_data qnap_ts41x_button_data = {
131 .buttons = qnap_ts41x_buttons,
132 .nbuttons = ARRAY_SIZE(qnap_ts41x_buttons),
133};
134
135static struct platform_device qnap_ts41x_button_device = {
136 .name = "gpio-keys",
137 .id = -1,
138 .num_resources = 0,
139 .dev = {
140 .platform_data = &qnap_ts41x_button_data,
141 }
142};
143
144static unsigned int qnap_ts41x_mpp_config[] __initdata = {
145 MPP0_SPI_SCn,
146 MPP1_SPI_MOSI,
147 MPP2_SPI_SCK,
148 MPP3_SPI_MISO,
149 MPP6_SYSRST_OUTn,
150 MPP7_PEX_RST_OUTn,
151 MPP8_TW_SDA,
152 MPP9_TW_SCK,
153 MPP10_UART0_TXD,
154 MPP11_UART0_RXD,
155 MPP13_UART1_TXD, /* PIC controller */
156 MPP14_UART1_RXD, /* PIC controller */
157 MPP15_SATA0_ACTn,
158 MPP16_SATA1_ACTn,
159 MPP20_GE1_0,
160 MPP21_GE1_1,
161 MPP22_GE1_2,
162 MPP23_GE1_3,
163 MPP24_GE1_4,
164 MPP25_GE1_5,
165 MPP26_GE1_6,
166 MPP27_GE1_7,
167 MPP30_GE1_10,
168 MPP31_GE1_11,
169 MPP32_GE1_12,
170 MPP33_GE1_13,
171 MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */
172 MPP37_GPIO, /* Reset button */
173 MPP43_GPIO, /* USB Copy button */
174 MPP44_GPIO, /* Board ID: 0: TS-419U, 1: TS-419 */
175 MPP45_GPIO, /* JP1: 0: console, 1: LCD */
176 MPP46_GPIO, /* External SATA HDD1 error indicator */
177 MPP47_GPIO, /* External SATA HDD2 error indicator */
178 MPP48_GPIO, /* External SATA HDD3 error indicator */
179 MPP49_GPIO, /* External SATA HDD4 error indicator */
180 0
181};
182
183
184/*****************************************************************************
185 * QNAP TS-x19 specific power off method via UART1-attached PIC
186 ****************************************************************************/
187
188#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
189
190void qnap_ts41x_power_off(void)
191{
192 /* 19200 baud divisor */
193 const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200));
194
195 pr_info("%s: triggering power-off...\n", __func__);
196
197 /* hijack UART1 and reset into sane state (19200,8n1) */
198 writel(0x83, UART1_REG(LCR));
199 writel(divisor & 0xff, UART1_REG(DLL));
200 writel((divisor >> 8) & 0xff, UART1_REG(DLM));
201 writel(0x03, UART1_REG(LCR));
202 writel(0x00, UART1_REG(IER));
203 writel(0x00, UART1_REG(FCR));
204 writel(0x00, UART1_REG(MCR));
205
206 /* send the power-off command 'A' to PIC */
207 writel('A', UART1_REG(TX));
208}
209
210static void __init qnap_ts41x_init(void)
211{
212 /*
213 * Basic setup. Needs to be called early.
214 */
215 kirkwood_init();
216 kirkwood_mpp_conf(qnap_ts41x_mpp_config);
217
218 kirkwood_uart0_init();
219 kirkwood_uart1_init(); /* A PIC controller is connected here. */
220 spi_register_board_info(qnap_ts41x_spi_slave_info,
221 ARRAY_SIZE(qnap_ts41x_spi_slave_info));
222 kirkwood_spi_init();
223 kirkwood_i2c_init();
224 i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1);
225 kirkwood_ge00_init(&qnap_ts41x_ge00_data);
226 kirkwood_ge01_init(&qnap_ts41x_ge01_data);
227 kirkwood_sata_init(&qnap_ts41x_sata_data);
228 kirkwood_ehci_init();
229 platform_device_register(&qnap_ts41x_button_device);
230
231 pm_power_off = qnap_ts41x_power_off;
232
233}
234
235static int __init ts41x_pci_init(void)
236{
237 if (machine_is_ts41x())
238 kirkwood_pcie_init();
239
240 return 0;
241}
242subsys_initcall(ts41x_pci_init);
243
244MACHINE_START(TS41X, "QNAP TS-41x")
245 /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
246 .phys_io = KIRKWOOD_REGS_PHYS_BASE,
247 .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
248 .boot_params = 0x00000100,
249 .init_machine = qnap_ts41x_init,
250 .map_io = kirkwood_map_io,
251 .init_irq = kirkwood_init_irq,
252 .timer = &kirkwood_timer,
253MACHINE_END