xref: /linux/arch/mips/lantiq/xway/clk.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
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  *
6  *  Copyright (C) 2010 John Crispin <john@phrozen.org>
7  *  Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
8  */
9 
10 #include <linux/io.h>
11 #include <linux/export.h>
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 
29 /* vr9, ar10/grx390 clock */
30 #define CGU_SYS_XRX		0x0c
31 #define CGU_IF_CLK_AR10		0x24
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 
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 
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))
91 		return sys / 3;
92 	else
93 		return sys / 2;
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 
109 	cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf;
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();
150 	ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3;
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 }
176 
177 unsigned long ltq_vr9_pp32_hz(void)
178 {
179 	unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7;
180 	unsigned long clk;
181 
182 	switch (clksys) {
183 	case 0:
184 		clk = CLOCK_500M;
185 		break;
186 	case 1:
187 		clk = CLOCK_432M;
188 		break;
189 	case 2:
190 		clk = CLOCK_288M;
191 		break;
192 	default:
193 		clk = CLOCK_500M;
194 		break;
195 	}
196 
197 	return clk;
198 }
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 }
354