Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
setup-sh7377.c
Go to the documentation of this file.
1 /*
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>
25 #include <linux/of_platform.h>
26 #include <linux/uio_driver.h>
27 #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>
34 #include <mach/common.h>
35 #include <asm/mach/map.h>
36 #include <mach/irqs.h>
37 #include <asm/mach-types.h>
38 #include <asm/mach/arch.h>
39 #include <asm/mach/time.h>
40 
41 static 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 
54 {
55  iotable_init(sh7377_io_desc, ARRAY_SIZE(sh7377_io_desc));
56 }
57 
58 /* SCIFA0 */
59 static struct plat_sci_port scif0_platform_data = {
60  .mapbase = 0xe6c40000,
61  .flags = UPF_BOOT_AUTOCONF,
62  .scscr = SCSCR_RE | SCSCR_TE,
63  .scbrr_algo_id = SCBRR_ALGO_4,
64  .type = PORT_SCIFA,
65  .irqs = { evt2irq(0xc00), evt2irq(0xc00),
66  evt2irq(0xc00), evt2irq(0xc00) },
67 };
68 
69 static struct platform_device scif0_device = {
70  .name = "sh-sci",
71  .id = 0,
72  .dev = {
73  .platform_data = &scif0_platform_data,
74  },
75 };
76 
77 /* SCIFA1 */
78 static struct plat_sci_port scif1_platform_data = {
79  .mapbase = 0xe6c50000,
80  .flags = UPF_BOOT_AUTOCONF,
81  .scscr = SCSCR_RE | SCSCR_TE,
82  .scbrr_algo_id = SCBRR_ALGO_4,
83  .type = PORT_SCIFA,
84  .irqs = { evt2irq(0xc20), evt2irq(0xc20),
85  evt2irq(0xc20), evt2irq(0xc20) },
86 };
87 
88 static struct platform_device scif1_device = {
89  .name = "sh-sci",
90  .id = 1,
91  .dev = {
92  .platform_data = &scif1_platform_data,
93  },
94 };
95 
96 /* SCIFA2 */
97 static struct plat_sci_port scif2_platform_data = {
98  .mapbase = 0xe6c60000,
99  .flags = UPF_BOOT_AUTOCONF,
100  .scscr = SCSCR_RE | SCSCR_TE,
101  .scbrr_algo_id = SCBRR_ALGO_4,
102  .type = PORT_SCIFA,
103  .irqs = { evt2irq(0xc40), evt2irq(0xc40),
104  evt2irq(0xc40), evt2irq(0xc40) },
105 };
106 
107 static struct platform_device scif2_device = {
108  .name = "sh-sci",
109  .id = 2,
110  .dev = {
111  .platform_data = &scif2_platform_data,
112  },
113 };
114 
115 /* SCIFA3 */
116 static struct plat_sci_port scif3_platform_data = {
117  .mapbase = 0xe6c70000,
118  .flags = UPF_BOOT_AUTOCONF,
119  .scscr = SCSCR_RE | SCSCR_TE,
120  .scbrr_algo_id = SCBRR_ALGO_4,
121  .type = PORT_SCIFA,
122  .irqs = { evt2irq(0xc60), evt2irq(0xc60),
123  evt2irq(0xc60), evt2irq(0xc60) },
124 };
125 
126 static struct platform_device scif3_device = {
127  .name = "sh-sci",
128  .id = 3,
129  .dev = {
130  .platform_data = &scif3_platform_data,
131  },
132 };
133 
134 /* SCIFA4 */
135 static struct plat_sci_port scif4_platform_data = {
136  .mapbase = 0xe6c80000,
137  .flags = UPF_BOOT_AUTOCONF,
138  .scscr = SCSCR_RE | SCSCR_TE,
139  .scbrr_algo_id = SCBRR_ALGO_4,
140  .type = PORT_SCIFA,
141  .irqs = { evt2irq(0xd20), evt2irq(0xd20),
142  evt2irq(0xd20), evt2irq(0xd20) },
143 };
144 
145 static struct platform_device scif4_device = {
146  .name = "sh-sci",
147  .id = 4,
148  .dev = {
149  .platform_data = &scif4_platform_data,
150  },
151 };
152 
153 /* SCIFA5 */
154 static struct plat_sci_port scif5_platform_data = {
155  .mapbase = 0xe6cb0000,
156  .flags = UPF_BOOT_AUTOCONF,
157  .scscr = SCSCR_RE | SCSCR_TE,
158  .scbrr_algo_id = SCBRR_ALGO_4,
159  .type = PORT_SCIFA,
160  .irqs = { evt2irq(0xd40), evt2irq(0xd40),
161  evt2irq(0xd40), evt2irq(0xd40) },
162 };
163 
164 static struct platform_device scif5_device = {
165  .name = "sh-sci",
166  .id = 5,
167  .dev = {
168  .platform_data = &scif5_platform_data,
169  },
170 };
171 
172 /* SCIFA6 */
173 static struct plat_sci_port scif6_platform_data = {
174  .mapbase = 0xe6cc0000,
175  .flags = UPF_BOOT_AUTOCONF,
176  .scscr = SCSCR_RE | SCSCR_TE,
177  .scbrr_algo_id = SCBRR_ALGO_4,
178  .type = PORT_SCIFA,
179  .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
180  intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
181 };
182 
183 static struct platform_device scif6_device = {
184  .name = "sh-sci",
185  .id = 6,
186  .dev = {
187  .platform_data = &scif6_platform_data,
188  },
189 };
190 
191 /* SCIFB */
192 static struct plat_sci_port scif7_platform_data = {
193  .mapbase = 0xe6c30000,
194  .flags = UPF_BOOT_AUTOCONF,
195  .scscr = SCSCR_RE | SCSCR_TE,
196  .scbrr_algo_id = SCBRR_ALGO_4,
197  .type = PORT_SCIFB,
198  .irqs = { evt2irq(0xd60), evt2irq(0xd60),
199  evt2irq(0xd60), evt2irq(0xd60) },
200 };
201 
202 static struct platform_device scif7_device = {
203  .name = "sh-sci",
204  .id = 7,
205  .dev = {
206  .platform_data = &scif7_platform_data,
207  },
208 };
209 
210 static struct sh_timer_config cmt10_platform_data = {
211  .name = "CMT10",
212  .channel_offset = 0x10,
213  .timer_bit = 0,
214  .clockevent_rating = 125,
215  .clocksource_rating = 125,
216 };
217 
218 static struct resource cmt10_resources[] = {
219  [0] = {
220  .name = "CMT10",
221  .start = 0xe6138010,
222  .end = 0xe613801b,
223  .flags = IORESOURCE_MEM,
224  },
225  [1] = {
226  .start = evt2irq(0xb00), /* CMT1_CMT10 */
227  .flags = IORESOURCE_IRQ,
228  },
229 };
230 
231 static 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 
241 /* VPU */
242 static struct uio_info vpu_platform_data = {
243  .name = "VPU5HG",
244  .version = "0",
245  .irq = intcs_evt2irq(0x980),
246 };
247 
248 static struct resource vpu_resources[] = {
249  [0] = {
250  .name = "VPU",
251  .start = 0xfe900000,
252  .end = 0xfe900157,
253  .flags = IORESOURCE_MEM,
254  },
255 };
256 
257 static 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 */
268 static struct uio_info veu0_platform_data = {
269  .name = "VEU0",
270  .version = "0",
271  .irq = intcs_evt2irq(0x700),
272 };
273 
274 static struct resource veu0_resources[] = {
275  [0] = {
276  .name = "VEU0",
277  .start = 0xfe920000,
278  .end = 0xfe9200cb,
279  .flags = IORESOURCE_MEM,
280  },
281 };
282 
283 static 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 */
294 static struct uio_info veu1_platform_data = {
295  .name = "VEU1",
296  .version = "0",
297  .irq = intcs_evt2irq(0x720),
298 };
299 
300 static struct resource veu1_resources[] = {
301  [0] = {
302  .name = "VEU1",
303  .start = 0xfe924000,
304  .end = 0xfe9240cb,
305  .flags = IORESOURCE_MEM,
306  },
307 };
308 
309 static 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 */
320 static struct uio_info veu2_platform_data = {
321  .name = "VEU2",
322  .version = "0",
323  .irq = intcs_evt2irq(0x740),
324 };
325 
326 static struct resource veu2_resources[] = {
327  [0] = {
328  .name = "VEU2",
329  .start = 0xfe928000,
330  .end = 0xfe928307,
331  .flags = IORESOURCE_MEM,
332  },
333 };
334 
335 static 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 */
346 static struct uio_info veu3_platform_data = {
347  .name = "VEU3",
348  .version = "0",
349  .irq = intcs_evt2irq(0x760),
350 };
351 
352 static struct resource veu3_resources[] = {
353  [0] = {
354  .name = "VEU3",
355  .start = 0xfe92c000,
356  .end = 0xfe92c307,
357  .flags = IORESOURCE_MEM,
358  },
359 };
360 
361 static 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 */
372 static struct uio_info jpu_platform_data = {
373  .name = "JPU",
374  .version = "0",
375  .irq = intcs_evt2irq(0x560),
376 };
377 
378 static struct resource jpu_resources[] = {
379  [0] = {
380  .name = "JPU",
381  .start = 0xfe980000,
382  .end = 0xfe9902d3,
383  .flags = IORESOURCE_MEM,
384  },
385 };
386 
387 static 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 */
398 static struct uio_info spu0_platform_data = {
399  .name = "SPU2DSP0",
400  .version = "0",
401  .irq = evt2irq(0x1800),
402 };
403 
404 static struct resource spu0_resources[] = {
405  [0] = {
406  .name = "SPU2DSP0",
407  .start = 0xfe200000,
408  .end = 0xfe2fffff,
409  .flags = IORESOURCE_MEM,
410  },
411 };
412 
413 static 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 */
424 static struct uio_info spu1_platform_data = {
425  .name = "SPU2DSP1",
426  .version = "0",
427  .irq = evt2irq(0x1820),
428 };
429 
430 static struct resource spu1_resources[] = {
431  [0] = {
432  .name = "SPU2DSP1",
433  .start = 0xfe300000,
434  .end = 0xfe3fffff,
435  .flags = IORESOURCE_MEM,
436  },
437 };
438 
439 static 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 
449 static 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 
461 static 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 
473 {
474  platform_add_devices(sh7377_early_devices,
475  ARRAY_SIZE(sh7377_early_devices));
476 
477  platform_add_devices(sh7377_devices,
478  ARRAY_SIZE(sh7377_devices));
479 }
480 
481 static void __init sh7377_earlytimer_init(void)
482 {
485 }
486 
487 #define SMSTPCR3 IOMEM(0xe615013c)
488 #define SMSTPCR3_CMT1 (1 << 29)
489 
491 {
492  /* enable clock to CMT1 */
494 
495  early_platform_add_devices(sh7377_early_devices,
496  ARRAY_SIZE(sh7377_early_devices));
497 
498  /* setup early console here as well */
500 
501  /* override timer setup with soc-specific code */
502  shmobile_timer.init = sh7377_earlytimer_init;
503 }
504 
505 #ifdef CONFIG_USE_OF
506 
507 void __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 */
516 }
517 
518 static const struct of_dev_auxdata sh7377_auxdata_lookup[] __initconst = {
519  { }
520 };
521 
522 void __init sh7377_add_standard_devices_dt(void)
523 {
524  /* clocks are setup late during boot in the case of DT */
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 
534 static const char *sh7377_boards_compat_dt[] __initdata = {
535  "renesas,sh7377",
536  NULL,
537 };
538 
539 DT_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,
548 
549 #endif /* CONFIG_USE_OF */