1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * R8A7740 processor support |
4 | * |
5 | * Copyright (C) 2011 Renesas Solutions Corp. |
6 | * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
7 | */ |
8 | #include <linux/kernel.h> |
9 | #include <linux/init.h> |
10 | #include <linux/io.h> |
11 | #include <linux/irqchip.h> |
12 | #include <linux/irqchip/arm-gic.h> |
13 | |
14 | #include <asm/mach/map.h> |
15 | #include <asm/mach/arch.h> |
16 | #include <asm/mach/time.h> |
17 | |
18 | #include "common.h" |
19 | |
20 | /* |
21 | * r8a7740 chip has lasting errata on MERAM buffer. |
22 | * this is work-around for it. |
23 | * see |
24 | * "Media RAM (MERAM)" on r8a7740 documentation |
25 | */ |
26 | #define MEBUFCNTR 0xFE950098 |
27 | static void __init r8a7740_meram_workaround(void) |
28 | { |
29 | void __iomem *reg; |
30 | |
31 | reg = ioremap(MEBUFCNTR, size: 4); |
32 | if (reg) { |
33 | iowrite32(0x01600164, reg); |
34 | iounmap(addr: reg); |
35 | } |
36 | } |
37 | |
38 | static void __init r8a7740_init_irq_of(void) |
39 | { |
40 | void __iomem *intc_prio_base = ioremap(offset: 0xe6900010, size: 0x10); |
41 | void __iomem *intc_msk_base = ioremap(offset: 0xe6900040, size: 0x10); |
42 | void __iomem *pfc_inta_ctrl = ioremap(offset: 0xe605807c, size: 0x4); |
43 | |
44 | irqchip_init(); |
45 | |
46 | /* route signals to GIC */ |
47 | iowrite32(0x0, pfc_inta_ctrl); |
48 | |
49 | /* |
50 | * To mask the shared interrupt to SPI 149 we must ensure to set |
51 | * PRIO *and* MASK. Else we run into IRQ floods when registering |
52 | * the intc_irqpin devices |
53 | */ |
54 | iowrite32(0x0, intc_prio_base + 0x0); |
55 | iowrite32(0x0, intc_prio_base + 0x4); |
56 | iowrite32(0x0, intc_prio_base + 0x8); |
57 | iowrite32(0x0, intc_prio_base + 0xc); |
58 | iowrite8(0xff, intc_msk_base + 0x0); |
59 | iowrite8(0xff, intc_msk_base + 0x4); |
60 | iowrite8(0xff, intc_msk_base + 0x8); |
61 | iowrite8(0xff, intc_msk_base + 0xc); |
62 | |
63 | iounmap(addr: intc_prio_base); |
64 | iounmap(addr: intc_msk_base); |
65 | iounmap(addr: pfc_inta_ctrl); |
66 | } |
67 | |
68 | static void __init r8a7740_generic_init(void) |
69 | { |
70 | r8a7740_meram_workaround(); |
71 | } |
72 | |
73 | static const char *const r8a7740_boards_compat_dt[] __initconst = { |
74 | "renesas,r8a7740" , |
75 | NULL |
76 | }; |
77 | |
78 | DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)" ) |
79 | .l2c_aux_val = 0, |
80 | .l2c_aux_mask = ~0, |
81 | .init_early = shmobile_init_delay, |
82 | .init_irq = r8a7740_init_irq_of, |
83 | .init_machine = r8a7740_generic_init, |
84 | .init_late = shmobile_init_late, |
85 | .dt_compat = r8a7740_boards_compat_dt, |
86 | MACHINE_END |
87 | |