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