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