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