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