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