Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / mips / lantiq / xway / clk.c
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 }