Loading...
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 */
30static 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
36static 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
44static 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
54static 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
60static 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
68static 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
78static 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
84static 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
92static 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
102static struct sh_timer_config tmu0_platform_data = {
103 .channel_offset = 0x04,
104 .timer_bit = 0,
105 .clockevent_rating = 200,
106};
107
108static struct resource tmu0_resources[] = {
109 [0] = {
110 .start = 0xffc10008,
111 .end = 0xffc10013,
112 .flags = IORESOURCE_MEM,
113 },
114 [1] = {
115 .start = evt2irq(0x400),
116 .flags = IORESOURCE_IRQ,
117 },
118};
119
120static struct platform_device tmu0_device = {
121 .name = "sh_tmu",
122 .id = 0,
123 .dev = {
124 .platform_data = &tmu0_platform_data,
125 },
126 .resource = tmu0_resources,
127 .num_resources = ARRAY_SIZE(tmu0_resources),
128};
129
130static struct sh_timer_config tmu1_platform_data = {
131 .channel_offset = 0x10,
132 .timer_bit = 1,
133 .clocksource_rating = 200,
134};
135
136static struct resource tmu1_resources[] = {
137 [0] = {
138 .start = 0xffc10014,
139 .end = 0xffc1001f,
140 .flags = IORESOURCE_MEM,
141 },
142 [1] = {
143 .start = evt2irq(0x420),
144 .flags = IORESOURCE_IRQ,
145 },
146};
147
148static struct platform_device tmu1_device = {
149 .name = "sh_tmu",
150 .id = 1,
151 .dev = {
152 .platform_data = &tmu1_platform_data,
153 },
154 .resource = tmu1_resources,
155 .num_resources = ARRAY_SIZE(tmu1_resources),
156};
157
158static struct sh_timer_config tmu2_platform_data = {
159 .channel_offset = 0x1c,
160 .timer_bit = 2,
161};
162
163static struct resource tmu2_resources[] = {
164 [0] = {
165 .start = 0xffc10020,
166 .end = 0xffc1002f,
167 .flags = IORESOURCE_MEM,
168 },
169 [1] = {
170 .start = evt2irq(0x440),
171 .flags = IORESOURCE_IRQ,
172 },
173};
174
175static struct platform_device tmu2_device = {
176 .name = "sh_tmu",
177 .id = 2,
178 .dev = {
179 .platform_data = &tmu2_platform_data,
180 },
181 .resource = tmu2_resources,
182 .num_resources = ARRAY_SIZE(tmu2_resources),
183};
184
185static struct sh_timer_config tmu3_platform_data = {
186 .channel_offset = 0x04,
187 .timer_bit = 0,
188};
189
190static struct resource tmu3_resources[] = {
191 [0] = {
192 .start = 0xffc20008,
193 .end = 0xffc20013,
194 .flags = IORESOURCE_MEM,
195 },
196 [1] = {
197 .start = evt2irq(0x460),
198 .flags = IORESOURCE_IRQ,
199 },
200};
201
202static struct platform_device tmu3_device = {
203 .name = "sh_tmu",
204 .id = 3,
205 .dev = {
206 .platform_data = &tmu3_platform_data,
207 },
208 .resource = tmu3_resources,
209 .num_resources = ARRAY_SIZE(tmu3_resources),
210};
211
212static struct sh_timer_config tmu4_platform_data = {
213 .channel_offset = 0x10,
214 .timer_bit = 1,
215};
216
217static struct resource tmu4_resources[] = {
218 [0] = {
219 .start = 0xffc20014,
220 .end = 0xffc2001f,
221 .flags = IORESOURCE_MEM,
222 },
223 [1] = {
224 .start = evt2irq(0x480),
225 .flags = IORESOURCE_IRQ,
226 },
227};
228
229static struct platform_device tmu4_device = {
230 .name = "sh_tmu",
231 .id = 4,
232 .dev = {
233 .platform_data = &tmu4_platform_data,
234 },
235 .resource = tmu4_resources,
236 .num_resources = ARRAY_SIZE(tmu4_resources),
237};
238
239static struct sh_timer_config tmu5_platform_data = {
240 .channel_offset = 0x1c,
241 .timer_bit = 2,
242};
243
244static struct resource tmu5_resources[] = {
245 [0] = {
246 .start = 0xffc20020,
247 .end = 0xffc2002b,
248 .flags = IORESOURCE_MEM,
249 },
250 [1] = {
251 .start = evt2irq(0x4a0),
252 .flags = IORESOURCE_IRQ,
253 },
254};
255
256static struct platform_device tmu5_device = {
257 .name = "sh_tmu",
258 .id = 5,
259 .dev = {
260 .platform_data = &tmu5_platform_data,
261 },
262 .resource = tmu5_resources,
263 .num_resources = ARRAY_SIZE(tmu5_resources),
264};
265
266static struct platform_device *shx3_early_devices[] __initdata = {
267 &scif0_device,
268 &scif1_device,
269 &scif2_device,
270 &tmu0_device,
271 &tmu1_device,
272 &tmu2_device,
273 &tmu3_device,
274 &tmu4_device,
275 &tmu5_device,
276};
277
278static int __init shx3_devices_setup(void)
279{
280 return platform_add_devices(shx3_early_devices,
281 ARRAY_SIZE(shx3_early_devices));
282}
283arch_initcall(shx3_devices_setup);
284
285void __init plat_early_device_setup(void)
286{
287 early_platform_add_devices(shx3_early_devices,
288 ARRAY_SIZE(shx3_early_devices));
289}
290
291enum {
292 UNUSED = 0,
293
294 /* interrupt sources */
295 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
296 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
297 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
298 IRL_HHLL, IRL_HHLH, IRL_HHHL,
299 IRQ0, IRQ1, IRQ2, IRQ3,
300 HUDII,
301 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
302 PCII0, PCII1, PCII2, PCII3, PCII4,
303 PCII5, PCII6, PCII7, PCII8, PCII9,
304 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
305 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
306 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
307 SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
308 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
309 DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
310 DU,
311 DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
312 DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
313 IIC, VIN0, VIN1, VCORE0, ATAPI,
314 DTU0, DTU1, DTU2, DTU3,
315 FE0, FE1,
316 GPIO0, GPIO1, GPIO2, GPIO3,
317 PAM, IRM,
318 INTICI0, INTICI1, INTICI2, INTICI3,
319 INTICI4, INTICI5, INTICI6, INTICI7,
320
321 /* interrupt groups */
322 IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
323 DMAC0, DMAC1,
324};
325
326static struct intc_vect vectors[] __initdata = {
327 INTC_VECT(HUDII, 0x3e0),
328 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
329 INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
330 INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
331 INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
332 INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
333 INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
334 INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
335 INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
336 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
337 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
338 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
339 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
340 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
341 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
342 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
343 INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
344 INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
345 INTC_VECT(DMAC0_DMAE, 0x9c0),
346 INTC_VECT(DU, 0x9e0),
347 INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
348 INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
349 INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
350 INTC_VECT(DMAC1_DMAE, 0xac0),
351 INTC_VECT(IIC, 0xae0),
352 INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
353 INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
354 INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
355 INTC_VECT(DTU0, 0xc40),
356 INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
357 INTC_VECT(DTU1, 0xca0),
358 INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
359 INTC_VECT(DTU2, 0xd00),
360 INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
361 INTC_VECT(DTU3, 0xd60),
362 INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
363 INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
364 INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
365 INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
366 INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
367 INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
368 INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
369 INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
370};
371
372static struct intc_group groups[] __initdata = {
373 INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
374 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
375 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
376 IRL_HHLL, IRL_HHLH, IRL_HHHL),
377 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
378 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
379 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
380 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
381 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
382 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
383 INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
384 DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
385};
386
387#define INT2DISTCR0 0xfe4108a0
388#define INT2DISTCR1 0xfe4108a4
389#define INT2DISTCR2 0xfe4108a8
390
391static struct intc_mask_reg mask_registers[] __initdata = {
392 { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
393 { IRQ0, IRQ1, IRQ2, IRQ3 } },
394 { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
395 { IRL } },
396 { 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
397 { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
398 DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
399 0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
400 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
401 INTC_SMP_BALANCING(INT2DISTCR0) },
402 { 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
403 { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
404 PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
405 PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
406 DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
407 DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
408 DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
409 INTC_SMP_BALANCING(INT2DISTCR1) },
410 { 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
411 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
412 SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
413 SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
414 SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
415 SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
416 INTC_SMP_BALANCING(INT2DISTCR2) },
417};
418
419static struct intc_prio_reg prio_registers[] __initdata = {
420 { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
421
422 { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
423 TMU3, TMU2, TMU1, TMU0 } },
424 { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
425 SCIF3, SCIF2,
426 SCIF1, SCIF0 } },
427 { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
428 PCII56789, PCII4,
429 PCII3, PCII2,
430 PCII1, PCII0 } },
431 { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
432 VIN1, VIN0, IIC, DU} },
433 { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
434 GPIO2, GPIO1, GPIO0, IRM } },
435 { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
436 { INTICI7, INTICI6, INTICI5, INTICI4,
437 INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
438};
439
440static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
441 mask_registers, prio_registers, NULL);
442
443/* Support for external interrupt pins in IRQ mode */
444static struct intc_vect vectors_irq[] __initdata = {
445 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
446 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
447};
448
449static struct intc_sense_reg sense_registers[] __initdata = {
450 { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
451};
452
453static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
454 mask_registers, prio_registers, sense_registers);
455
456/* External interrupt pins in IRL mode */
457static struct intc_vect vectors_irl[] __initdata = {
458 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
459 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
460 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
461 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
462 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
463 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
464 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
465 INTC_VECT(IRL_HHHL, 0x3c0),
466};
467
468static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
469 mask_registers, prio_registers, NULL);
470
471void __init plat_irq_setup_pins(int mode)
472{
473 int ret = 0;
474
475 switch (mode) {
476 case IRQ_MODE_IRQ:
477 ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
478 ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
479 ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
480 ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
481
482 if (unlikely(ret)) {
483 pr_err("Failed to set IRQ mode\n");
484 return;
485 }
486
487 register_intc_controller(&intc_desc_irq);
488 break;
489 case IRQ_MODE_IRL3210:
490 ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
491 ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
492 ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
493 ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
494
495 if (unlikely(ret)) {
496 pr_err("Failed to set IRL mode\n");
497 return;
498 }
499
500 register_intc_controller(&intc_desc_irl);
501 break;
502 default:
503 BUG();
504 }
505}
506
507void __init plat_irq_setup(void)
508{
509 register_intc_controller(&intc_desc);
510}
511
512void __init plat_mem_setup(void)
513{
514 unsigned int nid = 1;
515
516 /* Register CPU#0 URAM space as Node 1 */
517 setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
518
519#if 0
520 /* XXX: Not yet.. */
521 setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
522 setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
523 setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
524#endif
525
526 setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
527}
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 */
28static struct plat_sci_port scif0_platform_data = {
29 .scscr = SCSCR_REIE,
30 .type = PORT_SCIF,
31};
32
33static 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
41static 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
51static struct plat_sci_port scif1_platform_data = {
52 .scscr = SCSCR_REIE,
53 .type = PORT_SCIF,
54};
55
56static 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
64static 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
74static struct plat_sci_port scif2_platform_data = {
75 .scscr = SCSCR_REIE,
76 .type = PORT_SCIF,
77};
78
79static 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
87static 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
97static struct sh_timer_config tmu0_platform_data = {
98 .channels_mask = 7,
99};
100
101static 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
108static 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
118static struct sh_timer_config tmu1_platform_data = {
119 .channels_mask = 7,
120};
121
122static 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
129static 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
139static struct platform_device *shx3_early_devices[] __initdata = {
140 &scif0_device,
141 &scif1_device,
142 &scif2_device,
143 &tmu0_device,
144 &tmu1_device,
145};
146
147static int __init shx3_devices_setup(void)
148{
149 return platform_add_devices(shx3_early_devices,
150 ARRAY_SIZE(shx3_early_devices));
151}
152arch_initcall(shx3_devices_setup);
153
154void __init plat_early_device_setup(void)
155{
156 sh_early_platform_add_devices(shx3_early_devices,
157 ARRAY_SIZE(shx3_early_devices));
158}
159
160enum {
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
195static 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
241static 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
260static 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
288static 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
309static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
310 mask_registers, prio_registers, NULL);
311
312/* Support for external interrupt pins in IRQ mode */
313static 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
318static struct intc_sense_reg sense_registers[] __initdata = {
319 { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
320};
321
322static 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 */
326static 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
337static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
338 mask_registers, prio_registers, NULL);
339
340void __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
376void __init plat_irq_setup(void)
377{
378 register_intc_controller(&intc_desc);
379}
380
381void __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}