diff options
Diffstat (limited to 'arch/mips/lantiq/xway/clk.c')
-rw-r--r-- | arch/mips/lantiq/xway/clk.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/arch/mips/lantiq/xway/clk.c b/arch/mips/lantiq/xway/clk.c new file mode 100644 index 000000000..47ad21430 --- /dev/null +++ b/arch/mips/lantiq/xway/clk.c | |||
@@ -0,0 +1,351 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * | ||
4 | * Copyright (C) 2010 John Crispin <john@phrozen.org> | ||
5 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | ||
6 | */ | ||
7 | |||
8 | #include <linux/io.h> | ||
9 | #include <linux/export.h> | ||
10 | #include <linux/clk.h> | ||
11 | |||
12 | #include <asm/time.h> | ||
13 | #include <asm/irq.h> | ||
14 | #include <asm/div64.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | |||
18 | #include "../clk.h" | ||
19 | |||
20 | static unsigned int ram_clocks[] = { | ||
21 | CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; | ||
22 | #define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3] | ||
23 | |||
24 | /* legacy xway clock */ | ||
25 | #define CGU_SYS 0x10 | ||
26 | |||
27 | /* vr9, ar10/grx390 clock */ | ||
28 | #define CGU_SYS_XRX 0x0c | ||
29 | #define CGU_IF_CLK_AR10 0x24 | ||
30 | |||
31 | unsigned long ltq_danube_fpi_hz(void) | ||
32 | { | ||
33 | unsigned long ddr_clock = DDR_HZ; | ||
34 | |||
35 | if (ltq_cgu_r32(CGU_SYS) & 0x40) | ||
36 | return ddr_clock >> 1; | ||
37 | return ddr_clock; | ||
38 | } | ||
39 | |||
40 | unsigned long ltq_danube_cpu_hz(void) | ||
41 | { | ||
42 | switch (ltq_cgu_r32(CGU_SYS) & 0xc) { | ||
43 | case 0: | ||
44 | return CLOCK_333M; | ||
45 | case 4: | ||
46 | return DDR_HZ; | ||
47 | case 8: | ||
48 | return DDR_HZ << 1; | ||
49 | default: | ||
50 | return DDR_HZ >> 1; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | unsigned long ltq_danube_pp32_hz(void) | ||
55 | { | ||
56 | unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3; | ||
57 | unsigned long clk; | ||
58 | |||
59 | switch (clksys) { | ||
60 | case 1: | ||
61 | clk = CLOCK_240M; | ||
62 | break; | ||
63 | case 2: | ||
64 | clk = CLOCK_222M; | ||
65 | break; | ||
66 | case 3: | ||
67 | clk = CLOCK_133M; | ||
68 | break; | ||
69 | default: | ||
70 | clk = CLOCK_266M; | ||
71 | break; | ||
72 | } | ||
73 | |||
74 | return clk; | ||
75 | } | ||
76 | |||
77 | unsigned long ltq_ar9_sys_hz(void) | ||
78 | { | ||
79 | if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) | ||
80 | return CLOCK_393M; | ||
81 | return CLOCK_333M; | ||
82 | } | ||
83 | |||
84 | unsigned long ltq_ar9_fpi_hz(void) | ||
85 | { | ||
86 | unsigned long sys = ltq_ar9_sys_hz(); | ||
87 | |||
88 | if (ltq_cgu_r32(CGU_SYS) & BIT(0)) | ||
89 | return sys / 3; | ||
90 | else | ||
91 | return sys / 2; | ||
92 | } | ||
93 | |||
94 | unsigned long ltq_ar9_cpu_hz(void) | ||
95 | { | ||
96 | if (ltq_cgu_r32(CGU_SYS) & BIT(2)) | ||
97 | return ltq_ar9_fpi_hz(); | ||
98 | else | ||
99 | return ltq_ar9_sys_hz(); | ||
100 | } | ||
101 | |||
102 | unsigned long ltq_vr9_cpu_hz(void) | ||
103 | { | ||
104 | unsigned int cpu_sel; | ||
105 | unsigned long clk; | ||
106 | |||
107 | cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf; | ||
108 | |||
109 | switch (cpu_sel) { | ||
110 | case 0: | ||
111 | clk = CLOCK_600M; | ||
112 | break; | ||
113 | case 1: | ||
114 | clk = CLOCK_500M; | ||
115 | break; | ||
116 | case 2: | ||
117 | clk = CLOCK_393M; | ||
118 | break; | ||
119 | case 3: | ||
120 | clk = CLOCK_333M; | ||
121 | break; | ||
122 | case 5: | ||
123 | case 6: | ||
124 | clk = CLOCK_196_608M; | ||
125 | break; | ||
126 | case 7: | ||
127 | clk = CLOCK_167M; | ||
128 | break; | ||
129 | case 4: | ||
130 | case 8: | ||
131 | case 9: | ||
132 | clk = CLOCK_125M; | ||
133 | break; | ||
134 | default: | ||
135 | clk = 0; | ||
136 | break; | ||
137 | } | ||
138 | |||
139 | return clk; | ||
140 | } | ||
141 | |||
142 | unsigned long ltq_vr9_fpi_hz(void) | ||
143 | { | ||
144 | unsigned int ocp_sel, cpu_clk; | ||
145 | unsigned long clk; | ||
146 | |||
147 | cpu_clk = ltq_vr9_cpu_hz(); | ||
148 | ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3; | ||
149 | |||
150 | switch (ocp_sel) { | ||
151 | case 0: | ||
152 | /* OCP ratio 1 */ | ||
153 | clk = cpu_clk; | ||
154 | break; | ||
155 | case 2: | ||
156 | /* OCP ratio 2 */ | ||
157 | clk = cpu_clk / 2; | ||
158 | break; | ||
159 | case 3: | ||
160 | /* OCP ratio 2.5 */ | ||
161 | clk = (cpu_clk * 2) / 5; | ||
162 | break; | ||
163 | case 4: | ||
164 | /* OCP ratio 3 */ | ||
165 | clk = cpu_clk / 3; | ||
166 | break; | ||
167 | default: | ||
168 | clk = 0; | ||
169 | break; | ||
170 | } | ||
171 | |||
172 | return clk; | ||
173 | } | ||
174 | |||
175 | unsigned long ltq_vr9_pp32_hz(void) | ||
176 | { | ||
177 | unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; | ||
178 | unsigned long clk; | ||
179 | |||
180 | switch (clksys) { | ||
181 | case 0: | ||
182 | clk = CLOCK_500M; | ||
183 | break; | ||
184 | case 1: | ||
185 | clk = CLOCK_432M; | ||
186 | break; | ||
187 | case 2: | ||
188 | clk = CLOCK_288M; | ||
189 | break; | ||
190 | default: | ||
191 | clk = CLOCK_500M; | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | return clk; | ||
196 | } | ||
197 | |||
198 | unsigned long ltq_ar10_cpu_hz(void) | ||
199 | { | ||
200 | unsigned int clksys; | ||
201 | int cpu_fs = (ltq_cgu_r32(CGU_SYS_XRX) >> 8) & 0x1; | ||
202 | int freq_div = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7; | ||
203 | |||
204 | switch (cpu_fs) { | ||
205 | case 0: | ||
206 | clksys = CLOCK_500M; | ||
207 | break; | ||
208 | case 1: | ||
209 | clksys = CLOCK_600M; | ||
210 | break; | ||
211 | default: | ||
212 | clksys = CLOCK_500M; | ||
213 | break; | ||
214 | } | ||
215 | |||
216 | switch (freq_div) { | ||
217 | case 0: | ||
218 | return clksys; | ||
219 | case 1: | ||
220 | return clksys >> 1; | ||
221 | case 2: | ||
222 | return clksys >> 2; | ||
223 | default: | ||
224 | return clksys; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | unsigned long ltq_ar10_fpi_hz(void) | ||
229 | { | ||
230 | int freq_fpi = (ltq_cgu_r32(CGU_IF_CLK_AR10) >> 25) & 0xf; | ||
231 | |||
232 | switch (freq_fpi) { | ||
233 | case 1: | ||
234 | return CLOCK_300M; | ||
235 | case 5: | ||
236 | return CLOCK_250M; | ||
237 | case 2: | ||
238 | return CLOCK_150M; | ||
239 | case 6: | ||
240 | return CLOCK_125M; | ||
241 | |||
242 | default: | ||
243 | return CLOCK_125M; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | unsigned long ltq_ar10_pp32_hz(void) | ||
248 | { | ||
249 | unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; | ||
250 | unsigned long clk; | ||
251 | |||
252 | switch (clksys) { | ||
253 | case 1: | ||
254 | clk = CLOCK_250M; | ||
255 | break; | ||
256 | case 4: | ||
257 | clk = CLOCK_400M; | ||
258 | break; | ||
259 | default: | ||
260 | clk = CLOCK_250M; | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | return clk; | ||
265 | } | ||
266 | |||
267 | unsigned long ltq_grx390_cpu_hz(void) | ||
268 | { | ||
269 | unsigned int clksys; | ||
270 | int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); | ||
271 | int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7); | ||
272 | |||
273 | switch (cpu_fs) { | ||
274 | case 0: | ||
275 | clksys = CLOCK_600M; | ||
276 | break; | ||
277 | case 1: | ||
278 | clksys = CLOCK_666M; | ||
279 | break; | ||
280 | case 2: | ||
281 | clksys = CLOCK_720M; | ||
282 | break; | ||
283 | default: | ||
284 | clksys = CLOCK_600M; | ||
285 | break; | ||
286 | } | ||
287 | |||
288 | switch (freq_div) { | ||
289 | case 0: | ||
290 | return clksys; | ||
291 | case 1: | ||
292 | return clksys >> 1; | ||
293 | case 2: | ||
294 | return clksys >> 2; | ||
295 | default: | ||
296 | return clksys; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | unsigned long ltq_grx390_fpi_hz(void) | ||
301 | { | ||
302 | /* fpi clock is derived from ddr_clk */ | ||
303 | unsigned int clksys; | ||
304 | int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); | ||
305 | int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX)) & 0x7); | ||
306 | switch (cpu_fs) { | ||
307 | case 0: | ||
308 | clksys = CLOCK_600M; | ||
309 | break; | ||
310 | case 1: | ||
311 | clksys = CLOCK_666M; | ||
312 | break; | ||
313 | case 2: | ||
314 | clksys = CLOCK_720M; | ||
315 | break; | ||
316 | default: | ||
317 | clksys = CLOCK_600M; | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | switch (freq_div) { | ||
322 | case 1: | ||
323 | return clksys >> 1; | ||
324 | case 2: | ||
325 | return clksys >> 2; | ||
326 | default: | ||
327 | return clksys >> 1; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | unsigned long ltq_grx390_pp32_hz(void) | ||
332 | { | ||
333 | unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; | ||
334 | unsigned long clk; | ||
335 | |||
336 | switch (clksys) { | ||
337 | case 1: | ||
338 | clk = CLOCK_250M; | ||
339 | break; | ||
340 | case 2: | ||
341 | clk = CLOCK_432M; | ||
342 | break; | ||
343 | case 4: | ||
344 | clk = CLOCK_400M; | ||
345 | break; | ||
346 | default: | ||
347 | clk = CLOCK_250M; | ||
348 | break; | ||
349 | } | ||
350 | return clk; | ||
351 | } | ||