Merge branch 'linux-next' of git://git.infradead.org/ubi-2.6
[linux-block.git] / arch / sh / kernel / cpu / sh4a / setup-shx3.c
CommitLineData
2b1bd1ac 1/*
ccdaeb4c 2 * SH-X3 Prototype Setup
2b1bd1ac 3 *
ccdaeb4c 4 * Copyright (C) 2007 - 2009 Paul Mundt
2b1bd1ac
PM
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
96de1a8f 13#include <linux/serial_sci.h>
2b1bd1ac 14#include <linux/io.h>
ccdaeb4c 15#include <linux/sh_timer.h>
d6aee69c 16#include <asm/mmzone.h>
2b1bd1ac
PM
17
18static struct plat_sci_port sci_platform_data[] = {
19 {
20 .mapbase = 0xffc30000,
21 .flags = UPF_BOOT_AUTOCONF,
22 .type = PORT_SCIF,
23 .irqs = { 40, 41, 43, 42 },
24 }, {
25 .mapbase = 0xffc40000,
26 .flags = UPF_BOOT_AUTOCONF,
27 .type = PORT_SCIF,
28 .irqs = { 44, 45, 47, 46 },
29 }, {
30 .mapbase = 0xffc50000,
31 .flags = UPF_BOOT_AUTOCONF,
32 .type = PORT_SCIF,
33 .irqs = { 48, 49, 51, 50 },
34 }, {
35 .mapbase = 0xffc60000,
36 .flags = UPF_BOOT_AUTOCONF,
37 .type = PORT_SCIF,
38 .irqs = { 52, 53, 55, 54 },
39 }, {
40 .flags = 0,
41 }
42};
43
44static struct platform_device sci_device = {
45 .name = "sh-sci",
46 .id = -1,
47 .dev = {
48 .platform_data = sci_platform_data,
49 },
50};
51
ccdaeb4c
PM
52static struct sh_timer_config tmu0_platform_data = {
53 .name = "TMU0",
54 .channel_offset = 0x04,
55 .timer_bit = 0,
af777ce4 56 .clk = "peripheral_clk",
ccdaeb4c
PM
57 .clockevent_rating = 200,
58};
59
60static struct resource tmu0_resources[] = {
61 [0] = {
62 .name = "TMU0",
63 .start = 0xffc10008,
64 .end = 0xffc10013,
65 .flags = IORESOURCE_MEM,
66 },
67 [1] = {
68 .start = 16,
69 .flags = IORESOURCE_IRQ,
70 },
71};
72
73static struct platform_device tmu0_device = {
74 .name = "sh_tmu",
75 .id = 0,
76 .dev = {
77 .platform_data = &tmu0_platform_data,
78 },
79 .resource = tmu0_resources,
80 .num_resources = ARRAY_SIZE(tmu0_resources),
81};
82
83static struct sh_timer_config tmu1_platform_data = {
84 .name = "TMU1",
85 .channel_offset = 0x10,
86 .timer_bit = 1,
af777ce4 87 .clk = "peripheral_clk",
ccdaeb4c
PM
88 .clocksource_rating = 200,
89};
90
91static struct resource tmu1_resources[] = {
92 [0] = {
93 .name = "TMU1",
94 .start = 0xffc10014,
95 .end = 0xffc1001f,
96 .flags = IORESOURCE_MEM,
97 },
98 [1] = {
99 .start = 17,
100 .flags = IORESOURCE_IRQ,
101 },
102};
103
104static struct platform_device tmu1_device = {
105 .name = "sh_tmu",
106 .id = 1,
107 .dev = {
108 .platform_data = &tmu1_platform_data,
109 },
110 .resource = tmu1_resources,
111 .num_resources = ARRAY_SIZE(tmu1_resources),
112};
113
114static struct sh_timer_config tmu2_platform_data = {
115 .name = "TMU2",
116 .channel_offset = 0x1c,
117 .timer_bit = 2,
af777ce4 118 .clk = "peripheral_clk",
ccdaeb4c
PM
119};
120
121static struct resource tmu2_resources[] = {
122 [0] = {
123 .name = "TMU2",
124 .start = 0xffc10020,
125 .end = 0xffc1002f,
126 .flags = IORESOURCE_MEM,
127 },
128 [1] = {
129 .start = 18,
130 .flags = IORESOURCE_IRQ,
131 },
132};
133
134static struct platform_device tmu2_device = {
135 .name = "sh_tmu",
136 .id = 2,
137 .dev = {
138 .platform_data = &tmu2_platform_data,
139 },
140 .resource = tmu2_resources,
141 .num_resources = ARRAY_SIZE(tmu2_resources),
142};
143
144static struct sh_timer_config tmu3_platform_data = {
145 .name = "TMU3",
146 .channel_offset = 0x04,
147 .timer_bit = 0,
af777ce4 148 .clk = "peripheral_clk",
ccdaeb4c
PM
149};
150
151static struct resource tmu3_resources[] = {
152 [0] = {
153 .name = "TMU3",
154 .start = 0xffc20008,
155 .end = 0xffc20013,
156 .flags = IORESOURCE_MEM,
157 },
158 [1] = {
159 .start = 19,
160 .flags = IORESOURCE_IRQ,
161 },
162};
163
164static struct platform_device tmu3_device = {
165 .name = "sh_tmu",
166 .id = 3,
167 .dev = {
168 .platform_data = &tmu3_platform_data,
169 },
170 .resource = tmu3_resources,
171 .num_resources = ARRAY_SIZE(tmu3_resources),
172};
173
174static struct sh_timer_config tmu4_platform_data = {
175 .name = "TMU4",
176 .channel_offset = 0x10,
177 .timer_bit = 1,
af777ce4 178 .clk = "peripheral_clk",
ccdaeb4c
PM
179};
180
181static struct resource tmu4_resources[] = {
182 [0] = {
183 .name = "TMU4",
184 .start = 0xffc20014,
185 .end = 0xffc2001f,
186 .flags = IORESOURCE_MEM,
187 },
188 [1] = {
189 .start = 20,
190 .flags = IORESOURCE_IRQ,
191 },
192};
193
194static struct platform_device tmu4_device = {
195 .name = "sh_tmu",
196 .id = 4,
197 .dev = {
198 .platform_data = &tmu4_platform_data,
199 },
200 .resource = tmu4_resources,
201 .num_resources = ARRAY_SIZE(tmu4_resources),
202};
203
204static struct sh_timer_config tmu5_platform_data = {
205 .name = "TMU5",
206 .channel_offset = 0x1c,
207 .timer_bit = 2,
af777ce4 208 .clk = "peripheral_clk",
ccdaeb4c
PM
209};
210
211static struct resource tmu5_resources[] = {
212 [0] = {
213 .name = "TMU5",
214 .start = 0xffc20020,
215 .end = 0xffc2002b,
216 .flags = IORESOURCE_MEM,
217 },
218 [1] = {
219 .start = 21,
220 .flags = IORESOURCE_IRQ,
221 },
222};
223
224static struct platform_device tmu5_device = {
225 .name = "sh_tmu",
226 .id = 5,
227 .dev = {
228 .platform_data = &tmu5_platform_data,
229 },
230 .resource = tmu5_resources,
231 .num_resources = ARRAY_SIZE(tmu5_resources),
232};
233
234static struct platform_device *shx3_early_devices[] __initdata = {
235 &tmu0_device,
236 &tmu1_device,
237 &tmu2_device,
238 &tmu3_device,
239 &tmu4_device,
240 &tmu5_device,
241};
242
2b1bd1ac
PM
243static struct platform_device *shx3_devices[] __initdata = {
244 &sci_device,
245};
246
247static int __init shx3_devices_setup(void)
248{
ccdaeb4c
PM
249 int ret;
250
251 ret = platform_add_devices(shx3_early_devices,
252 ARRAY_SIZE(shx3_early_devices));
253 if (unlikely(ret != 0))
254 return ret;
255
2b1bd1ac
PM
256 return platform_add_devices(shx3_devices,
257 ARRAY_SIZE(shx3_devices));
258}
955c9863 259arch_initcall(shx3_devices_setup);
2b1bd1ac 260
ccdaeb4c
PM
261void __init plat_early_device_setup(void)
262{
263 early_platform_add_devices(shx3_early_devices,
264 ARRAY_SIZE(shx3_early_devices));
265}
266
1ee01008
MD
267enum {
268 UNUSED = 0,
269
270 /* interrupt sources */
3639dfb5 271 IRL, IRQ0, IRQ1, IRQ2, IRQ3,
1ee01008
MD
272 HUDII,
273 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
274 PCII0, PCII1, PCII2, PCII3, PCII4,
275 PCII5, PCII6, PCII7, PCII8, PCII9,
276 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
277 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
278 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
279 SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
280 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
281 DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
282 DU,
283 DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
284 DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
285 IIC, VIN0, VIN1, VCORE0, ATAPI,
3639dfb5 286 DTU0, DTU1, DTU2, DTU3,
1ee01008
MD
287 FE0, FE1,
288 GPIO0, GPIO1, GPIO2, GPIO3,
289 PAM, IRM,
46420e49
MD
290 INTICI0, INTICI1, INTICI2, INTICI3,
291 INTICI4, INTICI5, INTICI6, INTICI7,
1ee01008
MD
292
293 /* interrupt groups */
3639dfb5
PM
294 PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
295 DMAC0, DMAC1,
2b1bd1ac
PM
296};
297
5c37e025 298static struct intc_vect vectors[] __initdata = {
1ee01008
MD
299 INTC_VECT(HUDII, 0x3e0),
300 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
301 INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
302 INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
303 INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
304 INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
305 INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
306 INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
307 INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
308 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
309 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
310 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
311 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
312 INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820),
313 INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860),
314 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
315 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
316 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
317 INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
318 INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
319 INTC_VECT(DMAC0_DMAE, 0x9c0),
320 INTC_VECT(DU, 0x9e0),
321 INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
322 INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
323 INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
324 INTC_VECT(DMAC1_DMAE, 0xac0),
325 INTC_VECT(IIC, 0xae0),
326 INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
327 INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
3639dfb5
PM
328 INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
329 INTC_VECT(DTU0, 0xc40),
330 INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
331 INTC_VECT(DTU1, 0xca0),
332 INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
333 INTC_VECT(DTU2, 0xd00),
334 INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
335 INTC_VECT(DTU3, 0xd60),
1ee01008
MD
336 INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
337 INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
338 INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
339 INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
46420e49
MD
340 INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
341 INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
342 INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
343 INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
1ee01008 344};
2b1bd1ac 345
5c37e025 346static struct intc_group groups[] __initdata = {
1ee01008
MD
347 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
348 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
349 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
350 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
351 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
352 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
353 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
354 INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
355 DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
1ee01008 356};
2b1bd1ac 357
5c37e025 358static struct intc_mask_reg mask_registers[] __initdata = {
1ee01008
MD
359 { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
360 { IRQ0, IRQ1, IRQ2, IRQ3 } },
361 { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
362 { IRL } },
363 { 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
364 { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
365 DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
366 0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
367 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, } },
368 { 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
369 { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
370 PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
371 PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
372 DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
373 DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
374 DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 } },
375 { 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
376 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
377 SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
378 SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
379 SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
380 SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } },
381};
382
5c37e025 383static struct intc_prio_reg prio_registers[] __initdata = {
6ef5fb2c
MD
384 { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
385
386 { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
387 TMU3, TMU2, TMU1, TMU0 } },
388 { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
389 SCIF3, SCIF2,
390 SCIF1, SCIF0 } },
391 { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
392 PCII56789, PCII4,
393 PCII3, PCII2,
394 PCII1, PCII0 } },
395 { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
396 VIN1, VIN0, IIC, DU} },
397 { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
398 GPIO2, GPIO1, GPIO0, IRM } },
46420e49
MD
399 { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
400 { INTICI7, INTICI6, INTICI5, INTICI4,
ceb9b974 401 INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
2b1bd1ac
PM
402};
403
7f3edee8 404static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
1ee01008
MD
405 mask_registers, prio_registers, NULL);
406
407/* Support for external interrupt pins in IRQ mode */
5c37e025 408static struct intc_vect vectors_irq[] __initdata = {
1ee01008
MD
409 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
410 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
411};
412
5c37e025 413static struct intc_sense_reg sense_registers[] __initdata = {
1ee01008
MD
414 { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
415};
416
417static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
7f3edee8 418 mask_registers, prio_registers, sense_registers);
1ee01008
MD
419
420/* External interrupt pins in IRL mode */
5c37e025 421static struct intc_vect vectors_irl[] __initdata = {
3639dfb5
PM
422 INTC_VECT(IRL, 0x200), INTC_VECT(IRL, 0x220),
423 INTC_VECT(IRL, 0x240), INTC_VECT(IRL, 0x260),
424 INTC_VECT(IRL, 0x280), INTC_VECT(IRL, 0x2a0),
425 INTC_VECT(IRL, 0x2c0), INTC_VECT(IRL, 0x2e0),
426 INTC_VECT(IRL, 0x300), INTC_VECT(IRL, 0x320),
427 INTC_VECT(IRL, 0x340), INTC_VECT(IRL, 0x360),
428 INTC_VECT(IRL, 0x380), INTC_VECT(IRL, 0x3a0),
429 INTC_VECT(IRL, 0x3c0),
1ee01008
MD
430};
431
432static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
7f3edee8 433 mask_registers, prio_registers, NULL);
1ee01008
MD
434
435void __init plat_irq_setup_pins(int mode)
436{
437 switch (mode) {
438 case IRQ_MODE_IRQ:
439 register_intc_controller(&intc_desc_irq);
440 break;
441 case IRQ_MODE_IRL3210:
442 register_intc_controller(&intc_desc_irl);
443 break;
444 default:
445 BUG();
446 }
447}
448
90015c89 449void __init plat_irq_setup(void)
2b1bd1ac 450{
1ee01008 451 register_intc_controller(&intc_desc);
2b1bd1ac 452}
7da3b8ef
PM
453
454void __init plat_mem_setup(void)
455{
d3428e91
PM
456 unsigned int nid = 1;
457
7da3b8ef 458 /* Register CPU#0 URAM space as Node 1 */
d3428e91 459 setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
7da3b8ef
PM
460
461#if 0
462 /* XXX: Not yet.. */
d3428e91
PM
463 setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
464 setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
465 setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
7da3b8ef 466#endif
d3428e91
PM
467
468 setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
7da3b8ef 469}