GNU Linux-libre 6.7.9-gnu
[releases.git] / arch / sh / kernel / cpu / sh4a / setup-sh7763.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * SH7763 Setup
4  *
5  *  Copyright (C) 2006  Paul Mundt
6  *  Copyright (C) 2007  Yoshihiro Shimoda
7  *  Copyright (C) 2008, 2009  Nobuhiro Iwamatsu
8  */
9 #include <linux/platform_device.h>
10 #include <linux/init.h>
11 #include <linux/serial.h>
12 #include <linux/sh_timer.h>
13 #include <linux/sh_intc.h>
14 #include <linux/io.h>
15 #include <linux/serial_sci.h>
16 #include <linux/usb/ohci_pdriver.h>
17 #include <asm/platform_early.h>
18
19 static struct plat_sci_port scif0_platform_data = {
20         .scscr          = SCSCR_REIE,
21         .type           = PORT_SCIF,
22         .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
23 };
24
25 static struct resource scif0_resources[] = {
26         DEFINE_RES_MEM(0xffe00000, 0x100),
27         DEFINE_RES_IRQ(evt2irq(0x700)),
28 };
29
30 static struct platform_device scif0_device = {
31         .name           = "sh-sci",
32         .id             = 0,
33         .resource       = scif0_resources,
34         .num_resources  = ARRAY_SIZE(scif0_resources),
35         .dev            = {
36                 .platform_data  = &scif0_platform_data,
37         },
38 };
39
40 static struct plat_sci_port scif1_platform_data = {
41         .scscr          = SCSCR_REIE,
42         .type           = PORT_SCIF,
43         .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
44 };
45
46 static struct resource scif1_resources[] = {
47         DEFINE_RES_MEM(0xffe08000, 0x100),
48         DEFINE_RES_IRQ(evt2irq(0xb80)),
49 };
50
51 static struct platform_device scif1_device = {
52         .name           = "sh-sci",
53         .id             = 1,
54         .resource       = scif1_resources,
55         .num_resources  = ARRAY_SIZE(scif1_resources),
56         .dev            = {
57                 .platform_data  = &scif1_platform_data,
58         },
59 };
60
61 static struct plat_sci_port scif2_platform_data = {
62         .scscr          = SCSCR_REIE,
63         .type           = PORT_SCIF,
64         .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
65 };
66
67 static struct resource scif2_resources[] = {
68         DEFINE_RES_MEM(0xffe10000, 0x100),
69         DEFINE_RES_IRQ(evt2irq(0xf00)),
70 };
71
72 static struct platform_device scif2_device = {
73         .name           = "sh-sci",
74         .id             = 2,
75         .resource       = scif2_resources,
76         .num_resources  = ARRAY_SIZE(scif2_resources),
77         .dev            = {
78                 .platform_data  = &scif2_platform_data,
79         },
80 };
81
82 static struct resource rtc_resources[] = {
83         [0] = {
84                 .start  = 0xffe80000,
85                 .end    = 0xffe80000 + 0x58 - 1,
86                 .flags  = IORESOURCE_IO,
87         },
88         [1] = {
89                 /* Shared Period/Carry/Alarm IRQ */
90                 .start  = evt2irq(0x480),
91                 .flags  = IORESOURCE_IRQ,
92         },
93 };
94
95 static struct platform_device rtc_device = {
96         .name           = "sh-rtc",
97         .id             = -1,
98         .num_resources  = ARRAY_SIZE(rtc_resources),
99         .resource       = rtc_resources,
100 };
101
102 static struct resource usb_ohci_resources[] = {
103         [0] = {
104                 .start  = 0xffec8000,
105                 .end    = 0xffec80ff,
106                 .flags  = IORESOURCE_MEM,
107         },
108         [1] = {
109                 .start  = evt2irq(0xc60),
110                 .end    = evt2irq(0xc60),
111                 .flags  = IORESOURCE_IRQ,
112         },
113 };
114
115 static u64 usb_ohci_dma_mask = 0xffffffffUL;
116
117 static struct usb_ohci_pdata usb_ohci_pdata;
118
119 static struct platform_device usb_ohci_device = {
120         .name           = "ohci-platform",
121         .id             = -1,
122         .dev = {
123                 .dma_mask               = &usb_ohci_dma_mask,
124                 .coherent_dma_mask      = 0xffffffff,
125                 .platform_data          = &usb_ohci_pdata,
126         },
127         .num_resources  = ARRAY_SIZE(usb_ohci_resources),
128         .resource       = usb_ohci_resources,
129 };
130
131 static struct resource usbf_resources[] = {
132         [0] = {
133                 .start  = 0xffec0000,
134                 .end    = 0xffec00ff,
135                 .flags  = IORESOURCE_MEM,
136         },
137         [1] = {
138                 .start  = evt2irq(0xc80),
139                 .end    = evt2irq(0xc80),
140                 .flags  = IORESOURCE_IRQ,
141         },
142 };
143
144 static struct platform_device usbf_device = {
145         .name           = "sh_udc",
146         .id             = -1,
147         .dev = {
148                 .dma_mask               = NULL,
149                 .coherent_dma_mask      = 0xffffffff,
150         },
151         .num_resources  = ARRAY_SIZE(usbf_resources),
152         .resource       = usbf_resources,
153 };
154
155 static struct sh_timer_config tmu0_platform_data = {
156         .channels_mask = 7,
157 };
158
159 static struct resource tmu0_resources[] = {
160         DEFINE_RES_MEM(0xffd80000, 0x30),
161         DEFINE_RES_IRQ(evt2irq(0x580)),
162         DEFINE_RES_IRQ(evt2irq(0x5a0)),
163         DEFINE_RES_IRQ(evt2irq(0x5c0)),
164 };
165
166 static struct platform_device tmu0_device = {
167         .name           = "sh-tmu",
168         .id             = 0,
169         .dev = {
170                 .platform_data  = &tmu0_platform_data,
171         },
172         .resource       = tmu0_resources,
173         .num_resources  = ARRAY_SIZE(tmu0_resources),
174 };
175
176 static struct sh_timer_config tmu1_platform_data = {
177         .channels_mask = 7,
178 };
179
180 static struct resource tmu1_resources[] = {
181         DEFINE_RES_MEM(0xffd88000, 0x2c),
182         DEFINE_RES_IRQ(evt2irq(0xe00)),
183         DEFINE_RES_IRQ(evt2irq(0xe20)),
184         DEFINE_RES_IRQ(evt2irq(0xe40)),
185 };
186
187 static struct platform_device tmu1_device = {
188         .name           = "sh-tmu",
189         .id             = 1,
190         .dev = {
191                 .platform_data  = &tmu1_platform_data,
192         },
193         .resource       = tmu1_resources,
194         .num_resources  = ARRAY_SIZE(tmu1_resources),
195 };
196
197 static struct platform_device *sh7763_devices[] __initdata = {
198         &scif0_device,
199         &scif1_device,
200         &scif2_device,
201         &tmu0_device,
202         &tmu1_device,
203         &rtc_device,
204         &usb_ohci_device,
205         &usbf_device,
206 };
207
208 static int __init sh7763_devices_setup(void)
209 {
210         return platform_add_devices(sh7763_devices,
211                                     ARRAY_SIZE(sh7763_devices));
212 }
213 arch_initcall(sh7763_devices_setup);
214
215 static struct platform_device *sh7763_early_devices[] __initdata = {
216         &scif0_device,
217         &scif1_device,
218         &scif2_device,
219         &tmu0_device,
220         &tmu1_device,
221 };
222
223 void __init plat_early_device_setup(void)
224 {
225         sh_early_platform_add_devices(sh7763_early_devices,
226                                    ARRAY_SIZE(sh7763_early_devices));
227 }
228
229 enum {
230         UNUSED = 0,
231
232         /* interrupt sources */
233
234         IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
235         IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
236         IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
237         IRL_HHLL, IRL_HHLH, IRL_HHHL,
238
239         IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
240         RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
241         HUDI, LCDC, DMAC, SCIF0, IIC0, IIC1, CMT, GETHER, HAC,
242         PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
243         STIF0, STIF1, SCIF1, SIOF0, SIOF1, SIOF2,
244         USBH, USBF, TPU, PCC, MMCIF, SIM,
245         TMU3, TMU4, TMU5, ADC, SSI0, SSI1, SSI2, SSI3,
246         SCIF2, GPIO,
247
248         /* interrupt groups */
249
250         TMU012, TMU345,
251 };
252
253 static struct intc_vect vectors[] __initdata = {
254         INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
255         INTC_VECT(RTC, 0x4c0),
256         INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580),
257         INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0),
258         INTC_VECT(TMU2_TICPI, 0x5e0), INTC_VECT(HUDI, 0x600),
259         INTC_VECT(LCDC, 0x620),
260         INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
261         INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
262         INTC_VECT(DMAC, 0x6c0),
263         INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
264         INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
265         INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
266         INTC_VECT(IIC0, 0x8A0), INTC_VECT(IIC1, 0x8C0),
267         INTC_VECT(CMT, 0x900), INTC_VECT(GETHER, 0x920),
268         INTC_VECT(GETHER, 0x940), INTC_VECT(GETHER, 0x960),
269         INTC_VECT(HAC, 0x980),
270         INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
271         INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
272         INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
273         INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
274         INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
275         INTC_VECT(STIF0, 0xb40), INTC_VECT(STIF1, 0xb60),
276         INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
277         INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
278         INTC_VECT(SIOF0, 0xc00), INTC_VECT(SIOF1, 0xc20),
279         INTC_VECT(USBH, 0xc60), INTC_VECT(USBF, 0xc80),
280         INTC_VECT(USBF, 0xca0),
281         INTC_VECT(TPU, 0xcc0), INTC_VECT(PCC, 0xce0),
282         INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
283         INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
284         INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
285         INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
286         INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
287         INTC_VECT(TMU5, 0xe40), INTC_VECT(ADC, 0xe60),
288         INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
289         INTC_VECT(SSI2, 0xec0), INTC_VECT(SSI3, 0xee0),
290         INTC_VECT(SCIF2, 0xf00), INTC_VECT(SCIF2, 0xf20),
291         INTC_VECT(SCIF2, 0xf40), INTC_VECT(SCIF2, 0xf60),
292         INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
293         INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
294 };
295
296 static struct intc_group groups[] __initdata = {
297         INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
298         INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
299 };
300
301 static struct intc_mask_reg mask_registers[] __initdata = {
302         { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
303           { 0, 0, 0, 0, 0, 0, GPIO, 0,
304             SSI0, MMCIF, 0, SIOF0, PCIC5, PCIINTD, PCIINTC, PCIINTB,
305             PCIINTA, PCISERR, HAC, CMT, 0, 0, 0, DMAC,
306             HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
307         { 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
308           { 0, 0, 0, 0, 0, 0, SCIF2, USBF,
309             0, 0, STIF1, STIF0, 0, 0, USBH, GETHER,
310             PCC, 0, 0, ADC, TPU, SIM, SIOF2, SIOF1,
311             LCDC, 0, IIC1, IIC0, SSI3, SSI2, SSI1, 0 } },
312 };
313
314 static struct intc_prio_reg prio_registers[] __initdata = {
315         { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
316                                                  TMU2, TMU2_TICPI } },
317         { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
318         { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
319         { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC, ADC } },
320         { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
321                                                  PCISERR, PCIINTA } },
322         { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
323                                                  PCIINTD, PCIC5 } },
324         { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF0, USBF, MMCIF, SSI0 } },
325         { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SCIF2, GPIO } },
326         { 0xffd400a0, 0, 32, 8, /* INT2PRI8 */ { SSI3, SSI2, SSI1, 0 } },
327         { 0xffd400a4, 0, 32, 8, /* INT2PRI9 */ { LCDC, 0, IIC1, IIC0 } },
328         { 0xffd400a8, 0, 32, 8, /* INT2PRI10 */ { TPU, SIM, SIOF2, SIOF1 } },
329         { 0xffd400ac, 0, 32, 8, /* INT2PRI11 */ { PCC } },
330         { 0xffd400b0, 0, 32, 8, /* INT2PRI12 */ { 0, 0, USBH, GETHER } },
331         { 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } },
332 };
333
334 static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups,
335                          mask_registers, prio_registers, NULL);
336
337 /* Support for external interrupt pins in IRQ mode */
338 static struct intc_vect irq_vectors[] __initdata = {
339         INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
340         INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
341         INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
342         INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
343 };
344
345 static struct intc_mask_reg irq_mask_registers[] __initdata = {
346         { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
347           { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
348 };
349
350 static struct intc_prio_reg irq_prio_registers[] __initdata = {
351         { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
352                                                IRQ4, IRQ5, IRQ6, IRQ7 } },
353 };
354
355 static struct intc_sense_reg irq_sense_registers[] __initdata = {
356         { 0xffd0001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3,
357                                             IRQ4, IRQ5, IRQ6, IRQ7 } },
358 };
359
360 static struct intc_mask_reg irq_ack_registers[] __initdata = {
361         { 0xffd00024, 0, 32, /* INTREQ */
362           { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
363 };
364
365 static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7763-irq", irq_vectors,
366                              NULL, irq_mask_registers, irq_prio_registers,
367                              irq_sense_registers, irq_ack_registers);
368
369
370 /* External interrupt pins in IRL mode */
371 static struct intc_vect irl_vectors[] __initdata = {
372         INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
373         INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
374         INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
375         INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
376         INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
377         INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
378         INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
379         INTC_VECT(IRL_HHHL, 0x3c0),
380 };
381
382 static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
383         { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
384           { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
385             IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
386             IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
387             IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
388 };
389
390 static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
391         { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
392           { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393             IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
394             IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
395             IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
396             IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
397 };
398
399 static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors,
400                         NULL, irl7654_mask_registers, NULL, NULL);
401
402 static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
403                         NULL, irl3210_mask_registers, NULL, NULL);
404
405 #define INTC_ICR0       0xffd00000
406 #define INTC_INTMSK0    0xffd00044
407 #define INTC_INTMSK1    0xffd00048
408 #define INTC_INTMSK2    0xffd40080
409 #define INTC_INTMSKCLR1 0xffd00068
410 #define INTC_INTMSKCLR2 0xffd40084
411
412 void __init plat_irq_setup(void)
413 {
414         /* disable IRQ7-0 */
415         __raw_writel(0xff000000, INTC_INTMSK0);
416
417         /* disable IRL3-0 + IRL7-4 */
418         __raw_writel(0xc0000000, INTC_INTMSK1);
419         __raw_writel(0xfffefffe, INTC_INTMSK2);
420
421         register_intc_controller(&intc_desc);
422 }
423
424 void __init plat_irq_setup_pins(int mode)
425 {
426         switch (mode) {
427         case IRQ_MODE_IRQ:
428                 /* select IRQ mode for IRL3-0 + IRL7-4 */
429                 __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
430                 register_intc_controller(&intc_irq_desc);
431                 break;
432         case IRQ_MODE_IRL7654:
433                 /* enable IRL7-4 but don't provide any masking */
434                 __raw_writel(0x40000000, INTC_INTMSKCLR1);
435                 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
436                 break;
437         case IRQ_MODE_IRL3210:
438                 /* enable IRL0-3 but don't provide any masking */
439                 __raw_writel(0x80000000, INTC_INTMSKCLR1);
440                 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
441                 break;
442         case IRQ_MODE_IRL7654_MASK:
443                 /* enable IRL7-4 and mask using cpu intc controller */
444                 __raw_writel(0x40000000, INTC_INTMSKCLR1);
445                 register_intc_controller(&intc_irl7654_desc);
446                 break;
447         case IRQ_MODE_IRL3210_MASK:
448                 /* enable IRL0-3 and mask using cpu intc controller */
449                 __raw_writel(0x80000000, INTC_INTMSKCLR1);
450                 register_intc_controller(&intc_irl3210_desc);
451                 break;
452         default:
453                 BUG();
454         }
455 }