blob: eacb2f783693e079e74caffbbb3fc091810b2a5b [file] [log] [blame]
Magnus Dammf411fad2011-12-14 01:36:12 +09001/*
2 * r8a7779 processor support
3 *
Sergei Shtylyovdace48d2013-04-04 18:53:50 +00004 * Copyright (C) 2011, 2013 Renesas Solutions Corp.
Magnus Dammf411fad2011-12-14 01:36:12 +09005 * Copyright (C) 2011 Magnus Damm
Sergei Shtylyovdace48d2013-04-04 18:53:50 +00006 * Copyright (C) 2013 Cogent Embedded, Inc.
Magnus Dammf411fad2011-12-14 01:36:12 +09007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/irq.h>
Kuninori Morimoto5b3859d2013-08-01 23:39:56 -070025#include <linux/irqchip.h>
26#include <linux/irqchip/arm-gic.h>
Simon Horman10e8d4f2012-11-21 22:00:15 +090027#include <linux/of_platform.h>
Max Filippov441f7502013-08-25 21:46:23 +040028#include <linux/platform_data/dma-rcar-hpbdma.h>
Laurent Pinchart37a72d02013-03-10 03:31:51 +010029#include <linux/platform_data/gpio-rcar.h>
Kuninori Morimoto5b3859d2013-08-01 23:39:56 -070030#include <linux/platform_data/irq-renesas-intc-irqpin.h>
Magnus Dammf411fad2011-12-14 01:36:12 +090031#include <linux/platform_device.h>
32#include <linux/delay.h>
33#include <linux/input.h>
34#include <linux/io.h>
35#include <linux/serial_sci.h>
Magnus Dammf411fad2011-12-14 01:36:12 +090036#include <linux/sh_timer.h>
Vladimir Barinova7b98372013-02-27 23:39:14 +030037#include <linux/dma-mapping.h>
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +040038#include <linux/usb/otg.h>
Sergei Shtylyov84a812d2013-06-02 01:37:01 +040039#include <linux/usb/hcd.h>
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +040040#include <linux/usb/ehci_pdriver.h>
41#include <linux/usb/ohci_pdriver.h>
42#include <linux/pm_runtime.h>
Rob Herring250a2722012-01-03 16:57:33 -060043#include <mach/irqs.h>
Magnus Dammf411fad2011-12-14 01:36:12 +090044#include <mach/r8a7779.h>
Magnus Damma662c082012-01-10 15:50:01 +090045#include <mach/common.h>
Magnus Dammf411fad2011-12-14 01:36:12 +090046#include <asm/mach-types.h>
47#include <asm/mach/arch.h>
Magnus Dammdf27a2d2012-03-06 17:37:01 +090048#include <asm/mach/time.h>
Magnus Damm3e353b872012-02-29 21:37:43 +090049#include <asm/mach/map.h>
Magnus Damm8bac13f2012-03-01 12:48:03 +090050#include <asm/hardware/cache-l2x0.h>
Magnus Damm3e353b872012-02-29 21:37:43 +090051
52static struct map_desc r8a7779_io_desc[] __initdata = {
53 /* 2M entity map for 0xf0000000 (MPCORE) */
54 {
55 .virtual = 0xf0000000,
56 .pfn = __phys_to_pfn(0xf0000000),
57 .length = SZ_2M,
58 .type = MT_DEVICE_NONSHARED
59 },
60 /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
61 {
62 .virtual = 0xfe000000,
63 .pfn = __phys_to_pfn(0xfe000000),
64 .length = SZ_16M,
65 .type = MT_DEVICE_NONSHARED
66 },
67};
68
69void __init r8a7779_map_io(void)
70{
71 iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc));
72}
Magnus Dammf411fad2011-12-14 01:36:12 +090073
Kuninori Morimoto5b3859d2013-08-01 23:39:56 -070074/* IRQ */
75#define INT2SMSKCR0 IOMEM(0xfe7822a0)
76#define INT2SMSKCR1 IOMEM(0xfe7822a4)
77#define INT2SMSKCR2 IOMEM(0xfe7822a8)
78#define INT2SMSKCR3 IOMEM(0xfe7822ac)
79#define INT2SMSKCR4 IOMEM(0xfe7822b0)
80
81#define INT2NTSR0 IOMEM(0xfe700060)
82#define INT2NTSR1 IOMEM(0xfe700064)
83
84static struct renesas_intc_irqpin_config irqpin0_platform_data __initdata = {
85 .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
86 .sense_bitfield_width = 2,
87};
88
89static struct resource irqpin0_resources[] __initdata = {
90 DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */
91 DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */
92 DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */
93 DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */
94 DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */
95 DEFINE_RES_IRQ(gic_spi(27)), /* IRQ0 */
96 DEFINE_RES_IRQ(gic_spi(28)), /* IRQ1 */
97 DEFINE_RES_IRQ(gic_spi(29)), /* IRQ2 */
98 DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */
99};
100
101void __init r8a7779_init_irq_extpin(int irlm)
102{
103 void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
104 u32 tmp;
105
106 if (!icr0) {
107 pr_warn("r8a7779: unable to setup external irq pin mode\n");
108 return;
109 }
110
111 tmp = ioread32(icr0);
112 if (irlm)
113 tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */
114 else
115 tmp &= ~(1 << 23); /* IRL mode - not supported */
116 tmp |= (1 << 21); /* LVLMODE = 1 */
117 iowrite32(tmp, icr0);
118 iounmap(icr0);
119
120 if (irlm)
121 platform_device_register_resndata(
122 &platform_bus, "renesas_intc_irqpin", -1,
123 irqpin0_resources, ARRAY_SIZE(irqpin0_resources),
124 &irqpin0_platform_data, sizeof(irqpin0_platform_data));
125}
126
127/* PFC/GPIO */
Laurent Pinchart8b6edf32012-12-15 23:51:26 +0100128static struct resource r8a7779_pfc_resources[] = {
Magnus Damm0ccaf5b2013-04-12 14:21:29 +0200129 DEFINE_RES_MEM(0xfffc0000, 0x023c),
Laurent Pinchart8b6edf32012-12-15 23:51:26 +0100130};
131
132static struct platform_device r8a7779_pfc_device = {
133 .name = "pfc-r8a7779",
134 .id = -1,
135 .resource = r8a7779_pfc_resources,
136 .num_resources = ARRAY_SIZE(r8a7779_pfc_resources),
137};
138
Laurent Pinchart37a72d02013-03-10 03:31:51 +0100139#define R8A7779_GPIO(idx, npins) \
140static struct resource r8a7779_gpio##idx##_resources[] = { \
Magnus Damm0ccaf5b2013-04-12 14:21:29 +0200141 DEFINE_RES_MEM(0xffc40000 + (0x1000 * (idx)), 0x002c), \
142 DEFINE_RES_IRQ(gic_iid(0xad + (idx))), \
Laurent Pinchart37a72d02013-03-10 03:31:51 +0100143}; \
144 \
145static struct gpio_rcar_config r8a7779_gpio##idx##_platform_data = { \
146 .gpio_base = 32 * (idx), \
147 .irq_base = 0, \
148 .number_of_pins = npins, \
149 .pctl_name = "pfc-r8a7779", \
150}; \
151 \
152static struct platform_device r8a7779_gpio##idx##_device = { \
153 .name = "gpio_rcar", \
154 .id = idx, \
155 .resource = r8a7779_gpio##idx##_resources, \
156 .num_resources = ARRAY_SIZE(r8a7779_gpio##idx##_resources), \
157 .dev = { \
158 .platform_data = &r8a7779_gpio##idx##_platform_data, \
159 }, \
160}
161
162R8A7779_GPIO(0, 32);
163R8A7779_GPIO(1, 32);
164R8A7779_GPIO(2, 32);
165R8A7779_GPIO(3, 32);
166R8A7779_GPIO(4, 32);
167R8A7779_GPIO(5, 32);
168R8A7779_GPIO(6, 9);
169
170static struct platform_device *r8a7779_pinctrl_devices[] __initdata = {
171 &r8a7779_pfc_device,
172 &r8a7779_gpio0_device,
173 &r8a7779_gpio1_device,
174 &r8a7779_gpio2_device,
175 &r8a7779_gpio3_device,
176 &r8a7779_gpio4_device,
177 &r8a7779_gpio5_device,
178 &r8a7779_gpio6_device,
179};
180
Laurent Pinchart8b6edf32012-12-15 23:51:26 +0100181void __init r8a7779_pinmux_init(void)
182{
Laurent Pinchart37a72d02013-03-10 03:31:51 +0100183 platform_add_devices(r8a7779_pinctrl_devices,
184 ARRAY_SIZE(r8a7779_pinctrl_devices));
Laurent Pinchart8b6edf32012-12-15 23:51:26 +0100185}
186
Magnus Dammf411fad2011-12-14 01:36:12 +0900187static struct plat_sci_port scif0_platform_data = {
188 .mapbase = 0xffe40000,
189 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
190 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
191 .scbrr_algo_id = SCBRR_ALGO_2,
192 .type = PORT_SCIF,
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800193 .irqs = SCIx_IRQ_MUXED(gic_iid(0x78)),
Magnus Dammf411fad2011-12-14 01:36:12 +0900194};
195
196static struct platform_device scif0_device = {
197 .name = "sh-sci",
198 .id = 0,
199 .dev = {
200 .platform_data = &scif0_platform_data,
201 },
202};
203
204static struct plat_sci_port scif1_platform_data = {
205 .mapbase = 0xffe41000,
206 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
207 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
208 .scbrr_algo_id = SCBRR_ALGO_2,
209 .type = PORT_SCIF,
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800210 .irqs = SCIx_IRQ_MUXED(gic_iid(0x79)),
Magnus Dammf411fad2011-12-14 01:36:12 +0900211};
212
213static struct platform_device scif1_device = {
214 .name = "sh-sci",
215 .id = 1,
216 .dev = {
217 .platform_data = &scif1_platform_data,
218 },
219};
220
221static struct plat_sci_port scif2_platform_data = {
222 .mapbase = 0xffe42000,
223 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
224 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
225 .scbrr_algo_id = SCBRR_ALGO_2,
226 .type = PORT_SCIF,
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800227 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7a)),
Magnus Dammf411fad2011-12-14 01:36:12 +0900228};
229
230static struct platform_device scif2_device = {
231 .name = "sh-sci",
232 .id = 2,
233 .dev = {
234 .platform_data = &scif2_platform_data,
235 },
236};
237
238static struct plat_sci_port scif3_platform_data = {
239 .mapbase = 0xffe43000,
240 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
241 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
242 .scbrr_algo_id = SCBRR_ALGO_2,
243 .type = PORT_SCIF,
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800244 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7b)),
Magnus Dammf411fad2011-12-14 01:36:12 +0900245};
246
247static struct platform_device scif3_device = {
248 .name = "sh-sci",
249 .id = 3,
250 .dev = {
251 .platform_data = &scif3_platform_data,
252 },
253};
254
255static struct plat_sci_port scif4_platform_data = {
256 .mapbase = 0xffe44000,
257 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
258 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
259 .scbrr_algo_id = SCBRR_ALGO_2,
260 .type = PORT_SCIF,
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800261 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7c)),
Magnus Dammf411fad2011-12-14 01:36:12 +0900262};
263
264static struct platform_device scif4_device = {
265 .name = "sh-sci",
266 .id = 4,
267 .dev = {
268 .platform_data = &scif4_platform_data,
269 },
270};
271
272static struct plat_sci_port scif5_platform_data = {
273 .mapbase = 0xffe45000,
274 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
275 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
276 .scbrr_algo_id = SCBRR_ALGO_2,
277 .type = PORT_SCIF,
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800278 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7d)),
Magnus Dammf411fad2011-12-14 01:36:12 +0900279};
280
281static struct platform_device scif5_device = {
282 .name = "sh-sci",
283 .id = 5,
284 .dev = {
285 .platform_data = &scif5_platform_data,
286 },
287};
288
289/* TMU */
290static struct sh_timer_config tmu00_platform_data = {
291 .name = "TMU00",
292 .channel_offset = 0x4,
293 .timer_bit = 0,
294 .clockevent_rating = 200,
295};
296
297static struct resource tmu00_resources[] = {
298 [0] = {
299 .name = "TMU00",
300 .start = 0xffd80008,
301 .end = 0xffd80013,
302 .flags = IORESOURCE_MEM,
303 },
304 [1] = {
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800305 .start = gic_iid(0x40),
Magnus Dammf411fad2011-12-14 01:36:12 +0900306 .flags = IORESOURCE_IRQ,
307 },
308};
309
310static struct platform_device tmu00_device = {
311 .name = "sh_tmu",
312 .id = 0,
313 .dev = {
314 .platform_data = &tmu00_platform_data,
315 },
316 .resource = tmu00_resources,
317 .num_resources = ARRAY_SIZE(tmu00_resources),
318};
319
320static struct sh_timer_config tmu01_platform_data = {
321 .name = "TMU01",
322 .channel_offset = 0x10,
323 .timer_bit = 1,
324 .clocksource_rating = 200,
325};
326
327static struct resource tmu01_resources[] = {
328 [0] = {
329 .name = "TMU01",
330 .start = 0xffd80014,
331 .end = 0xffd8001f,
332 .flags = IORESOURCE_MEM,
333 },
334 [1] = {
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800335 .start = gic_iid(0x41),
Magnus Dammf411fad2011-12-14 01:36:12 +0900336 .flags = IORESOURCE_IRQ,
337 },
338};
339
340static struct platform_device tmu01_device = {
341 .name = "sh_tmu",
342 .id = 1,
343 .dev = {
344 .platform_data = &tmu01_platform_data,
345 },
346 .resource = tmu01_resources,
347 .num_resources = ARRAY_SIZE(tmu01_resources),
348};
349
Kuninori Morimotoccc2a272012-10-10 19:56:51 -0700350/* I2C */
351static struct resource rcar_i2c0_res[] = {
352 {
353 .start = 0xffc70000,
354 .end = 0xffc70fff,
355 .flags = IORESOURCE_MEM,
356 }, {
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800357 .start = gic_iid(0x6f),
Kuninori Morimotoccc2a272012-10-10 19:56:51 -0700358 .flags = IORESOURCE_IRQ,
359 },
360};
361
362static struct platform_device i2c0_device = {
363 .name = "i2c-rcar",
364 .id = 0,
365 .resource = rcar_i2c0_res,
366 .num_resources = ARRAY_SIZE(rcar_i2c0_res),
367};
368
369static struct resource rcar_i2c1_res[] = {
370 {
371 .start = 0xffc71000,
372 .end = 0xffc71fff,
373 .flags = IORESOURCE_MEM,
374 }, {
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800375 .start = gic_iid(0x72),
Kuninori Morimotoccc2a272012-10-10 19:56:51 -0700376 .flags = IORESOURCE_IRQ,
377 },
378};
379
380static struct platform_device i2c1_device = {
381 .name = "i2c-rcar",
382 .id = 1,
383 .resource = rcar_i2c1_res,
384 .num_resources = ARRAY_SIZE(rcar_i2c1_res),
385};
386
387static struct resource rcar_i2c2_res[] = {
388 {
389 .start = 0xffc72000,
390 .end = 0xffc72fff,
391 .flags = IORESOURCE_MEM,
392 }, {
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800393 .start = gic_iid(0x70),
Kuninori Morimotoccc2a272012-10-10 19:56:51 -0700394 .flags = IORESOURCE_IRQ,
395 },
396};
397
398static struct platform_device i2c2_device = {
399 .name = "i2c-rcar",
400 .id = 2,
401 .resource = rcar_i2c2_res,
402 .num_resources = ARRAY_SIZE(rcar_i2c2_res),
403};
404
405static struct resource rcar_i2c3_res[] = {
406 {
407 .start = 0xffc73000,
408 .end = 0xffc73fff,
409 .flags = IORESOURCE_MEM,
410 }, {
Kuninori Morimotodbe95ad2013-03-03 23:11:41 -0800411 .start = gic_iid(0x71),
Kuninori Morimotoccc2a272012-10-10 19:56:51 -0700412 .flags = IORESOURCE_IRQ,
413 },
414};
415
416static struct platform_device i2c3_device = {
417 .name = "i2c-rcar",
418 .id = 3,
419 .resource = rcar_i2c3_res,
420 .num_resources = ARRAY_SIZE(rcar_i2c3_res),
421};
422
Vladimir Barinova7b98372013-02-27 23:39:14 +0300423static struct resource sata_resources[] = {
424 [0] = {
425 .name = "rcar-sata",
426 .start = 0xfc600000,
427 .end = 0xfc601fff,
428 .flags = IORESOURCE_MEM,
429 },
430 [1] = {
Sergei Shtylyovd60cd5f2013-03-08 02:31:03 +0300431 .start = gic_iid(0x84),
Vladimir Barinova7b98372013-02-27 23:39:14 +0300432 .flags = IORESOURCE_IRQ,
433 },
434};
435
436static struct platform_device sata_device = {
437 .name = "sata_rcar",
438 .id = -1,
439 .resource = sata_resources,
440 .num_resources = ARRAY_SIZE(sata_resources),
441 .dev = {
442 .dma_mask = &sata_device.dev.coherent_dma_mask,
443 .coherent_dma_mask = DMA_BIT_MASK(32),
444 },
445};
446
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +0400447/* USB */
448static struct usb_phy *phy;
449
450static int usb_power_on(struct platform_device *pdev)
451{
452 if (IS_ERR(phy))
453 return PTR_ERR(phy);
454
455 pm_runtime_enable(&pdev->dev);
456 pm_runtime_get_sync(&pdev->dev);
457
458 usb_phy_init(phy);
459
460 return 0;
461}
462
463static void usb_power_off(struct platform_device *pdev)
464{
465 if (IS_ERR(phy))
466 return;
467
468 usb_phy_shutdown(phy);
469
470 pm_runtime_put_sync(&pdev->dev);
471 pm_runtime_disable(&pdev->dev);
472}
473
Sergei Shtylyov84a812d2013-06-02 01:37:01 +0400474static int ehci_init_internal_buffer(struct usb_hcd *hcd)
475{
476 /*
477 * Below are recommended values from the datasheet;
478 * see [USB :: Setting of EHCI Internal Buffer].
479 */
480 /* EHCI IP internal buffer setting */
481 iowrite32(0x00ff0040, hcd->regs + 0x0094);
482 /* EHCI IP internal buffer enable */
483 iowrite32(0x00000001, hcd->regs + 0x009C);
484
485 return 0;
486}
487
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +0400488static struct usb_ehci_pdata ehcix_pdata = {
489 .power_on = usb_power_on,
490 .power_off = usb_power_off,
491 .power_suspend = usb_power_off,
Sergei Shtylyov84a812d2013-06-02 01:37:01 +0400492 .pre_setup = ehci_init_internal_buffer,
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +0400493};
494
495static struct resource ehci0_resources[] = {
496 [0] = {
497 .start = 0xffe70000,
498 .end = 0xffe70400 - 1,
499 .flags = IORESOURCE_MEM,
500 },
501 [1] = {
502 .start = gic_iid(0x4c),
503 .flags = IORESOURCE_IRQ,
504 },
505};
506
507static struct platform_device ehci0_device = {
508 .name = "ehci-platform",
509 .id = 0,
510 .dev = {
511 .dma_mask = &ehci0_device.dev.coherent_dma_mask,
512 .coherent_dma_mask = 0xffffffff,
513 .platform_data = &ehcix_pdata,
514 },
515 .num_resources = ARRAY_SIZE(ehci0_resources),
516 .resource = ehci0_resources,
517};
518
519static struct resource ehci1_resources[] = {
520 [0] = {
521 .start = 0xfff70000,
522 .end = 0xfff70400 - 1,
523 .flags = IORESOURCE_MEM,
524 },
525 [1] = {
526 .start = gic_iid(0x4d),
527 .flags = IORESOURCE_IRQ,
528 },
529};
530
531static struct platform_device ehci1_device = {
532 .name = "ehci-platform",
533 .id = 1,
534 .dev = {
535 .dma_mask = &ehci1_device.dev.coherent_dma_mask,
536 .coherent_dma_mask = 0xffffffff,
537 .platform_data = &ehcix_pdata,
538 },
539 .num_resources = ARRAY_SIZE(ehci1_resources),
540 .resource = ehci1_resources,
541};
542
543static struct usb_ohci_pdata ohcix_pdata = {
544 .power_on = usb_power_on,
545 .power_off = usb_power_off,
546 .power_suspend = usb_power_off,
547};
548
549static struct resource ohci0_resources[] = {
550 [0] = {
551 .start = 0xffe70400,
552 .end = 0xffe70800 - 1,
553 .flags = IORESOURCE_MEM,
554 },
555 [1] = {
556 .start = gic_iid(0x4c),
557 .flags = IORESOURCE_IRQ,
558 },
559};
560
561static struct platform_device ohci0_device = {
562 .name = "ohci-platform",
563 .id = 0,
564 .dev = {
565 .dma_mask = &ohci0_device.dev.coherent_dma_mask,
566 .coherent_dma_mask = 0xffffffff,
567 .platform_data = &ohcix_pdata,
568 },
569 .num_resources = ARRAY_SIZE(ohci0_resources),
570 .resource = ohci0_resources,
571};
572
573static struct resource ohci1_resources[] = {
574 [0] = {
575 .start = 0xfff70400,
576 .end = 0xfff70800 - 1,
577 .flags = IORESOURCE_MEM,
578 },
579 [1] = {
580 .start = gic_iid(0x4d),
581 .flags = IORESOURCE_IRQ,
582 },
583};
584
585static struct platform_device ohci1_device = {
586 .name = "ohci-platform",
587 .id = 1,
588 .dev = {
589 .dma_mask = &ohci1_device.dev.coherent_dma_mask,
590 .coherent_dma_mask = 0xffffffff,
591 .platform_data = &ohcix_pdata,
592 },
593 .num_resources = ARRAY_SIZE(ohci1_resources),
594 .resource = ohci1_resources,
595};
596
Sergei Shtylyovdace48d2013-04-04 18:53:50 +0000597/* Ether */
Kuninori Morimotoc7537652013-08-01 18:33:38 -0700598static struct resource ether_resources[] __initdata = {
Sergei Shtylyovdace48d2013-04-04 18:53:50 +0000599 {
600 .start = 0xfde00000,
601 .end = 0xfde003ff,
602 .flags = IORESOURCE_MEM,
603 }, {
604 .start = gic_iid(0xb4),
605 .flags = IORESOURCE_IRQ,
606 },
607};
608
Vladimir Barinov4714a022013-08-22 17:23:13 -0300609#define R8A7779_VIN(idx) \
610static struct resource vin##idx##_resources[] __initdata = { \
611 DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \
612 DEFINE_RES_IRQ(gic_iid(0x5f + (idx))), \
613}; \
614 \
615static struct platform_device_info vin##idx##_info __initdata = { \
616 .parent = &platform_bus, \
617 .name = "r8a7779-vin", \
618 .id = idx, \
619 .res = vin##idx##_resources, \
620 .num_res = ARRAY_SIZE(vin##idx##_resources), \
621 .dma_mask = DMA_BIT_MASK(32), \
622}
623
624R8A7779_VIN(0);
625R8A7779_VIN(1);
626R8A7779_VIN(2);
627R8A7779_VIN(3);
628
629static struct platform_device_info *vin_info_table[] __initdata = {
630 &vin0_info,
631 &vin1_info,
632 &vin2_info,
633 &vin3_info,
634};
635
Max Filippov441f7502013-08-25 21:46:23 +0400636/* HPB-DMA */
637
638/* Asynchronous mode register bits */
639#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */
640#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */
641#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */
642#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */
643#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */
644#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */
645#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */
646#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */
647#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */
648#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */
649#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */
650#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */
651#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */
652#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */
653#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */
654#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */
655#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */
656#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */
657#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */
658#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */
659#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */
660#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */
661#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */
662#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */
663#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */
664#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */
665#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */
666#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */
667#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */
668#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */
669#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */
670#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */
671#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */
672#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */
673#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */
674#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */
675#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */
676#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */
677#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */
678#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */
679#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */
680#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */
681#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */
682#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */
683#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */
684#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */
685#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */
686#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */
687#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */
688#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */
689#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */
690#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */
691#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */
692#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */
693#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */
694#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */
695#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */
696#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */
697#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */
698#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */
699#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */
700#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */
701#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */
702#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */
703#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */
704#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */
705#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */
706#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */
707#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */
708#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */
709#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */
710#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */
711
712static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
713 {
714 .id = HPBDMA_SLAVE_SDHI0_TX,
715 .addr = 0xffe4c000 + 0x30,
716 .dcr = HPB_DMAE_DCR_SPDS_16BIT |
717 HPB_DMAE_DCR_DMDL |
718 HPB_DMAE_DCR_DPDS_16BIT,
719 .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
720 HPB_DMAE_ASYNCRSTR_ASRST22 |
721 HPB_DMAE_ASYNCRSTR_ASRST23,
722 .mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE |
723 HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST,
724 .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK |
725 HPB_DMAE_ASYNCMDR_ASBTMD21_MASK,
726 .port = 0x0D0C,
727 .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
728 .dma_ch = 21,
729 }, {
730 .id = HPBDMA_SLAVE_SDHI0_RX,
731 .addr = 0xffe4c000 + 0x30,
732 .dcr = HPB_DMAE_DCR_SMDL |
733 HPB_DMAE_DCR_SPDS_16BIT |
734 HPB_DMAE_DCR_DPDS_16BIT,
735 .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
736 HPB_DMAE_ASYNCRSTR_ASRST22 |
737 HPB_DMAE_ASYNCRSTR_ASRST23,
738 .mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE |
739 HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST,
740 .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK |
741 HPB_DMAE_ASYNCMDR_ASBTMD22_MASK,
742 .port = 0x0D0C,
743 .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
744 .dma_ch = 22,
745 },
746};
747
748static const struct hpb_dmae_channel hpb_dmae_channels[] = {
749 HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
750 HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
751};
752
753static struct hpb_dmae_pdata dma_platform_data __initdata = {
754 .slaves = hpb_dmae_slaves,
755 .num_slaves = ARRAY_SIZE(hpb_dmae_slaves),
756 .channels = hpb_dmae_channels,
757 .num_channels = ARRAY_SIZE(hpb_dmae_channels),
758 .ts_shift = {
759 [XMIT_SZ_8BIT] = 0,
760 [XMIT_SZ_16BIT] = 1,
761 [XMIT_SZ_32BIT] = 2,
762 },
763 .num_hw_channels = 44,
764};
765
766static struct resource hpb_dmae_resources[] __initdata = {
767 /* Channel registers */
768 DEFINE_RES_MEM(0xffc08000, 0x1000),
769 /* Common registers */
770 DEFINE_RES_MEM(0xffc09000, 0x170),
771 /* Asynchronous reset registers */
772 DEFINE_RES_MEM(0xffc00300, 4),
773 /* Asynchronous mode registers */
774 DEFINE_RES_MEM(0xffc00400, 4),
775 /* IRQ for DMA channels */
776 DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ),
777};
778
779static void __init r8a7779_register_hpb_dmae(void)
780{
781 platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1,
782 hpb_dmae_resources,
783 ARRAY_SIZE(hpb_dmae_resources),
784 &dma_platform_data,
785 sizeof(dma_platform_data));
786}
787
Simon Horman916ddc32013-02-19 10:53:05 +0900788static struct platform_device *r8a7779_devices_dt[] __initdata = {
Magnus Dammf411fad2011-12-14 01:36:12 +0900789 &scif0_device,
790 &scif1_device,
791 &scif2_device,
792 &scif3_device,
793 &scif4_device,
794 &scif5_device,
795 &tmu00_device,
796 &tmu01_device,
Simon Horman10e8d4f2012-11-21 22:00:15 +0900797};
798
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +0400799static struct platform_device *r8a7779_standard_devices[] __initdata = {
Kuninori Morimotoccc2a272012-10-10 19:56:51 -0700800 &i2c0_device,
801 &i2c1_device,
802 &i2c2_device,
803 &i2c3_device,
Vladimir Barinova7b98372013-02-27 23:39:14 +0300804 &sata_device,
Magnus Dammf411fad2011-12-14 01:36:12 +0900805};
806
Magnus Dammf411fad2011-12-14 01:36:12 +0900807void __init r8a7779_add_standard_devices(void)
808{
Magnus Damm8bac13f2012-03-01 12:48:03 +0900809#ifdef CONFIG_CACHE_L2X0
810 /* Early BRESP enable, Shared attribute override enable, 64K*16way */
Kuninori Morimotoed7d1322012-10-14 23:35:24 -0700811 l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff);
Magnus Damm8bac13f2012-03-01 12:48:03 +0900812#endif
Magnus Damma662c082012-01-10 15:50:01 +0900813 r8a7779_pm_init();
814
Rafael J. Wysocki45e5ca52012-08-07 01:14:14 +0200815 r8a7779_init_pm_domains();
Magnus Damma662c082012-01-10 15:50:01 +0900816
Simon Horman916ddc32013-02-19 10:53:05 +0900817 platform_add_devices(r8a7779_devices_dt,
818 ARRAY_SIZE(r8a7779_devices_dt));
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +0400819 platform_add_devices(r8a7779_standard_devices,
820 ARRAY_SIZE(r8a7779_standard_devices));
Max Filippov441f7502013-08-25 21:46:23 +0400821 r8a7779_register_hpb_dmae();
Magnus Dammf411fad2011-12-14 01:36:12 +0900822}
823
Sergei Shtylyovdace48d2013-04-04 18:53:50 +0000824void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
825{
Sergei Shtylyov4c370ab2013-06-09 01:24:35 +0400826 platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
Sergei Shtylyovdace48d2013-04-04 18:53:50 +0000827 ether_resources,
828 ARRAY_SIZE(ether_resources),
829 pdata, sizeof(*pdata));
830}
831
Vladimir Barinov4714a022013-08-22 17:23:13 -0300832void __init r8a7779_add_vin_device(int id, struct rcar_vin_platform_data *pdata)
833{
834 BUG_ON(id < 0 || id > 3);
835
836 vin_info_table[id]->data = pdata;
837 vin_info_table[id]->size_data = sizeof(*pdata);
838
839 platform_device_register_full(vin_info_table[id]);
840}
841
Magnus Dammb759bd12012-05-10 14:57:22 +0900842/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
843void __init __weak r8a7779_register_twd(void) { }
844
Stephen Warren6bb27d72012-11-08 12:40:59 -0700845void __init r8a7779_earlytimer_init(void)
Magnus Dammdf27a2d2012-03-06 17:37:01 +0900846{
847 r8a7779_clock_init();
Magnus Dammb759bd12012-05-10 14:57:22 +0900848 r8a7779_register_twd();
Simon Horman7658ea22013-08-08 17:59:17 +0900849 shmobile_earlytimer_init();
Magnus Dammdf27a2d2012-03-06 17:37:01 +0900850}
851
Magnus Dammf411fad2011-12-14 01:36:12 +0900852void __init r8a7779_add_early_devices(void)
853{
Simon Horman916ddc32013-02-19 10:53:05 +0900854 early_platform_add_devices(r8a7779_devices_dt,
855 ARRAY_SIZE(r8a7779_devices_dt));
Magnus Damm3e353b872012-02-29 21:37:43 +0900856
857 /* Early serial console setup is not included here due to
858 * memory map collisions. The SCIF serial ports in r8a7779
859 * are difficult to entity map 1:1 due to collision with the
860 * virtual memory range used by the coherent DMA code on ARM.
861 *
862 * Anyone wanting to debug early can remove UPF_IOREMAP from
863 * the sh-sci serial console platform data, adjust mapbase
864 * to a static M:N virt:phys mapping that needs to be added to
865 * the mappings passed with iotable_init() above.
866 *
867 * Then add a call to shmobile_setup_console() from this function.
868 *
869 * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
870 * command line in case of the marzen board.
871 */
Magnus Dammf411fad2011-12-14 01:36:12 +0900872}
Simon Horman10e8d4f2012-11-21 22:00:15 +0900873
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +0400874static struct platform_device *r8a7779_late_devices[] __initdata = {
875 &ehci0_device,
876 &ehci1_device,
877 &ohci0_device,
878 &ohci1_device,
879};
880
881void __init r8a7779_init_late(void)
882{
883 /* get USB PHY */
884 phy = usb_get_phy(USB_PHY_TYPE_USB2);
885
886 shmobile_init_late();
887 platform_add_devices(r8a7779_late_devices,
888 ARRAY_SIZE(r8a7779_late_devices));
889}
890
Simon Horman10e8d4f2012-11-21 22:00:15 +0900891#ifdef CONFIG_USE_OF
Kuninori Morimoto5b3859d2013-08-01 23:39:56 -0700892static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
893{
894 return 0; /* always allow wakeup */
895}
896
897void __init r8a7779_init_irq_dt(void)
898{
899 gic_arch_extn.irq_set_wake = r8a7779_set_wake;
900
901 irqchip_init();
902
903 /* route all interrupts to ARM */
904 __raw_writel(0xffffffff, INT2NTSR0);
905 __raw_writel(0x3fffffff, INT2NTSR1);
906
907 /* unmask all known interrupts in INTCS2 */
908 __raw_writel(0xfffffff0, INT2SMSKCR0);
909 __raw_writel(0xfff7ffff, INT2SMSKCR1);
910 __raw_writel(0xfffbffdf, INT2SMSKCR2);
911 __raw_writel(0xbffffffc, INT2SMSKCR3);
912 __raw_writel(0x003fee3f, INT2SMSKCR4);
913}
914
Simon Horman916ddc32013-02-19 10:53:05 +0900915void __init r8a7779_init_delay(void)
Simon Horman10e8d4f2012-11-21 22:00:15 +0900916{
917 shmobile_setup_delay(1000, 2, 4); /* Cortex-A9 @ 1000MHz */
Simon Horman10e8d4f2012-11-21 22:00:15 +0900918}
919
Simon Horman10e8d4f2012-11-21 22:00:15 +0900920void __init r8a7779_add_standard_devices_dt(void)
921{
922 /* clocks are setup late during boot in the case of DT */
923 r8a7779_clock_init();
924
Simon Horman916ddc32013-02-19 10:53:05 +0900925 platform_add_devices(r8a7779_devices_dt,
926 ARRAY_SIZE(r8a7779_devices_dt));
Magnus Damm41b01562013-07-01 14:41:46 +0900927 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
Simon Horman10e8d4f2012-11-21 22:00:15 +0900928}
929
930static const char *r8a7779_compat_dt[] __initdata = {
931 "renesas,r8a7779",
932 NULL,
933};
934
Kuninori Morimotoabe0e142013-03-03 23:11:20 -0800935DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
Simon Horman10e8d4f2012-11-21 22:00:15 +0900936 .map_io = r8a7779_map_io,
Simon Horman916ddc32013-02-19 10:53:05 +0900937 .init_early = r8a7779_init_delay,
Simon Horman10e8d4f2012-11-21 22:00:15 +0900938 .nr_irqs = NR_IRQS_LEGACY,
939 .init_irq = r8a7779_init_irq_dt,
940 .init_machine = r8a7779_add_standard_devices_dt,
Sergei Shtylyov2c8788b2013-06-02 01:30:15 +0400941 .init_late = r8a7779_init_late,
Simon Horman10e8d4f2012-11-21 22:00:15 +0900942 .dt_compat = r8a7779_compat_dt,
943MACHINE_END
944#endif /* CONFIG_USE_OF */