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