xref: /openbmc/linux/arch/sh/kernel/cpu/sh4a/setup-shx3.c (revision 23c2b932)
1 /*
2  * SH-X3 Prototype Setup
3  *
4  *  Copyright (C) 2007 - 2010  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/gpio.h>
16 #include <linux/sh_timer.h>
17 #include <linux/sh_intc.h>
18 #include <cpu/shx3.h>
19 #include <asm/mmzone.h>
20 
21 /*
22  * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
23  * INTEVT values overlap with the FPU EXPEVT ones, requiring special
24  * demuxing in the exception dispatch path.
25  *
26  * As this overlap is something that never should have made it in to
27  * silicon in the first place, we just refuse to deal with the port at
28  * all rather than adding infrastructure to hack around it.
29  */
30 static struct plat_sci_port scif0_platform_data = {
31 	.flags		= UPF_BOOT_AUTOCONF,
32 	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_REIE,
33 	.type		= PORT_SCIF,
34 };
35 
36 static struct resource scif0_resources[] = {
37 	DEFINE_RES_MEM(0xffc30000, 0x100),
38 	DEFINE_RES_IRQ(evt2irq(0x700)),
39 	DEFINE_RES_IRQ(evt2irq(0x720)),
40 	DEFINE_RES_IRQ(evt2irq(0x760)),
41 	DEFINE_RES_IRQ(evt2irq(0x740)),
42 };
43 
44 static struct platform_device scif0_device = {
45 	.name		= "sh-sci",
46 	.id		= 0,
47 	.resource	= scif0_resources,
48 	.num_resources	= ARRAY_SIZE(scif0_resources),
49 	.dev		= {
50 		.platform_data	= &scif0_platform_data,
51 	},
52 };
53 
54 static struct plat_sci_port scif1_platform_data = {
55 	.flags		= UPF_BOOT_AUTOCONF,
56 	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_REIE,
57 	.type		= PORT_SCIF,
58 };
59 
60 static struct resource scif1_resources[] = {
61 	DEFINE_RES_MEM(0xffc40000, 0x100),
62 	DEFINE_RES_IRQ(evt2irq(0x780)),
63 	DEFINE_RES_IRQ(evt2irq(0x7a0)),
64 	DEFINE_RES_IRQ(evt2irq(0x7e0)),
65 	DEFINE_RES_IRQ(evt2irq(0x7c0)),
66 };
67 
68 static struct platform_device scif1_device = {
69 	.name		= "sh-sci",
70 	.id		= 1,
71 	.resource	= scif1_resources,
72 	.num_resources	= ARRAY_SIZE(scif1_resources),
73 	.dev		= {
74 		.platform_data	= &scif1_platform_data,
75 	},
76 };
77 
78 static struct plat_sci_port scif2_platform_data = {
79 	.flags		= UPF_BOOT_AUTOCONF,
80 	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_REIE,
81 	.type		= PORT_SCIF,
82 };
83 
84 static struct resource scif2_resources[] = {
85 	DEFINE_RES_MEM(0xffc60000, 0x100),
86 	DEFINE_RES_IRQ(evt2irq(0x880)),
87 	DEFINE_RES_IRQ(evt2irq(0x8a0)),
88 	DEFINE_RES_IRQ(evt2irq(0x8e0)),
89 	DEFINE_RES_IRQ(evt2irq(0x8c0)),
90 };
91 
92 static struct platform_device scif2_device = {
93 	.name		= "sh-sci",
94 	.id		= 2,
95 	.resource	= scif2_resources,
96 	.num_resources	= ARRAY_SIZE(scif2_resources),
97 	.dev		= {
98 		.platform_data	= &scif2_platform_data,
99 	},
100 };
101 
102 static struct sh_timer_config tmu0_platform_data = {
103 	.channels_mask = 7,
104 };
105 
106 static struct resource tmu0_resources[] = {
107 	DEFINE_RES_MEM(0xffc10000, 0x30),
108 	DEFINE_RES_IRQ(evt2irq(0x400)),
109 	DEFINE_RES_IRQ(evt2irq(0x420)),
110 	DEFINE_RES_IRQ(evt2irq(0x440)),
111 };
112 
113 static struct platform_device tmu0_device = {
114 	.name		= "sh-tmu",
115 	.id		= 0,
116 	.dev = {
117 		.platform_data	= &tmu0_platform_data,
118 	},
119 	.resource	= tmu0_resources,
120 	.num_resources	= ARRAY_SIZE(tmu0_resources),
121 };
122 
123 static struct sh_timer_config tmu1_platform_data = {
124 	.channels_mask = 7,
125 };
126 
127 static struct resource tmu1_resources[] = {
128 	DEFINE_RES_MEM(0xffc20000, 0x2c),
129 	DEFINE_RES_IRQ(evt2irq(0x460)),
130 	DEFINE_RES_IRQ(evt2irq(0x480)),
131 	DEFINE_RES_IRQ(evt2irq(0x4a0)),
132 };
133 
134 static struct platform_device tmu1_device = {
135 	.name		= "sh-tmu",
136 	.id		= 1,
137 	.dev = {
138 		.platform_data	= &tmu1_platform_data,
139 	},
140 	.resource	= tmu1_resources,
141 	.num_resources	= ARRAY_SIZE(tmu1_resources),
142 };
143 
144 static struct platform_device *shx3_early_devices[] __initdata = {
145 	&scif0_device,
146 	&scif1_device,
147 	&scif2_device,
148 	&tmu0_device,
149 	&tmu1_device,
150 };
151 
152 static int __init shx3_devices_setup(void)
153 {
154 	return platform_add_devices(shx3_early_devices,
155 				   ARRAY_SIZE(shx3_early_devices));
156 }
157 arch_initcall(shx3_devices_setup);
158 
159 void __init plat_early_device_setup(void)
160 {
161 	early_platform_add_devices(shx3_early_devices,
162 				   ARRAY_SIZE(shx3_early_devices));
163 }
164 
165 enum {
166 	UNUSED = 0,
167 
168 	/* interrupt sources */
169 	IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
170 	IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
171 	IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
172 	IRL_HHLL, IRL_HHLH, IRL_HHHL,
173 	IRQ0, IRQ1, IRQ2, IRQ3,
174 	HUDII,
175 	TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
176 	PCII0, PCII1, PCII2, PCII3, PCII4,
177 	PCII5, PCII6, PCII7, PCII8, PCII9,
178 	SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
179 	SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
180 	SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
181 	SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
182 	DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
183 	DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
184 	DU,
185 	DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
186 	DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
187 	IIC, VIN0, VIN1, VCORE0, ATAPI,
188 	DTU0, DTU1, DTU2, DTU3,
189 	FE0, FE1,
190 	GPIO0, GPIO1, GPIO2, GPIO3,
191 	PAM, IRM,
192 	INTICI0, INTICI1, INTICI2, INTICI3,
193 	INTICI4, INTICI5, INTICI6, INTICI7,
194 
195 	/* interrupt groups */
196 	IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
197 	DMAC0, DMAC1,
198 };
199 
200 static struct intc_vect vectors[] __initdata = {
201 	INTC_VECT(HUDII, 0x3e0),
202 	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
203 	INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
204 	INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
205 	INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
206 	INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
207 	INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
208 	INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
209 	INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
210 	INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
211 	INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
212 	INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
213 	INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
214 	INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
215 	INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
216 	INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
217 	INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
218 	INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
219 	INTC_VECT(DMAC0_DMAE, 0x9c0),
220 	INTC_VECT(DU, 0x9e0),
221 	INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
222 	INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
223 	INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
224 	INTC_VECT(DMAC1_DMAE, 0xac0),
225 	INTC_VECT(IIC, 0xae0),
226 	INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
227 	INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
228 	INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
229 	INTC_VECT(DTU0, 0xc40),
230 	INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
231 	INTC_VECT(DTU1, 0xca0),
232 	INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
233 	INTC_VECT(DTU2, 0xd00),
234 	INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
235 	INTC_VECT(DTU3, 0xd60),
236 	INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
237 	INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
238 	INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
239 	INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
240 	INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
241 	INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
242 	INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
243 	INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
244 };
245 
246 static struct intc_group groups[] __initdata = {
247 	INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
248 		   IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
249 		   IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
250 		   IRL_HHLL, IRL_HHLH, IRL_HHHL),
251 	INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
252 	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
253 	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
254 	INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
255 	INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
256 		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
257 	INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
258 		   DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
259 };
260 
261 #define INT2DISTCR0	0xfe4108a0
262 #define INT2DISTCR1	0xfe4108a4
263 #define INT2DISTCR2	0xfe4108a8
264 
265 static struct intc_mask_reg mask_registers[] __initdata = {
266 	{ 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
267 	  { IRQ0, IRQ1, IRQ2, IRQ3 } },
268 	{ 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
269 	  { IRL } },
270 	{ 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
271 	  { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
272 	    DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
273 	    0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
274 	    0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
275 	    INTC_SMP_BALANCING(INT2DISTCR0) },
276 	{ 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
277 	  { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
278 	    PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
279 	    PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
280 	    DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
281 	    DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
282 	    DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
283 	    INTC_SMP_BALANCING(INT2DISTCR1) },
284 	{ 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
285 	  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
286 	    SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
287 	    SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
288 	    SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
289 	    SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
290 	    INTC_SMP_BALANCING(INT2DISTCR2) },
291 };
292 
293 static struct intc_prio_reg prio_registers[] __initdata = {
294 	{ 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
295 
296 	{ 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
297 						 TMU3, TMU2, TMU1, TMU0 } },
298 	{ 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
299 						 SCIF3, SCIF2,
300 						 SCIF1, SCIF0 } },
301 	{ 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
302 						 PCII56789, PCII4,
303 						 PCII3, PCII2,
304 						 PCII1, PCII0 } },
305 	{ 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
306 						 VIN1, VIN0, IIC, DU} },
307 	{ 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
308 						 GPIO2, GPIO1, GPIO0, IRM } },
309 	{ 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
310 	  { INTICI7, INTICI6, INTICI5, INTICI4,
311 	    INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
312 };
313 
314 static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
315 			 mask_registers, prio_registers, NULL);
316 
317 /* Support for external interrupt pins in IRQ mode */
318 static struct intc_vect vectors_irq[] __initdata = {
319 	INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
320 	INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
321 };
322 
323 static struct intc_sense_reg sense_registers[] __initdata = {
324 	{ 0xfe41001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3 } },
325 };
326 
327 static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
328 			 mask_registers, prio_registers, sense_registers);
329 
330 /* External interrupt pins in IRL mode */
331 static struct intc_vect vectors_irl[] __initdata = {
332 	INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
333 	INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
334 	INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
335 	INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
336 	INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
337 	INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
338 	INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
339 	INTC_VECT(IRL_HHHL, 0x3c0),
340 };
341 
342 static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
343 			 mask_registers, prio_registers, NULL);
344 
345 void __init plat_irq_setup_pins(int mode)
346 {
347 	int ret = 0;
348 
349 	switch (mode) {
350 	case IRQ_MODE_IRQ:
351 		ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
352 		ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
353 		ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
354 		ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
355 
356 		if (unlikely(ret)) {
357 			pr_err("Failed to set IRQ mode\n");
358 			return;
359 		}
360 
361 		register_intc_controller(&intc_desc_irq);
362 		break;
363 	case IRQ_MODE_IRL3210:
364 		ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
365 		ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
366 		ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
367 		ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
368 
369 		if (unlikely(ret)) {
370 			pr_err("Failed to set IRL mode\n");
371 			return;
372 		}
373 
374 		register_intc_controller(&intc_desc_irl);
375 		break;
376 	default:
377 		BUG();
378 	}
379 }
380 
381 void __init plat_irq_setup(void)
382 {
383 	register_intc_controller(&intc_desc);
384 }
385 
386 void __init plat_mem_setup(void)
387 {
388 	unsigned int nid = 1;
389 
390 	/* Register CPU#0 URAM space as Node 1 */
391 	setup_bootmem_node(nid++, 0x145f0000, 0x14610000);	/* CPU0 */
392 
393 #if 0
394 	/* XXX: Not yet.. */
395 	setup_bootmem_node(nid++, 0x14df0000, 0x14e10000);	/* CPU1 */
396 	setup_bootmem_node(nid++, 0x155f0000, 0x15610000);	/* CPU2 */
397 	setup_bootmem_node(nid++, 0x15df0000, 0x15e10000);	/* CPU3 */
398 #endif
399 
400 	setup_bootmem_node(nid++, 0x16000000, 0x16020000);	/* CSM */
401 }
402