sh: multiple vectors per irq - sh7763
[firewire-audio.git] / arch / sh / kernel / cpu / sh4a / setup-sh7763.c
blob14a916f0d75e9ad60a2643a2ec444ac8ff11aae3
1 /*
2 * SH7763 Setup
4 * Copyright (C) 2006 Paul Mundt
5 * Copyright (C) 2007 Yoshihiro Shimoda
6 * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu
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.
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>
18 static struct resource rtc_resources[] = {
19 [0] = {
20 .start = 0xffe80000,
21 .end = 0xffe80000 + 0x58 - 1,
22 .flags = IORESOURCE_IO,
24 [1] = {
25 /* Shared Period/Carry/Alarm IRQ */
26 .flags = IORESOURCE_IRQ,
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,
37 static struct plat_sci_port sci_platform_data[] = {
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,
58 static struct platform_device sci_device = {
59 .name = "sh-sci",
60 .id = -1,
61 .dev = {
62 .platform_data = sci_platform_data,
66 static struct resource usb_ohci_resources[] = {
67 [0] = {
68 .start = 0xffec8000,
69 .end = 0xffec80ff,
70 .flags = IORESOURCE_MEM,
72 [1] = {
73 .start = 83,
74 .end = 83,
75 .flags = IORESOURCE_IRQ,
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,
87 .num_resources = ARRAY_SIZE(usb_ohci_resources),
88 .resource = usb_ohci_resources,
91 static struct resource usbf_resources[] = {
92 [0] = {
93 .start = 0xffec0000,
94 .end = 0xffec00ff,
95 .flags = IORESOURCE_MEM,
97 [1] = {
98 .start = 84,
99 .end = 84,
100 .flags = IORESOURCE_IRQ,
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,
111 .num_resources = ARRAY_SIZE(usbf_resources),
112 .resource = usbf_resources,
115 static struct platform_device *sh7763_devices[] __initdata = {
116 &rtc_device,
117 &sci_device,
118 &usb_ohci_device,
119 &usbf_device,
122 static int __init sh7763_devices_setup(void)
124 return platform_add_devices(sh7763_devices,
125 ARRAY_SIZE(sh7763_devices));
127 __initcall(sh7763_devices_setup);
129 enum {
130 UNUSED = 0,
132 /* interrupt sources */
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,
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,
148 /* interrupt groups */
150 TMU012, TMU345,
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),
196 static struct intc_group groups[] __initdata = {
197 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
198 INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
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 } },
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 } },
234 static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups,
235 mask_registers, prio_registers, NULL);
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),
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 } },
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 } },
255 static struct intc_sense_reg irq_sense_registers[] __initdata = {
256 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
257 IRQ4, IRQ5, IRQ6, IRQ7 } },
260 static struct intc_mask_reg irq_ack_registers[] __initdata = {
261 { 0xffd00024, 0, 32, /* INTREQ */
262 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
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);
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),
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, } },
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, } },
299 static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors,
300 NULL, irl7654_mask_registers, NULL, NULL);
302 static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
303 NULL, irl3210_mask_registers, NULL, NULL);
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
312 void __init plat_irq_setup(void)
314 /* disable IRQ7-0 */
315 ctrl_outl(0xff000000, INTC_INTMSK0);
317 /* disable IRL3-0 + IRL7-4 */
318 ctrl_outl(0xc0000000, INTC_INTMSK1);
319 ctrl_outl(0xfffefffe, INTC_INTMSK2);
321 register_intc_controller(&intc_desc);
324 void __init plat_irq_setup_pins(int mode)
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();