blob: 855b1506caf88b209187ed88d8808968e5f6bf40 [file] [log] [blame]
Magnus Dammf2aaf662010-02-05 11:15:07 +00001/*
2 * sh7377 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>
Magnus Dammc54d6ec2012-07-06 17:10:02 +090025#include <linux/of_platform.h>
Magnus Dammc9fcf002011-04-28 03:19:05 +000026#include <linux/uio_driver.h>
Magnus Dammf2aaf662010-02-05 11:15:07 +000027#include <linux/delay.h>
28#include <linux/input.h>
29#include <linux/io.h>
30#include <linux/serial_sci.h>
31#include <linux/sh_intc.h>
32#include <linux/sh_timer.h>
33#include <mach/hardware.h>
Magnus Dammbfc46f32012-02-29 21:37:12 +090034#include <mach/common.h>
35#include <asm/mach/map.h>
Rob Herring250a2722012-01-03 16:57:33 -060036#include <mach/irqs.h>
Magnus Dammf2aaf662010-02-05 11:15:07 +000037#include <asm/mach-types.h>
38#include <asm/mach/arch.h>
Magnus Damm03f7bee2012-03-06 17:36:29 +090039#include <asm/mach/time.h>
Magnus Dammf2aaf662010-02-05 11:15:07 +000040
Magnus Dammbfc46f32012-02-29 21:37:12 +090041static struct map_desc sh7377_io_desc[] __initdata = {
42 /* create a 1:1 entity map for 0xe6xxxxxx
43 * used by CPGA, INTC and PFC.
44 */
45 {
46 .virtual = 0xe6000000,
47 .pfn = __phys_to_pfn(0xe6000000),
48 .length = 256 << 20,
49 .type = MT_DEVICE_NONSHARED
50 },
51};
52
53void __init sh7377_map_io(void)
54{
55 iotable_init(sh7377_io_desc, ARRAY_SIZE(sh7377_io_desc));
56}
57
Magnus Damm043296d2010-05-20 14:39:21 +000058/* SCIFA0 */
Magnus Dammf2aaf662010-02-05 11:15:07 +000059static struct plat_sci_port scif0_platform_data = {
60 .mapbase = 0xe6c40000,
61 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +090062 .scscr = SCSCR_RE | SCSCR_TE,
63 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +000064 .type = PORT_SCIFA,
Magnus Damm043296d2010-05-20 14:39:21 +000065 .irqs = { evt2irq(0xc00), evt2irq(0xc00),
66 evt2irq(0xc00), evt2irq(0xc00) },
Magnus Dammf2aaf662010-02-05 11:15:07 +000067};
68
69static struct platform_device scif0_device = {
70 .name = "sh-sci",
71 .id = 0,
72 .dev = {
73 .platform_data = &scif0_platform_data,
74 },
75};
76
Magnus Damm043296d2010-05-20 14:39:21 +000077/* SCIFA1 */
Magnus Dammf2aaf662010-02-05 11:15:07 +000078static struct plat_sci_port scif1_platform_data = {
79 .mapbase = 0xe6c50000,
80 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +090081 .scscr = SCSCR_RE | SCSCR_TE,
82 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +000083 .type = PORT_SCIFA,
Magnus Damm043296d2010-05-20 14:39:21 +000084 .irqs = { evt2irq(0xc20), evt2irq(0xc20),
85 evt2irq(0xc20), evt2irq(0xc20) },
Magnus Dammf2aaf662010-02-05 11:15:07 +000086};
87
88static struct platform_device scif1_device = {
89 .name = "sh-sci",
90 .id = 1,
91 .dev = {
92 .platform_data = &scif1_platform_data,
93 },
94};
95
Magnus Damm043296d2010-05-20 14:39:21 +000096/* SCIFA2 */
Magnus Dammf2aaf662010-02-05 11:15:07 +000097static struct plat_sci_port scif2_platform_data = {
98 .mapbase = 0xe6c60000,
99 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +0900100 .scscr = SCSCR_RE | SCSCR_TE,
101 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +0000102 .type = PORT_SCIFA,
Magnus Damm043296d2010-05-20 14:39:21 +0000103 .irqs = { evt2irq(0xc40), evt2irq(0xc40),
104 evt2irq(0xc40), evt2irq(0xc40) },
Magnus Dammf2aaf662010-02-05 11:15:07 +0000105};
106
107static struct platform_device scif2_device = {
108 .name = "sh-sci",
109 .id = 2,
110 .dev = {
111 .platform_data = &scif2_platform_data,
112 },
113};
114
Magnus Damm043296d2010-05-20 14:39:21 +0000115/* SCIFA3 */
Magnus Dammf2aaf662010-02-05 11:15:07 +0000116static struct plat_sci_port scif3_platform_data = {
117 .mapbase = 0xe6c70000,
118 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +0900119 .scscr = SCSCR_RE | SCSCR_TE,
120 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +0000121 .type = PORT_SCIFA,
Magnus Damm043296d2010-05-20 14:39:21 +0000122 .irqs = { evt2irq(0xc60), evt2irq(0xc60),
123 evt2irq(0xc60), evt2irq(0xc60) },
Magnus Dammf2aaf662010-02-05 11:15:07 +0000124};
125
126static struct platform_device scif3_device = {
127 .name = "sh-sci",
128 .id = 3,
129 .dev = {
130 .platform_data = &scif3_platform_data,
131 },
132};
133
Magnus Damm043296d2010-05-20 14:39:21 +0000134/* SCIFA4 */
Magnus Dammf2aaf662010-02-05 11:15:07 +0000135static struct plat_sci_port scif4_platform_data = {
136 .mapbase = 0xe6c80000,
137 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +0900138 .scscr = SCSCR_RE | SCSCR_TE,
139 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +0000140 .type = PORT_SCIFA,
Magnus Damm043296d2010-05-20 14:39:21 +0000141 .irqs = { evt2irq(0xd20), evt2irq(0xd20),
142 evt2irq(0xd20), evt2irq(0xd20) },
Magnus Dammf2aaf662010-02-05 11:15:07 +0000143};
144
145static struct platform_device scif4_device = {
146 .name = "sh-sci",
147 .id = 4,
148 .dev = {
149 .platform_data = &scif4_platform_data,
150 },
151};
152
Magnus Damm043296d2010-05-20 14:39:21 +0000153/* SCIFA5 */
Magnus Dammf2aaf662010-02-05 11:15:07 +0000154static struct plat_sci_port scif5_platform_data = {
155 .mapbase = 0xe6cb0000,
156 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +0900157 .scscr = SCSCR_RE | SCSCR_TE,
158 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +0000159 .type = PORT_SCIFA,
Magnus Damm043296d2010-05-20 14:39:21 +0000160 .irqs = { evt2irq(0xd40), evt2irq(0xd40),
161 evt2irq(0xd40), evt2irq(0xd40) },
Magnus Dammf2aaf662010-02-05 11:15:07 +0000162};
163
164static struct platform_device scif5_device = {
165 .name = "sh-sci",
166 .id = 5,
167 .dev = {
168 .platform_data = &scif5_platform_data,
169 },
170};
171
Magnus Damm043296d2010-05-20 14:39:21 +0000172/* SCIFA6 */
Magnus Dammf2aaf662010-02-05 11:15:07 +0000173static struct plat_sci_port scif6_platform_data = {
174 .mapbase = 0xe6cc0000,
175 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +0900176 .scscr = SCSCR_RE | SCSCR_TE,
177 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +0000178 .type = PORT_SCIFA,
Magnus Damm043296d2010-05-20 14:39:21 +0000179 .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
180 intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
Magnus Dammf2aaf662010-02-05 11:15:07 +0000181};
182
183static struct platform_device scif6_device = {
184 .name = "sh-sci",
185 .id = 6,
186 .dev = {
187 .platform_data = &scif6_platform_data,
188 },
189};
190
Magnus Damm043296d2010-05-20 14:39:21 +0000191/* SCIFB */
Magnus Dammf2aaf662010-02-05 11:15:07 +0000192static struct plat_sci_port scif7_platform_data = {
193 .mapbase = 0xe6c30000,
194 .flags = UPF_BOOT_AUTOCONF,
Paul Mundtf43dc232011-01-13 15:06:28 +0900195 .scscr = SCSCR_RE | SCSCR_TE,
196 .scbrr_algo_id = SCBRR_ALGO_4,
Magnus Damm1d0738e2011-04-28 03:02:40 +0000197 .type = PORT_SCIFB,
Magnus Damm043296d2010-05-20 14:39:21 +0000198 .irqs = { evt2irq(0xd60), evt2irq(0xd60),
199 evt2irq(0xd60), evt2irq(0xd60) },
Magnus Dammf2aaf662010-02-05 11:15:07 +0000200};
201
202static struct platform_device scif7_device = {
203 .name = "sh-sci",
204 .id = 7,
205 .dev = {
206 .platform_data = &scif7_platform_data,
207 },
208};
209
210static struct sh_timer_config cmt10_platform_data = {
211 .name = "CMT10",
212 .channel_offset = 0x10,
213 .timer_bit = 0,
Magnus Dammf2aaf662010-02-05 11:15:07 +0000214 .clockevent_rating = 125,
215 .clocksource_rating = 125,
216};
217
218static struct resource cmt10_resources[] = {
219 [0] = {
220 .name = "CMT10",
221 .start = 0xe6138010,
222 .end = 0xe613801b,
223 .flags = IORESOURCE_MEM,
224 },
225 [1] = {
Magnus Damm043296d2010-05-20 14:39:21 +0000226 .start = evt2irq(0xb00), /* CMT1_CMT10 */
Magnus Dammf2aaf662010-02-05 11:15:07 +0000227 .flags = IORESOURCE_IRQ,
228 },
229};
230
231static struct platform_device cmt10_device = {
232 .name = "sh_cmt",
233 .id = 10,
234 .dev = {
235 .platform_data = &cmt10_platform_data,
236 },
237 .resource = cmt10_resources,
238 .num_resources = ARRAY_SIZE(cmt10_resources),
239};
240
Magnus Dammc9fcf002011-04-28 03:19:05 +0000241/* VPU */
242static struct uio_info vpu_platform_data = {
243 .name = "VPU5HG",
244 .version = "0",
245 .irq = intcs_evt2irq(0x980),
246};
247
248static struct resource vpu_resources[] = {
249 [0] = {
250 .name = "VPU",
251 .start = 0xfe900000,
252 .end = 0xfe900157,
253 .flags = IORESOURCE_MEM,
254 },
255};
256
257static struct platform_device vpu_device = {
258 .name = "uio_pdrv_genirq",
259 .id = 0,
260 .dev = {
261 .platform_data = &vpu_platform_data,
262 },
263 .resource = vpu_resources,
264 .num_resources = ARRAY_SIZE(vpu_resources),
265};
266
267/* VEU0 */
268static struct uio_info veu0_platform_data = {
269 .name = "VEU0",
270 .version = "0",
271 .irq = intcs_evt2irq(0x700),
272};
273
274static struct resource veu0_resources[] = {
275 [0] = {
276 .name = "VEU0",
277 .start = 0xfe920000,
278 .end = 0xfe9200cb,
279 .flags = IORESOURCE_MEM,
280 },
281};
282
283static struct platform_device veu0_device = {
284 .name = "uio_pdrv_genirq",
285 .id = 1,
286 .dev = {
287 .platform_data = &veu0_platform_data,
288 },
289 .resource = veu0_resources,
290 .num_resources = ARRAY_SIZE(veu0_resources),
291};
292
293/* VEU1 */
294static struct uio_info veu1_platform_data = {
295 .name = "VEU1",
296 .version = "0",
297 .irq = intcs_evt2irq(0x720),
298};
299
300static struct resource veu1_resources[] = {
301 [0] = {
302 .name = "VEU1",
303 .start = 0xfe924000,
304 .end = 0xfe9240cb,
305 .flags = IORESOURCE_MEM,
306 },
307};
308
309static struct platform_device veu1_device = {
310 .name = "uio_pdrv_genirq",
311 .id = 2,
312 .dev = {
313 .platform_data = &veu1_platform_data,
314 },
315 .resource = veu1_resources,
316 .num_resources = ARRAY_SIZE(veu1_resources),
317};
318
319/* VEU2 */
320static struct uio_info veu2_platform_data = {
321 .name = "VEU2",
322 .version = "0",
323 .irq = intcs_evt2irq(0x740),
324};
325
326static struct resource veu2_resources[] = {
327 [0] = {
328 .name = "VEU2",
329 .start = 0xfe928000,
330 .end = 0xfe928307,
331 .flags = IORESOURCE_MEM,
332 },
333};
334
335static struct platform_device veu2_device = {
336 .name = "uio_pdrv_genirq",
337 .id = 3,
338 .dev = {
339 .platform_data = &veu2_platform_data,
340 },
341 .resource = veu2_resources,
342 .num_resources = ARRAY_SIZE(veu2_resources),
343};
344
345/* VEU3 */
346static struct uio_info veu3_platform_data = {
347 .name = "VEU3",
348 .version = "0",
349 .irq = intcs_evt2irq(0x760),
350};
351
352static struct resource veu3_resources[] = {
353 [0] = {
354 .name = "VEU3",
355 .start = 0xfe92c000,
356 .end = 0xfe92c307,
357 .flags = IORESOURCE_MEM,
358 },
359};
360
361static struct platform_device veu3_device = {
362 .name = "uio_pdrv_genirq",
363 .id = 4,
364 .dev = {
365 .platform_data = &veu3_platform_data,
366 },
367 .resource = veu3_resources,
368 .num_resources = ARRAY_SIZE(veu3_resources),
369};
370
371/* JPU */
372static struct uio_info jpu_platform_data = {
373 .name = "JPU",
374 .version = "0",
375 .irq = intcs_evt2irq(0x560),
376};
377
378static struct resource jpu_resources[] = {
379 [0] = {
380 .name = "JPU",
381 .start = 0xfe980000,
382 .end = 0xfe9902d3,
383 .flags = IORESOURCE_MEM,
384 },
385};
386
387static struct platform_device jpu_device = {
388 .name = "uio_pdrv_genirq",
389 .id = 5,
390 .dev = {
391 .platform_data = &jpu_platform_data,
392 },
393 .resource = jpu_resources,
394 .num_resources = ARRAY_SIZE(jpu_resources),
395};
396
397/* SPU2DSP0 */
398static struct uio_info spu0_platform_data = {
399 .name = "SPU2DSP0",
400 .version = "0",
401 .irq = evt2irq(0x1800),
402};
403
404static struct resource spu0_resources[] = {
405 [0] = {
406 .name = "SPU2DSP0",
407 .start = 0xfe200000,
408 .end = 0xfe2fffff,
409 .flags = IORESOURCE_MEM,
410 },
411};
412
413static struct platform_device spu0_device = {
414 .name = "uio_pdrv_genirq",
415 .id = 6,
416 .dev = {
417 .platform_data = &spu0_platform_data,
418 },
419 .resource = spu0_resources,
420 .num_resources = ARRAY_SIZE(spu0_resources),
421};
422
423/* SPU2DSP1 */
424static struct uio_info spu1_platform_data = {
425 .name = "SPU2DSP1",
426 .version = "0",
427 .irq = evt2irq(0x1820),
428};
429
430static struct resource spu1_resources[] = {
431 [0] = {
432 .name = "SPU2DSP1",
433 .start = 0xfe300000,
434 .end = 0xfe3fffff,
435 .flags = IORESOURCE_MEM,
436 },
437};
438
439static struct platform_device spu1_device = {
440 .name = "uio_pdrv_genirq",
441 .id = 7,
442 .dev = {
443 .platform_data = &spu1_platform_data,
444 },
445 .resource = spu1_resources,
446 .num_resources = ARRAY_SIZE(spu1_resources),
447};
448
Magnus Dammf2aaf662010-02-05 11:15:07 +0000449static struct platform_device *sh7377_early_devices[] __initdata = {
450 &scif0_device,
451 &scif1_device,
452 &scif2_device,
453 &scif3_device,
454 &scif4_device,
455 &scif5_device,
456 &scif6_device,
457 &scif7_device,
458 &cmt10_device,
459};
460
Magnus Dammc9fcf002011-04-28 03:19:05 +0000461static struct platform_device *sh7377_devices[] __initdata = {
462 &vpu_device,
463 &veu0_device,
464 &veu1_device,
465 &veu2_device,
466 &veu3_device,
467 &jpu_device,
468 &spu0_device,
469 &spu1_device,
470};
471
Magnus Dammf2aaf662010-02-05 11:15:07 +0000472void __init sh7377_add_standard_devices(void)
473{
474 platform_add_devices(sh7377_early_devices,
475 ARRAY_SIZE(sh7377_early_devices));
Magnus Dammc9fcf002011-04-28 03:19:05 +0000476
477 platform_add_devices(sh7377_devices,
478 ARRAY_SIZE(sh7377_devices));
Magnus Dammf2aaf662010-02-05 11:15:07 +0000479}
480
Magnus Damm03f7bee2012-03-06 17:36:29 +0900481static void __init sh7377_earlytimer_init(void)
482{
483 sh7377_clock_init();
484 shmobile_earlytimer_init();
485}
486
Magnus Dammf2aaf662010-02-05 11:15:07 +0000487#define SMSTPCR3 0xe615013c
488#define SMSTPCR3_CMT1 (1 << 29)
489
490void __init sh7377_add_early_devices(void)
491{
492 /* enable clock to CMT1 */
493 __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
494
495 early_platform_add_devices(sh7377_early_devices,
496 ARRAY_SIZE(sh7377_early_devices));
Magnus Dammbfc46f32012-02-29 21:37:12 +0900497
498 /* setup early console here as well */
499 shmobile_setup_console();
Magnus Damm03f7bee2012-03-06 17:36:29 +0900500
501 /* override timer setup with soc-specific code */
502 shmobile_timer.init = sh7377_earlytimer_init;
Magnus Dammf2aaf662010-02-05 11:15:07 +0000503}
Magnus Dammc54d6ec2012-07-06 17:10:02 +0900504
505#ifdef CONFIG_USE_OF
506
507void __init sh7377_add_early_devices_dt(void)
508{
509 shmobile_setup_delay(600, 1, 3); /* Cortex-A8 @ 600MHz */
510
511 early_platform_add_devices(sh7377_early_devices,
512 ARRAY_SIZE(sh7377_early_devices));
513
514 /* setup early console here as well */
515 shmobile_setup_console();
516}
517
518static const struct of_dev_auxdata sh7377_auxdata_lookup[] __initconst = {
519 { }
520};
521
522void __init sh7377_add_standard_devices_dt(void)
523{
524 /* clocks are setup late during boot in the case of DT */
525 sh7377_clock_init();
526
527 platform_add_devices(sh7377_early_devices,
528 ARRAY_SIZE(sh7377_early_devices));
529
530 of_platform_populate(NULL, of_default_bus_match_table,
531 sh7377_auxdata_lookup, NULL);
532}
533
534static const char *sh7377_boards_compat_dt[] __initdata = {
535 "renesas,sh7377",
536 NULL,
537};
538
539DT_MACHINE_START(SH7377_DT, "Generic SH7377 (Flattened Device Tree)")
540 .map_io = sh7377_map_io,
541 .init_early = sh7377_add_early_devices_dt,
542 .init_irq = sh7377_init_irq,
543 .handle_irq = shmobile_handle_irq_intc,
544 .init_machine = sh7377_add_standard_devices_dt,
545 .timer = &shmobile_timer,
546 .dt_compat = sh7377_boards_compat_dt,
547MACHINE_END
548
549#endif /* CONFIG_USE_OF */