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