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
shx3_devices_setup(void)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
plat_early_device_setup(void)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
plat_irq_setup_pins(int mode)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
plat_irq_setup(void)375 void __init plat_irq_setup(void)
376 {
377 register_intc_controller(&intc_desc);
378 }
379
plat_mem_setup(void)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