Commit | Line | Data |
---|---|---|
f411fade MD |
1 | /* |
2 | * r8a7779 processor support | |
3 | * | |
4 | * Copyright (C) 2011 Renesas Solutions Corp. | |
5 | * Copyright (C) 2011 Magnus Damm | |
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> | |
10e8d4f6 | 24 | #include <linux/of_platform.h> |
f411fade MD |
25 | #include <linux/platform_device.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_intc.h> | |
31 | #include <linux/sh_timer.h> | |
a7b9837c | 32 | #include <linux/dma-mapping.h> |
f411fade | 33 | #include <mach/hardware.h> |
250a2723 | 34 | #include <mach/irqs.h> |
f411fade | 35 | #include <mach/r8a7779.h> |
a662c082 | 36 | #include <mach/common.h> |
f411fade MD |
37 | #include <asm/mach-types.h> |
38 | #include <asm/mach/arch.h> | |
df27a2d8 | 39 | #include <asm/mach/time.h> |
3e353b87 | 40 | #include <asm/mach/map.h> |
8bac13f5 | 41 | #include <asm/hardware/cache-l2x0.h> |
3e353b87 MD |
42 | |
43 | static struct map_desc r8a7779_io_desc[] __initdata = { | |
44 | /* 2M entity map for 0xf0000000 (MPCORE) */ | |
45 | { | |
46 | .virtual = 0xf0000000, | |
47 | .pfn = __phys_to_pfn(0xf0000000), | |
48 | .length = SZ_2M, | |
49 | .type = MT_DEVICE_NONSHARED | |
50 | }, | |
51 | /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */ | |
52 | { | |
53 | .virtual = 0xfe000000, | |
54 | .pfn = __phys_to_pfn(0xfe000000), | |
55 | .length = SZ_16M, | |
56 | .type = MT_DEVICE_NONSHARED | |
57 | }, | |
58 | }; | |
59 | ||
60 | void __init r8a7779_map_io(void) | |
61 | { | |
62 | iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc)); | |
63 | } | |
f411fade | 64 | |
8b6edf36 LP |
65 | static struct resource r8a7779_pfc_resources[] = { |
66 | [0] = { | |
67 | .start = 0xfffc0000, | |
68 | .end = 0xfffc023b, | |
69 | .flags = IORESOURCE_MEM, | |
70 | }, | |
71 | [1] = { | |
72 | .start = 0xffc40000, | |
73 | .end = 0xffc46fff, | |
74 | .flags = IORESOURCE_MEM, | |
75 | } | |
76 | }; | |
77 | ||
78 | static struct platform_device r8a7779_pfc_device = { | |
79 | .name = "pfc-r8a7779", | |
80 | .id = -1, | |
81 | .resource = r8a7779_pfc_resources, | |
82 | .num_resources = ARRAY_SIZE(r8a7779_pfc_resources), | |
83 | }; | |
84 | ||
85 | void __init r8a7779_pinmux_init(void) | |
86 | { | |
87 | platform_device_register(&r8a7779_pfc_device); | |
88 | } | |
89 | ||
f411fade MD |
90 | static struct plat_sci_port scif0_platform_data = { |
91 | .mapbase = 0xffe40000, | |
92 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, | |
93 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | |
94 | .scbrr_algo_id = SCBRR_ALGO_2, | |
95 | .type = PORT_SCIF, | |
dbe95ad0 | 96 | .irqs = SCIx_IRQ_MUXED(gic_iid(0x78)), |
f411fade MD |
97 | }; |
98 | ||
99 | static struct platform_device scif0_device = { | |
100 | .name = "sh-sci", | |
101 | .id = 0, | |
102 | .dev = { | |
103 | .platform_data = &scif0_platform_data, | |
104 | }, | |
105 | }; | |
106 | ||
107 | static struct plat_sci_port scif1_platform_data = { | |
108 | .mapbase = 0xffe41000, | |
109 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, | |
110 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | |
111 | .scbrr_algo_id = SCBRR_ALGO_2, | |
112 | .type = PORT_SCIF, | |
dbe95ad0 | 113 | .irqs = SCIx_IRQ_MUXED(gic_iid(0x79)), |
f411fade MD |
114 | }; |
115 | ||
116 | static struct platform_device scif1_device = { | |
117 | .name = "sh-sci", | |
118 | .id = 1, | |
119 | .dev = { | |
120 | .platform_data = &scif1_platform_data, | |
121 | }, | |
122 | }; | |
123 | ||
124 | static struct plat_sci_port scif2_platform_data = { | |
125 | .mapbase = 0xffe42000, | |
126 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, | |
127 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | |
128 | .scbrr_algo_id = SCBRR_ALGO_2, | |
129 | .type = PORT_SCIF, | |
dbe95ad0 | 130 | .irqs = SCIx_IRQ_MUXED(gic_iid(0x7a)), |
f411fade MD |
131 | }; |
132 | ||
133 | static struct platform_device scif2_device = { | |
134 | .name = "sh-sci", | |
135 | .id = 2, | |
136 | .dev = { | |
137 | .platform_data = &scif2_platform_data, | |
138 | }, | |
139 | }; | |
140 | ||
141 | static struct plat_sci_port scif3_platform_data = { | |
142 | .mapbase = 0xffe43000, | |
143 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, | |
144 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | |
145 | .scbrr_algo_id = SCBRR_ALGO_2, | |
146 | .type = PORT_SCIF, | |
dbe95ad0 | 147 | .irqs = SCIx_IRQ_MUXED(gic_iid(0x7b)), |
f411fade MD |
148 | }; |
149 | ||
150 | static struct platform_device scif3_device = { | |
151 | .name = "sh-sci", | |
152 | .id = 3, | |
153 | .dev = { | |
154 | .platform_data = &scif3_platform_data, | |
155 | }, | |
156 | }; | |
157 | ||
158 | static struct plat_sci_port scif4_platform_data = { | |
159 | .mapbase = 0xffe44000, | |
160 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, | |
161 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | |
162 | .scbrr_algo_id = SCBRR_ALGO_2, | |
163 | .type = PORT_SCIF, | |
dbe95ad0 | 164 | .irqs = SCIx_IRQ_MUXED(gic_iid(0x7c)), |
f411fade MD |
165 | }; |
166 | ||
167 | static struct platform_device scif4_device = { | |
168 | .name = "sh-sci", | |
169 | .id = 4, | |
170 | .dev = { | |
171 | .platform_data = &scif4_platform_data, | |
172 | }, | |
173 | }; | |
174 | ||
175 | static struct plat_sci_port scif5_platform_data = { | |
176 | .mapbase = 0xffe45000, | |
177 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, | |
178 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | |
179 | .scbrr_algo_id = SCBRR_ALGO_2, | |
180 | .type = PORT_SCIF, | |
dbe95ad0 | 181 | .irqs = SCIx_IRQ_MUXED(gic_iid(0x7d)), |
f411fade MD |
182 | }; |
183 | ||
184 | static struct platform_device scif5_device = { | |
185 | .name = "sh-sci", | |
186 | .id = 5, | |
187 | .dev = { | |
188 | .platform_data = &scif5_platform_data, | |
189 | }, | |
190 | }; | |
191 | ||
192 | /* TMU */ | |
193 | static struct sh_timer_config tmu00_platform_data = { | |
194 | .name = "TMU00", | |
195 | .channel_offset = 0x4, | |
196 | .timer_bit = 0, | |
197 | .clockevent_rating = 200, | |
198 | }; | |
199 | ||
200 | static struct resource tmu00_resources[] = { | |
201 | [0] = { | |
202 | .name = "TMU00", | |
203 | .start = 0xffd80008, | |
204 | .end = 0xffd80013, | |
205 | .flags = IORESOURCE_MEM, | |
206 | }, | |
207 | [1] = { | |
dbe95ad0 | 208 | .start = gic_iid(0x40), |
f411fade MD |
209 | .flags = IORESOURCE_IRQ, |
210 | }, | |
211 | }; | |
212 | ||
213 | static struct platform_device tmu00_device = { | |
214 | .name = "sh_tmu", | |
215 | .id = 0, | |
216 | .dev = { | |
217 | .platform_data = &tmu00_platform_data, | |
218 | }, | |
219 | .resource = tmu00_resources, | |
220 | .num_resources = ARRAY_SIZE(tmu00_resources), | |
221 | }; | |
222 | ||
223 | static struct sh_timer_config tmu01_platform_data = { | |
224 | .name = "TMU01", | |
225 | .channel_offset = 0x10, | |
226 | .timer_bit = 1, | |
227 | .clocksource_rating = 200, | |
228 | }; | |
229 | ||
230 | static struct resource tmu01_resources[] = { | |
231 | [0] = { | |
232 | .name = "TMU01", | |
233 | .start = 0xffd80014, | |
234 | .end = 0xffd8001f, | |
235 | .flags = IORESOURCE_MEM, | |
236 | }, | |
237 | [1] = { | |
dbe95ad0 | 238 | .start = gic_iid(0x41), |
f411fade MD |
239 | .flags = IORESOURCE_IRQ, |
240 | }, | |
241 | }; | |
242 | ||
243 | static struct platform_device tmu01_device = { | |
244 | .name = "sh_tmu", | |
245 | .id = 1, | |
246 | .dev = { | |
247 | .platform_data = &tmu01_platform_data, | |
248 | }, | |
249 | .resource = tmu01_resources, | |
250 | .num_resources = ARRAY_SIZE(tmu01_resources), | |
251 | }; | |
252 | ||
ccc2a27b KM |
253 | /* I2C */ |
254 | static struct resource rcar_i2c0_res[] = { | |
255 | { | |
256 | .start = 0xffc70000, | |
257 | .end = 0xffc70fff, | |
258 | .flags = IORESOURCE_MEM, | |
259 | }, { | |
dbe95ad0 | 260 | .start = gic_iid(0x6f), |
ccc2a27b KM |
261 | .flags = IORESOURCE_IRQ, |
262 | }, | |
263 | }; | |
264 | ||
265 | static struct platform_device i2c0_device = { | |
266 | .name = "i2c-rcar", | |
267 | .id = 0, | |
268 | .resource = rcar_i2c0_res, | |
269 | .num_resources = ARRAY_SIZE(rcar_i2c0_res), | |
270 | }; | |
271 | ||
272 | static struct resource rcar_i2c1_res[] = { | |
273 | { | |
274 | .start = 0xffc71000, | |
275 | .end = 0xffc71fff, | |
276 | .flags = IORESOURCE_MEM, | |
277 | }, { | |
dbe95ad0 | 278 | .start = gic_iid(0x72), |
ccc2a27b KM |
279 | .flags = IORESOURCE_IRQ, |
280 | }, | |
281 | }; | |
282 | ||
283 | static struct platform_device i2c1_device = { | |
284 | .name = "i2c-rcar", | |
285 | .id = 1, | |
286 | .resource = rcar_i2c1_res, | |
287 | .num_resources = ARRAY_SIZE(rcar_i2c1_res), | |
288 | }; | |
289 | ||
290 | static struct resource rcar_i2c2_res[] = { | |
291 | { | |
292 | .start = 0xffc72000, | |
293 | .end = 0xffc72fff, | |
294 | .flags = IORESOURCE_MEM, | |
295 | }, { | |
dbe95ad0 | 296 | .start = gic_iid(0x70), |
ccc2a27b KM |
297 | .flags = IORESOURCE_IRQ, |
298 | }, | |
299 | }; | |
300 | ||
301 | static struct platform_device i2c2_device = { | |
302 | .name = "i2c-rcar", | |
303 | .id = 2, | |
304 | .resource = rcar_i2c2_res, | |
305 | .num_resources = ARRAY_SIZE(rcar_i2c2_res), | |
306 | }; | |
307 | ||
308 | static struct resource rcar_i2c3_res[] = { | |
309 | { | |
310 | .start = 0xffc73000, | |
311 | .end = 0xffc73fff, | |
312 | .flags = IORESOURCE_MEM, | |
313 | }, { | |
dbe95ad0 | 314 | .start = gic_iid(0x71), |
ccc2a27b KM |
315 | .flags = IORESOURCE_IRQ, |
316 | }, | |
317 | }; | |
318 | ||
319 | static struct platform_device i2c3_device = { | |
320 | .name = "i2c-rcar", | |
321 | .id = 3, | |
322 | .resource = rcar_i2c3_res, | |
323 | .num_resources = ARRAY_SIZE(rcar_i2c3_res), | |
324 | }; | |
325 | ||
a7b9837c VB |
326 | static struct resource sata_resources[] = { |
327 | [0] = { | |
328 | .name = "rcar-sata", | |
329 | .start = 0xfc600000, | |
330 | .end = 0xfc601fff, | |
331 | .flags = IORESOURCE_MEM, | |
332 | }, | |
333 | [1] = { | |
d60cd5f1 | 334 | .start = gic_iid(0x84), |
a7b9837c VB |
335 | .flags = IORESOURCE_IRQ, |
336 | }, | |
337 | }; | |
338 | ||
339 | static struct platform_device sata_device = { | |
340 | .name = "sata_rcar", | |
341 | .id = -1, | |
342 | .resource = sata_resources, | |
343 | .num_resources = ARRAY_SIZE(sata_resources), | |
344 | .dev = { | |
345 | .dma_mask = &sata_device.dev.coherent_dma_mask, | |
346 | .coherent_dma_mask = DMA_BIT_MASK(32), | |
347 | }, | |
348 | }; | |
349 | ||
916ddc35 | 350 | static struct platform_device *r8a7779_devices_dt[] __initdata = { |
f411fade MD |
351 | &scif0_device, |
352 | &scif1_device, | |
353 | &scif2_device, | |
354 | &scif3_device, | |
355 | &scif4_device, | |
356 | &scif5_device, | |
357 | &tmu00_device, | |
358 | &tmu01_device, | |
10e8d4f6 SH |
359 | }; |
360 | ||
e7921202 | 361 | static struct platform_device *r8a7779_late_devices[] __initdata = { |
ccc2a27b KM |
362 | &i2c0_device, |
363 | &i2c1_device, | |
364 | &i2c2_device, | |
365 | &i2c3_device, | |
a7b9837c | 366 | &sata_device, |
f411fade MD |
367 | }; |
368 | ||
f411fade MD |
369 | void __init r8a7779_add_standard_devices(void) |
370 | { | |
8bac13f5 MD |
371 | #ifdef CONFIG_CACHE_L2X0 |
372 | /* Early BRESP enable, Shared attribute override enable, 64K*16way */ | |
ed7d132a | 373 | l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff); |
8bac13f5 | 374 | #endif |
a662c082 MD |
375 | r8a7779_pm_init(); |
376 | ||
45e5ca57 | 377 | r8a7779_init_pm_domains(); |
a662c082 | 378 | |
916ddc35 SH |
379 | platform_add_devices(r8a7779_devices_dt, |
380 | ARRAY_SIZE(r8a7779_devices_dt)); | |
e7921202 SH |
381 | platform_add_devices(r8a7779_late_devices, |
382 | ARRAY_SIZE(r8a7779_late_devices)); | |
f411fade MD |
383 | } |
384 | ||
b759bd11 MD |
385 | /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ |
386 | void __init __weak r8a7779_register_twd(void) { } | |
387 | ||
6bb27d73 | 388 | void __init r8a7779_earlytimer_init(void) |
df27a2d8 MD |
389 | { |
390 | r8a7779_clock_init(); | |
391 | shmobile_earlytimer_init(); | |
b759bd11 | 392 | r8a7779_register_twd(); |
df27a2d8 MD |
393 | } |
394 | ||
f411fade MD |
395 | void __init r8a7779_add_early_devices(void) |
396 | { | |
916ddc35 SH |
397 | early_platform_add_devices(r8a7779_devices_dt, |
398 | ARRAY_SIZE(r8a7779_devices_dt)); | |
3e353b87 MD |
399 | |
400 | /* Early serial console setup is not included here due to | |
401 | * memory map collisions. The SCIF serial ports in r8a7779 | |
402 | * are difficult to entity map 1:1 due to collision with the | |
403 | * virtual memory range used by the coherent DMA code on ARM. | |
404 | * | |
405 | * Anyone wanting to debug early can remove UPF_IOREMAP from | |
406 | * the sh-sci serial console platform data, adjust mapbase | |
407 | * to a static M:N virt:phys mapping that needs to be added to | |
408 | * the mappings passed with iotable_init() above. | |
409 | * | |
410 | * Then add a call to shmobile_setup_console() from this function. | |
411 | * | |
412 | * As a final step pass earlyprint=sh-sci.2,115200 on the kernel | |
413 | * command line in case of the marzen board. | |
414 | */ | |
f411fade | 415 | } |
10e8d4f6 SH |
416 | |
417 | #ifdef CONFIG_USE_OF | |
916ddc35 | 418 | void __init r8a7779_init_delay(void) |
10e8d4f6 SH |
419 | { |
420 | shmobile_setup_delay(1000, 2, 4); /* Cortex-A9 @ 1000MHz */ | |
10e8d4f6 SH |
421 | } |
422 | ||
423 | static const struct of_dev_auxdata r8a7779_auxdata_lookup[] __initconst = { | |
424 | {}, | |
425 | }; | |
426 | ||
427 | void __init r8a7779_add_standard_devices_dt(void) | |
428 | { | |
429 | /* clocks are setup late during boot in the case of DT */ | |
430 | r8a7779_clock_init(); | |
431 | ||
916ddc35 SH |
432 | platform_add_devices(r8a7779_devices_dt, |
433 | ARRAY_SIZE(r8a7779_devices_dt)); | |
10e8d4f6 SH |
434 | of_platform_populate(NULL, of_default_bus_match_table, |
435 | r8a7779_auxdata_lookup, NULL); | |
436 | } | |
437 | ||
438 | static const char *r8a7779_compat_dt[] __initdata = { | |
439 | "renesas,r8a7779", | |
440 | NULL, | |
441 | }; | |
442 | ||
abe0e14b | 443 | DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") |
10e8d4f6 | 444 | .map_io = r8a7779_map_io, |
916ddc35 | 445 | .init_early = r8a7779_init_delay, |
10e8d4f6 SH |
446 | .nr_irqs = NR_IRQS_LEGACY, |
447 | .init_irq = r8a7779_init_irq_dt, | |
448 | .init_machine = r8a7779_add_standard_devices_dt, | |
449 | .init_time = shmobile_timer_init, | |
450 | .dt_compat = r8a7779_compat_dt, | |
451 | MACHINE_END | |
452 | #endif /* CONFIG_USE_OF */ |