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