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