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