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