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