1 /*
2  * sh7367 processor support
3  *
4  * Copyright (C) 2010  Magnus Damm
5  * Copyright (C) 2008  Yoshihiro Shimoda
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; version 2 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/platform_device.h>
25 #include <linux/uio_driver.h>
26 #include <linux/delay.h>
27 #include <linux/input.h>
28 #include <linux/io.h>
29 #include <linux/serial_sci.h>
30 #include <linux/sh_timer.h>
31 #include <mach/hardware.h>
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 
35 /* SCIFA0 */
36 static struct plat_sci_port scif0_platform_data = {
37 	.mapbase	= 0xe6c40000,
38 	.flags		= UPF_BOOT_AUTOCONF,
39 	.scscr		= SCSCR_RE | SCSCR_TE,
40 	.scbrr_algo_id	= SCBRR_ALGO_4,
41 	.type		= PORT_SCIFA,
42 	.irqs		= { evt2irq(0xc00), evt2irq(0xc00),
43 			    evt2irq(0xc00), evt2irq(0xc00) },
44 };
45 
46 static struct platform_device scif0_device = {
47 	.name		= "sh-sci",
48 	.id		= 0,
49 	.dev		= {
50 		.platform_data	= &scif0_platform_data,
51 	},
52 };
53 
54 /* SCIFA1 */
55 static struct plat_sci_port scif1_platform_data = {
56 	.mapbase	= 0xe6c50000,
57 	.flags		= UPF_BOOT_AUTOCONF,
58 	.scscr		= SCSCR_RE | SCSCR_TE,
59 	.scbrr_algo_id	= SCBRR_ALGO_4,
60 	.type		= PORT_SCIFA,
61 	.irqs		= { evt2irq(0xc20), evt2irq(0xc20),
62 			    evt2irq(0xc20), evt2irq(0xc20) },
63 };
64 
65 static struct platform_device scif1_device = {
66 	.name		= "sh-sci",
67 	.id		= 1,
68 	.dev		= {
69 		.platform_data	= &scif1_platform_data,
70 	},
71 };
72 
73 /* SCIFA2 */
74 static struct plat_sci_port scif2_platform_data = {
75 	.mapbase	= 0xe6c60000,
76 	.flags		= UPF_BOOT_AUTOCONF,
77 	.scscr		= SCSCR_RE | SCSCR_TE,
78 	.scbrr_algo_id	= SCBRR_ALGO_4,
79 	.type		= PORT_SCIFA,
80 	.irqs		= { evt2irq(0xc40), evt2irq(0xc40),
81 			    evt2irq(0xc40), evt2irq(0xc40) },
82 };
83 
84 static struct platform_device scif2_device = {
85 	.name		= "sh-sci",
86 	.id		= 2,
87 	.dev		= {
88 		.platform_data	= &scif2_platform_data,
89 	},
90 };
91 
92 /* SCIFA3 */
93 static struct plat_sci_port scif3_platform_data = {
94 	.mapbase	= 0xe6c70000,
95 	.flags		= UPF_BOOT_AUTOCONF,
96 	.scscr		= SCSCR_RE | SCSCR_TE,
97 	.scbrr_algo_id	= SCBRR_ALGO_4,
98 	.type		= PORT_SCIFA,
99 	.irqs		= { evt2irq(0xc60), evt2irq(0xc60),
100 			    evt2irq(0xc60), evt2irq(0xc60) },
101 };
102 
103 static struct platform_device scif3_device = {
104 	.name		= "sh-sci",
105 	.id		= 3,
106 	.dev		= {
107 		.platform_data	= &scif3_platform_data,
108 	},
109 };
110 
111 /* SCIFA4 */
112 static struct plat_sci_port scif4_platform_data = {
113 	.mapbase	= 0xe6c80000,
114 	.flags		= UPF_BOOT_AUTOCONF,
115 	.scscr		= SCSCR_RE | SCSCR_TE,
116 	.scbrr_algo_id	= SCBRR_ALGO_4,
117 	.type		= PORT_SCIFA,
118 	.irqs		= { evt2irq(0xd20), evt2irq(0xd20),
119 			    evt2irq(0xd20), evt2irq(0xd20) },
120 };
121 
122 static struct platform_device scif4_device = {
123 	.name		= "sh-sci",
124 	.id		= 4,
125 	.dev		= {
126 		.platform_data	= &scif4_platform_data,
127 	},
128 };
129 
130 /* SCIFA5 */
131 static struct plat_sci_port scif5_platform_data = {
132 	.mapbase	= 0xe6cb0000,
133 	.flags		= UPF_BOOT_AUTOCONF,
134 	.scscr		= SCSCR_RE | SCSCR_TE,
135 	.scbrr_algo_id	= SCBRR_ALGO_4,
136 	.type		= PORT_SCIFA,
137 	.irqs		= { evt2irq(0xd40), evt2irq(0xd40),
138 			    evt2irq(0xd40), evt2irq(0xd40) },
139 };
140 
141 static struct platform_device scif5_device = {
142 	.name		= "sh-sci",
143 	.id		= 5,
144 	.dev		= {
145 		.platform_data	= &scif5_platform_data,
146 	},
147 };
148 
149 /* SCIFB */
150 static struct plat_sci_port scif6_platform_data = {
151 	.mapbase	= 0xe6c30000,
152 	.flags		= UPF_BOOT_AUTOCONF,
153 	.scscr		= SCSCR_RE | SCSCR_TE,
154 	.scbrr_algo_id	= SCBRR_ALGO_4,
155 	.type		= PORT_SCIFB,
156 	.irqs		= { evt2irq(0xd60), evt2irq(0xd60),
157 			    evt2irq(0xd60), evt2irq(0xd60) },
158 };
159 
160 static struct platform_device scif6_device = {
161 	.name		= "sh-sci",
162 	.id		= 6,
163 	.dev		= {
164 		.platform_data	= &scif6_platform_data,
165 	},
166 };
167 
168 static struct sh_timer_config cmt10_platform_data = {
169 	.name = "CMT10",
170 	.channel_offset = 0x10,
171 	.timer_bit = 0,
172 	.clockevent_rating = 125,
173 	.clocksource_rating = 125,
174 };
175 
176 static struct resource cmt10_resources[] = {
177 	[0] = {
178 		.name	= "CMT10",
179 		.start	= 0xe6138010,
180 		.end	= 0xe613801b,
181 		.flags	= IORESOURCE_MEM,
182 	},
183 	[1] = {
184 		.start	= evt2irq(0xb00), /* CMT1_CMT10 */
185 		.flags	= IORESOURCE_IRQ,
186 	},
187 };
188 
189 static struct platform_device cmt10_device = {
190 	.name		= "sh_cmt",
191 	.id		= 10,
192 	.dev = {
193 		.platform_data	= &cmt10_platform_data,
194 	},
195 	.resource	= cmt10_resources,
196 	.num_resources	= ARRAY_SIZE(cmt10_resources),
197 };
198 
199 /* VPU */
200 static struct uio_info vpu_platform_data = {
201 	.name = "VPU5",
202 	.version = "0",
203 	.irq = intcs_evt2irq(0x980),
204 };
205 
206 static struct resource vpu_resources[] = {
207 	[0] = {
208 		.name	= "VPU",
209 		.start	= 0xfe900000,
210 		.end	= 0xfe902807,
211 		.flags	= IORESOURCE_MEM,
212 	},
213 };
214 
215 static struct platform_device vpu_device = {
216 	.name		= "uio_pdrv_genirq",
217 	.id		= 0,
218 	.dev = {
219 		.platform_data	= &vpu_platform_data,
220 	},
221 	.resource	= vpu_resources,
222 	.num_resources	= ARRAY_SIZE(vpu_resources),
223 };
224 
225 /* VEU0 */
226 static struct uio_info veu0_platform_data = {
227 	.name = "VEU0",
228 	.version = "0",
229 	.irq = intcs_evt2irq(0x700),
230 };
231 
232 static struct resource veu0_resources[] = {
233 	[0] = {
234 		.name	= "VEU0",
235 		.start	= 0xfe920000,
236 		.end	= 0xfe9200b7,
237 		.flags	= IORESOURCE_MEM,
238 	},
239 };
240 
241 static struct platform_device veu0_device = {
242 	.name		= "uio_pdrv_genirq",
243 	.id		= 1,
244 	.dev = {
245 		.platform_data	= &veu0_platform_data,
246 	},
247 	.resource	= veu0_resources,
248 	.num_resources	= ARRAY_SIZE(veu0_resources),
249 };
250 
251 /* VEU1 */
252 static struct uio_info veu1_platform_data = {
253 	.name = "VEU1",
254 	.version = "0",
255 	.irq = intcs_evt2irq(0x720),
256 };
257 
258 static struct resource veu1_resources[] = {
259 	[0] = {
260 		.name	= "VEU1",
261 		.start	= 0xfe924000,
262 		.end	= 0xfe9240b7,
263 		.flags	= IORESOURCE_MEM,
264 	},
265 };
266 
267 static struct platform_device veu1_device = {
268 	.name		= "uio_pdrv_genirq",
269 	.id		= 2,
270 	.dev = {
271 		.platform_data	= &veu1_platform_data,
272 	},
273 	.resource	= veu1_resources,
274 	.num_resources	= ARRAY_SIZE(veu1_resources),
275 };
276 
277 /* VEU2 */
278 static struct uio_info veu2_platform_data = {
279 	.name = "VEU2",
280 	.version = "0",
281 	.irq = intcs_evt2irq(0x740),
282 };
283 
284 static struct resource veu2_resources[] = {
285 	[0] = {
286 		.name	= "VEU2",
287 		.start	= 0xfe928000,
288 		.end	= 0xfe9280b7,
289 		.flags	= IORESOURCE_MEM,
290 	},
291 };
292 
293 static struct platform_device veu2_device = {
294 	.name		= "uio_pdrv_genirq",
295 	.id		= 3,
296 	.dev = {
297 		.platform_data	= &veu2_platform_data,
298 	},
299 	.resource	= veu2_resources,
300 	.num_resources	= ARRAY_SIZE(veu2_resources),
301 };
302 
303 /* VEU3 */
304 static struct uio_info veu3_platform_data = {
305 	.name = "VEU3",
306 	.version = "0",
307 	.irq = intcs_evt2irq(0x760),
308 };
309 
310 static struct resource veu3_resources[] = {
311 	[0] = {
312 		.name	= "VEU3",
313 		.start	= 0xfe92c000,
314 		.end	= 0xfe92c0b7,
315 		.flags	= IORESOURCE_MEM,
316 	},
317 };
318 
319 static struct platform_device veu3_device = {
320 	.name		= "uio_pdrv_genirq",
321 	.id		= 4,
322 	.dev = {
323 		.platform_data	= &veu3_platform_data,
324 	},
325 	.resource	= veu3_resources,
326 	.num_resources	= ARRAY_SIZE(veu3_resources),
327 };
328 
329 /* VEU2H */
330 static struct uio_info veu2h_platform_data = {
331 	.name = "VEU2H",
332 	.version = "0",
333 	.irq = intcs_evt2irq(0x520),
334 };
335 
336 static struct resource veu2h_resources[] = {
337 	[0] = {
338 		.name	= "VEU2H",
339 		.start	= 0xfe93c000,
340 		.end	= 0xfe93c27b,
341 		.flags	= IORESOURCE_MEM,
342 	},
343 };
344 
345 static struct platform_device veu2h_device = {
346 	.name		= "uio_pdrv_genirq",
347 	.id		= 5,
348 	.dev = {
349 		.platform_data	= &veu2h_platform_data,
350 	},
351 	.resource	= veu2h_resources,
352 	.num_resources	= ARRAY_SIZE(veu2h_resources),
353 };
354 
355 /* JPU */
356 static struct uio_info jpu_platform_data = {
357 	.name = "JPU",
358 	.version = "0",
359 	.irq = intcs_evt2irq(0x560),
360 };
361 
362 static struct resource jpu_resources[] = {
363 	[0] = {
364 		.name	= "JPU",
365 		.start	= 0xfe980000,
366 		.end	= 0xfe9902d3,
367 		.flags	= IORESOURCE_MEM,
368 	},
369 };
370 
371 static struct platform_device jpu_device = {
372 	.name		= "uio_pdrv_genirq",
373 	.id		= 6,
374 	.dev = {
375 		.platform_data	= &jpu_platform_data,
376 	},
377 	.resource	= jpu_resources,
378 	.num_resources	= ARRAY_SIZE(jpu_resources),
379 };
380 
381 /* SPU1 */
382 static struct uio_info spu1_platform_data = {
383 	.name = "SPU1",
384 	.version = "0",
385 	.irq = evt2irq(0xfc0),
386 };
387 
388 static struct resource spu1_resources[] = {
389 	[0] = {
390 		.name	= "SPU1",
391 		.start	= 0xfe300000,
392 		.end	= 0xfe3fffff,
393 		.flags	= IORESOURCE_MEM,
394 	},
395 };
396 
397 static struct platform_device spu1_device = {
398 	.name		= "uio_pdrv_genirq",
399 	.id		= 7,
400 	.dev = {
401 		.platform_data	= &spu1_platform_data,
402 	},
403 	.resource	= spu1_resources,
404 	.num_resources	= ARRAY_SIZE(spu1_resources),
405 };
406 
407 static struct platform_device *sh7367_early_devices[] __initdata = {
408 	&scif0_device,
409 	&scif1_device,
410 	&scif2_device,
411 	&scif3_device,
412 	&scif4_device,
413 	&scif5_device,
414 	&scif6_device,
415 	&cmt10_device,
416 };
417 
418 static struct platform_device *sh7367_devices[] __initdata = {
419 	&vpu_device,
420 	&veu0_device,
421 	&veu1_device,
422 	&veu2_device,
423 	&veu3_device,
424 	&veu2h_device,
425 	&jpu_device,
426 	&spu1_device,
427 };
428 
sh7367_add_standard_devices(void)429 void __init sh7367_add_standard_devices(void)
430 {
431 	platform_add_devices(sh7367_early_devices,
432 			     ARRAY_SIZE(sh7367_early_devices));
433 
434 	platform_add_devices(sh7367_devices,
435 			    ARRAY_SIZE(sh7367_devices));
436 }
437 
438 #define SYMSTPCR2 0xe6158048
439 #define SYMSTPCR2_CMT1 (1 << 29)
440 
sh7367_add_early_devices(void)441 void __init sh7367_add_early_devices(void)
442 {
443 	/* enable clock to CMT1 */
444 	__raw_writel(__raw_readl(SYMSTPCR2) & ~SYMSTPCR2_CMT1, SYMSTPCR2);
445 
446 	early_platform_add_devices(sh7367_early_devices,
447 				   ARRAY_SIZE(sh7367_early_devices));
448 }
449