GNU Linux-libre 6.7.9-gnu
[releases.git] / arch / sh / kernel / cpu / sh4a / setup-shx3.c
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
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
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
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
376 void __init plat_irq_setup(void)
377 {
378         register_intc_controller(&intc_desc);
379 }
380
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 }