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