xref: /openbmc/linux/arch/sh/kernel/cpu/sh4a/setup-shx3.c (revision 7dd65feb)
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 }
487