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