1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/clk-provider.h>
19#include <linux/clocksource.h>
20#include <linux/device.h>
21#include <linux/dma-contiguous.h>
22#include <linux/io.h>
23#include <linux/kernel.h>
24#include <linux/memblock.h>
25#include <linux/of.h>
26#include <linux/of_fdt.h>
27#include <linux/of_platform.h>
28#include <asm/mach/arch.h>
29#include "common.h"
30#include "rcar-gen2.h"
31
32static unsigned int __init get_extal_freq(void)
33{
34 struct device_node *cpg, *extal;
35 u32 freq = 20000000;
36
37 cpg = of_find_compatible_node(NULL, NULL,
38 "renesas,rcar-gen2-cpg-clocks");
39 if (!cpg)
40 return freq;
41
42 extal = of_parse_phandle(cpg, "clocks", 0);
43 of_node_put(cpg);
44 if (!extal)
45 return freq;
46
47 of_property_read_u32(extal, "clock-frequency", &freq);
48 of_node_put(extal);
49 return freq;
50}
51
52#define CNTCR 0
53#define CNTFID0 0x20
54
55void __init rcar_gen2_timer_init(void)
56{
57#ifdef CONFIG_ARM_ARCH_TIMER
58 void __iomem *base;
59 u32 freq;
60
61 if (of_machine_is_compatible("renesas,r8a7792") ||
62 of_machine_is_compatible("renesas,r8a7794")) {
63 freq = 260000000 / 8;
64
65
66
67
68
69 asm volatile(
70 " cps 0x16\n"
71 " mrc p15, 0, r1, c1, c1, 0\n"
72 " orr r0, r1, #1\n"
73 " mcr p15, 0, r0, c1, c1, 0\n"
74 " isb\n"
75 " mov r0, #0\n"
76 " mcrr p15, 4, r0, r0, c14\n"
77 " isb\n"
78 " mcr p15, 0, r1, c1, c1, 0\n"
79 " isb\n"
80 " cps 0x13\n"
81 : : : "r0", "r1");
82 } else {
83
84
85
86
87
88
89 freq = get_extal_freq() / 2;
90 }
91
92
93 base = ioremap(0xe6080000, PAGE_SIZE);
94
95
96
97
98
99
100
101
102 if ((ioread32(base + CNTCR) & 1) == 0 ||
103 ioread32(base + CNTFID0) != freq) {
104
105 iowrite32(freq, base + CNTFID0);
106 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
107
108
109 iowrite32(1, base + CNTCR);
110 }
111
112 iounmap(base);
113#endif
114
115 of_clk_init(NULL);
116 clocksource_probe();
117}
118
119struct memory_reserve_config {
120 u64 reserved;
121 u64 base, size;
122};
123
124static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname,
125 int depth, void *data)
126{
127 const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
128 const __be32 *reg, *endp;
129 int l;
130 struct memory_reserve_config *mrc = data;
131 u64 lpae_start = 1ULL << 32;
132
133
134 if (type == NULL || strcmp(type, "memory"))
135 return 0;
136
137 reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
138 if (reg == NULL)
139 reg = of_get_flat_dt_prop(node, "reg", &l);
140 if (reg == NULL)
141 return 0;
142
143 endp = reg + (l / sizeof(__be32));
144 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
145 u64 base, size;
146
147 base = dt_mem_next_cell(dt_root_addr_cells, ®);
148 size = dt_mem_next_cell(dt_root_size_cells, ®);
149
150 if (base >= lpae_start)
151 continue;
152
153 if ((base + size) >= lpae_start)
154 size = lpae_start - base;
155
156 if (size < mrc->reserved)
157 continue;
158
159 if (base < mrc->base)
160 continue;
161
162
163 mrc->base = base + size - mrc->reserved;
164 mrc->size = mrc->reserved;
165 }
166
167 return 0;
168}
169
170void __init rcar_gen2_reserve(void)
171{
172 struct memory_reserve_config mrc;
173
174
175 memset(&mrc, 0, sizeof(mrc));
176 mrc.reserved = SZ_256M;
177
178 of_scan_flat_dt(rcar_gen2_scan_mem, &mrc);
179#ifdef CONFIG_DMA_CMA
180 if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) {
181 static struct cma *rcar_gen2_dma_contiguous;
182
183 dma_contiguous_reserve_area(mrc.size, mrc.base, 0,
184 &rcar_gen2_dma_contiguous, true);
185 }
186#endif
187}
188
189static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
190
191
192
193
194 "renesas,r8a7792",
195 "renesas,r8a7793",
196 "renesas,r8a7794",
197 NULL,
198};
199
200DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
201 .init_early = shmobile_init_delay,
202 .init_late = shmobile_init_late,
203 .init_time = rcar_gen2_timer_init,
204 .reserve = rcar_gen2_reserve,
205 .dt_compat = rcar_gen2_boards_compat_dt,
206MACHINE_END
207
208static const char * const rz_g1_boards_compat_dt[] __initconst = {
209 "renesas,r8a7743",
210 "renesas,r8a7745",
211 NULL,
212};
213
214DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
215 .init_early = shmobile_init_delay,
216 .init_late = shmobile_init_late,
217 .init_time = rcar_gen2_timer_init,
218 .reserve = rcar_gen2_reserve,
219 .dt_compat = rz_g1_boards_compat_dt,
220MACHINE_END
221