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