790262afd4821d73ecf87c4293228fd1bc0073dc
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.3 / 0022-MIPS-lantiq-convert-xway-to-clkdev-api.patch
1 From de49a17fd2d9a73b9449f04061bb08eb5d73fe98 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Thu, 8 Mar 2012 11:18:22 +0100
4 Subject: [PATCH 22/70] MIPS: lantiq: convert xway to clkdev api
5
6 Unify xway/ase clock code and add clkdev hooks to sysctrl.c
7
8 Signed-off-by: John Crispin <blogic@openwrt.org>
9 ---
10 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 13 --
11 arch/mips/lantiq/xway/Makefile | 6 +-
12 arch/mips/lantiq/xway/clk-ase.c | 48 ----
13 arch/mips/lantiq/xway/clk-xway.c | 223 -------------------
14 arch/mips/lantiq/xway/clk.c | 227 ++++++++++++++++++++
15 arch/mips/lantiq/xway/sysctrl.c | 104 ++++++++-
16 6 files changed, 325 insertions(+), 296 deletions(-)
17 delete mode 100644 arch/mips/lantiq/xway/clk-ase.c
18 delete mode 100644 arch/mips/lantiq/xway/clk-xway.c
19 create mode 100644 arch/mips/lantiq/xway/clk.c
20
21 diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
22 index 45e480c..e9d2dd4 100644
23 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
24 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
25 @@ -81,15 +81,6 @@
26 #define LTQ_PMU_BASE_ADDR 0x1F102000
27 #define LTQ_PMU_SIZE 0x1000
28
29 -#define PMU_DMA 0x0020
30 -#define PMU_EPHY 0x0080
31 -#define PMU_USB 0x8041
32 -#define PMU_LED 0x0800
33 -#define PMU_GPT 0x1000
34 -#define PMU_PPE 0x2000
35 -#define PMU_FPI 0x4000
36 -#define PMU_SWITCH 0x10000000
37 -
38 /* ETOP - ethernet */
39 #define LTQ_ETOP_BASE_ADDR 0x1E180000
40 #define LTQ_ETOP_SIZE 0x40000
41 @@ -145,10 +136,6 @@
42 extern __iomem void *ltq_ebu_membase;
43 extern __iomem void *ltq_cgu_membase;
44
45 -extern void ltq_pmu_enable(unsigned int module);
46 -extern void ltq_pmu_disable(unsigned int module);
47 -extern void ltq_cgu_enable(unsigned int clk);
48 -
49 static inline int ltq_is_ase(void)
50 {
51 return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
52 diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
53 index 6678402..4dcb96f 100644
54 --- a/arch/mips/lantiq/xway/Makefile
55 +++ b/arch/mips/lantiq/xway/Makefile
56 @@ -1,7 +1,7 @@
57 -obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
58 +obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o
59
60 -obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o
61 -obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o
62 +obj-$(CONFIG_SOC_XWAY) += prom-xway.o
63 +obj-$(CONFIG_SOC_AMAZON_SE) += prom-ase.o
64
65 obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
66 obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
67 diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c
68 deleted file mode 100644
69 index 6522583..0000000
70 --- a/arch/mips/lantiq/xway/clk-ase.c
71 +++ /dev/null
72 @@ -1,48 +0,0 @@
73 -/*
74 - * This program is free software; you can redistribute it and/or modify it
75 - * under the terms of the GNU General Public License version 2 as published
76 - * by the Free Software Foundation.
77 - *
78 - * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
79 - */
80 -
81 -#include <linux/io.h>
82 -#include <linux/export.h>
83 -#include <linux/init.h>
84 -#include <linux/clk.h>
85 -
86 -#include <asm/time.h>
87 -#include <asm/irq.h>
88 -#include <asm/div64.h>
89 -
90 -#include <lantiq_soc.h>
91 -
92 -/* cgu registers */
93 -#define LTQ_CGU_SYS 0x0010
94 -
95 -unsigned int ltq_get_io_region_clock(void)
96 -{
97 - return CLOCK_133M;
98 -}
99 -EXPORT_SYMBOL(ltq_get_io_region_clock);
100 -
101 -unsigned int ltq_get_fpi_bus_clock(int fpi)
102 -{
103 - return CLOCK_133M;
104 -}
105 -EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
106 -
107 -unsigned int ltq_get_cpu_hz(void)
108 -{
109 - if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
110 - return CLOCK_266M;
111 - else
112 - return CLOCK_133M;
113 -}
114 -EXPORT_SYMBOL(ltq_get_cpu_hz);
115 -
116 -unsigned int ltq_get_fpi_hz(void)
117 -{
118 - return CLOCK_133M;
119 -}
120 -EXPORT_SYMBOL(ltq_get_fpi_hz);
121 diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c
122 deleted file mode 100644
123 index 696b1a3..0000000
124 --- a/arch/mips/lantiq/xway/clk-xway.c
125 +++ /dev/null
126 @@ -1,223 +0,0 @@
127 -/*
128 - * This program is free software; you can redistribute it and/or modify it
129 - * under the terms of the GNU General Public License version 2 as published
130 - * by the Free Software Foundation.
131 - *
132 - * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
133 - */
134 -
135 -#include <linux/io.h>
136 -#include <linux/export.h>
137 -#include <linux/init.h>
138 -#include <linux/clk.h>
139 -
140 -#include <asm/time.h>
141 -#include <asm/irq.h>
142 -#include <asm/div64.h>
143 -
144 -#include <lantiq_soc.h>
145 -
146 -static unsigned int ltq_ram_clocks[] = {
147 - CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
148 -#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
149 -
150 -#define BASIC_FREQUENCY_1 35328000
151 -#define BASIC_FREQUENCY_2 36000000
152 -#define BASIS_REQUENCY_USB 12000000
153 -
154 -#define GET_BITS(x, msb, lsb) \
155 - (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
156 -
157 -#define LTQ_CGU_PLL0_CFG 0x0004
158 -#define LTQ_CGU_PLL1_CFG 0x0008
159 -#define LTQ_CGU_PLL2_CFG 0x000C
160 -#define LTQ_CGU_SYS 0x0010
161 -#define LTQ_CGU_UPDATE 0x0014
162 -#define LTQ_CGU_IF_CLK 0x0018
163 -#define LTQ_CGU_OSC_CON 0x001C
164 -#define LTQ_CGU_SMD 0x0020
165 -#define LTQ_CGU_CT1SR 0x0028
166 -#define LTQ_CGU_CT2SR 0x002C
167 -#define LTQ_CGU_PCMCR 0x0030
168 -#define LTQ_CGU_PCI_CR 0x0034
169 -#define LTQ_CGU_PD_PC 0x0038
170 -#define LTQ_CGU_FMR 0x003C
171 -
172 -#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
173 - (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
174 -#define CGU_PLL0_BYPASS \
175 - (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
176 -#define CGU_PLL0_CFG_DSMSEL \
177 - (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
178 -#define CGU_PLL0_CFG_FRAC_EN \
179 - (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
180 -#define CGU_PLL1_SRC \
181 - (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
182 -#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
183 - (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
184 -#define CGU_SYS_FPI_SEL (1 << 6)
185 -#define CGU_SYS_DDR_SEL 0x3
186 -#define CGU_PLL0_SRC (1 << 29)
187 -
188 -#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
189 -#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
190 -#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
191 -#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
192 -#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
193 -
194 -static unsigned int ltq_get_pll0_fdiv(void);
195 -
196 -static inline unsigned int get_input_clock(int pll)
197 -{
198 - switch (pll) {
199 - case 0:
200 - if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
201 - return BASIS_REQUENCY_USB;
202 - else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
203 - return BASIC_FREQUENCY_1;
204 - else
205 - return BASIC_FREQUENCY_2;
206 - case 1:
207 - if (CGU_PLL1_SRC)
208 - return BASIS_REQUENCY_USB;
209 - else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
210 - return BASIC_FREQUENCY_1;
211 - else
212 - return BASIC_FREQUENCY_2;
213 - case 2:
214 - switch (CGU_PLL2_SRC) {
215 - case 0:
216 - return ltq_get_pll0_fdiv();
217 - case 1:
218 - return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
219 - BASIC_FREQUENCY_1 :
220 - BASIC_FREQUENCY_2;
221 - case 2:
222 - return BASIS_REQUENCY_USB;
223 - }
224 - default:
225 - return 0;
226 - }
227 -}
228 -
229 -static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
230 -{
231 - u64 res, clock = get_input_clock(pll);
232 -
233 - res = num * clock;
234 - do_div(res, den);
235 - return res;
236 -}
237 -
238 -static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
239 - unsigned int K)
240 -{
241 - unsigned int num = ((N + 1) << 10) + K;
242 - unsigned int den = (M + 1) << 10;
243 -
244 - return cal_dsm(pll, num, den);
245 -}
246 -
247 -static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
248 - unsigned int K)
249 -{
250 - unsigned int num = ((N + 1) << 11) + K + 512;
251 - unsigned int den = (M + 1) << 11;
252 -
253 - return cal_dsm(pll, num, den);
254 -}
255 -
256 -static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
257 - unsigned int K)
258 -{
259 - unsigned int num = K >= 512 ?
260 - ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
261 - unsigned int den = (M + 1) << 12;
262 -
263 - return cal_dsm(pll, num, den);
264 -}
265 -
266 -static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
267 - unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
268 -{
269 - if (!dsmsel)
270 - return mash_dsm(pll, M, N, K);
271 - else if (!phase_div_en)
272 - return mash_dsm(pll, M, N, K);
273 - else
274 - return ssff_dsm_2(pll, M, N, K);
275 -}
276 -
277 -static inline unsigned int ltq_get_pll0_fosc(void)
278 -{
279 - if (CGU_PLL0_BYPASS)
280 - return get_input_clock(0);
281 - else
282 - return !CGU_PLL0_CFG_FRAC_EN
283 - ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
284 - CGU_PLL0_CFG_DSMSEL,
285 - CGU_PLL0_PHASE_DIVIDER_ENABLE)
286 - : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
287 - CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
288 - CGU_PLL0_PHASE_DIVIDER_ENABLE);
289 -}
290 -
291 -static unsigned int ltq_get_pll0_fdiv(void)
292 -{
293 - unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
294 -
295 - return (ltq_get_pll0_fosc() + (div >> 1)) / div;
296 -}
297 -
298 -unsigned int ltq_get_io_region_clock(void)
299 -{
300 - unsigned int ret = ltq_get_pll0_fosc();
301 -
302 - switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
303 - default:
304 - case 0:
305 - return (ret + 1) / 2;
306 - case 1:
307 - return (ret * 2 + 2) / 5;
308 - case 2:
309 - return (ret + 1) / 3;
310 - case 3:
311 - return (ret + 2) / 4;
312 - }
313 -}
314 -EXPORT_SYMBOL(ltq_get_io_region_clock);
315 -
316 -unsigned int ltq_get_fpi_bus_clock(int fpi)
317 -{
318 - unsigned int ret = ltq_get_io_region_clock();
319 -
320 - if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
321 - ret >>= 1;
322 - return ret;
323 -}
324 -EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
325 -
326 -unsigned int ltq_get_cpu_hz(void)
327 -{
328 - switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
329 - case 0:
330 - return CLOCK_333M;
331 - case 4:
332 - return DDR_HZ;
333 - case 8:
334 - return DDR_HZ << 1;
335 - default:
336 - return DDR_HZ >> 1;
337 - }
338 -}
339 -EXPORT_SYMBOL(ltq_get_cpu_hz);
340 -
341 -unsigned int ltq_get_fpi_hz(void)
342 -{
343 - unsigned int ddr_clock = DDR_HZ;
344 -
345 - if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
346 - return ddr_clock >> 1;
347 - return ddr_clock;
348 -}
349 -EXPORT_SYMBOL(ltq_get_fpi_hz);
350 diff --git a/arch/mips/lantiq/xway/clk.c b/arch/mips/lantiq/xway/clk.c
351 new file mode 100644
352 index 0000000..f3b50fc
353 --- /dev/null
354 +++ b/arch/mips/lantiq/xway/clk.c
355 @@ -0,0 +1,227 @@
356 +/*
357 + * This program is free software; you can redistribute it and/or modify it
358 + * under the terms of the GNU General Public License version 2 as published
359 + * by the Free Software Foundation.
360 + *
361 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
362 + */
363 +
364 +#include <linux/io.h>
365 +#include <linux/export.h>
366 +#include <linux/init.h>
367 +#include <linux/clk.h>
368 +
369 +#include <asm/time.h>
370 +#include <asm/irq.h>
371 +#include <asm/div64.h>
372 +
373 +#include <lantiq_soc.h>
374 +
375 +#include "../clk.h"
376 +
377 +static unsigned int ltq_ram_clocks[] = {
378 + CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
379 +#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
380 +
381 +#define BASIC_FREQUENCY_1 35328000
382 +#define BASIC_FREQUENCY_2 36000000
383 +#define BASIS_REQUENCY_USB 12000000
384 +
385 +#define GET_BITS(x, msb, lsb) \
386 + (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
387 +
388 +/* legacy xway clock */
389 +#define LTQ_CGU_PLL0_CFG 0x0004
390 +#define LTQ_CGU_PLL1_CFG 0x0008
391 +#define LTQ_CGU_PLL2_CFG 0x000C
392 +#define LTQ_CGU_SYS 0x0010
393 +#define LTQ_CGU_UPDATE 0x0014
394 +#define LTQ_CGU_IF_CLK 0x0018
395 +#define LTQ_CGU_OSC_CON 0x001C
396 +#define LTQ_CGU_SMD 0x0020
397 +#define LTQ_CGU_CT1SR 0x0028
398 +#define LTQ_CGU_CT2SR 0x002C
399 +#define LTQ_CGU_PCMCR 0x0030
400 +#define LTQ_CGU_PCI_CR 0x0034
401 +#define LTQ_CGU_PD_PC 0x0038
402 +#define LTQ_CGU_FMR 0x003C
403 +
404 +#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
405 + (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
406 +#define CGU_PLL0_BYPASS \
407 + (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
408 +#define CGU_PLL0_CFG_DSMSEL \
409 + (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
410 +#define CGU_PLL0_CFG_FRAC_EN \
411 + (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
412 +#define CGU_PLL1_SRC \
413 + (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
414 +#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
415 + (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
416 +#define CGU_SYS_FPI_SEL (1 << 6)
417 +#define CGU_SYS_DDR_SEL 0x3
418 +#define CGU_PLL0_SRC (1 << 29)
419 +
420 +#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
421 +#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
422 +#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
423 +#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
424 +#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
425 +
426 +/* vr9 clock */
427 +#define LTQ_CGU_SYS_VR9 0x0c
428 +#define LTQ_CGU_IF_CLK_VR9 0x24
429 +
430 +
431 +static unsigned int ltq_get_pll0_fdiv(void);
432 +
433 +static inline unsigned int get_input_clock(int pll)
434 +{
435 + switch (pll) {
436 + case 0:
437 + if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
438 + return BASIS_REQUENCY_USB;
439 + else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
440 + return BASIC_FREQUENCY_1;
441 + else
442 + return BASIC_FREQUENCY_2;
443 + case 1:
444 + if (CGU_PLL1_SRC)
445 + return BASIS_REQUENCY_USB;
446 + else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
447 + return BASIC_FREQUENCY_1;
448 + else
449 + return BASIC_FREQUENCY_2;
450 + case 2:
451 + switch (CGU_PLL2_SRC) {
452 + case 0:
453 + return ltq_get_pll0_fdiv();
454 + case 1:
455 + return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
456 + BASIC_FREQUENCY_1 :
457 + BASIC_FREQUENCY_2;
458 + case 2:
459 + return BASIS_REQUENCY_USB;
460 + }
461 + default:
462 + return 0;
463 + }
464 +}
465 +
466 +static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
467 +{
468 + u64 res, clock = get_input_clock(pll);
469 +
470 + res = num * clock;
471 + do_div(res, den);
472 + return res;
473 +}
474 +
475 +static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
476 + unsigned int K)
477 +{
478 + unsigned int num = ((N + 1) << 10) + K;
479 + unsigned int den = (M + 1) << 10;
480 +
481 + return cal_dsm(pll, num, den);
482 +}
483 +
484 +static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
485 + unsigned int K)
486 +{
487 + unsigned int num = ((N + 1) << 11) + K + 512;
488 + unsigned int den = (M + 1) << 11;
489 +
490 + return cal_dsm(pll, num, den);
491 +}
492 +
493 +static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
494 + unsigned int K)
495 +{
496 + unsigned int num = K >= 512 ?
497 + ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
498 + unsigned int den = (M + 1) << 12;
499 +
500 + return cal_dsm(pll, num, den);
501 +}
502 +
503 +static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
504 + unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
505 +{
506 + if (!dsmsel)
507 + return mash_dsm(pll, M, N, K);
508 + else if (!phase_div_en)
509 + return mash_dsm(pll, M, N, K);
510 + else
511 + return ssff_dsm_2(pll, M, N, K);
512 +}
513 +
514 +static inline unsigned int ltq_get_pll0_fosc(void)
515 +{
516 + if (CGU_PLL0_BYPASS)
517 + return get_input_clock(0);
518 + else
519 + return !CGU_PLL0_CFG_FRAC_EN
520 + ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
521 + CGU_PLL0_CFG_DSMSEL,
522 + CGU_PLL0_PHASE_DIVIDER_ENABLE)
523 + : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
524 + CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
525 + CGU_PLL0_PHASE_DIVIDER_ENABLE);
526 +}
527 +
528 +static unsigned int ltq_get_pll0_fdiv(void)
529 +{
530 + unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
531 +
532 + return (ltq_get_pll0_fosc() + (div >> 1)) / div;
533 +}
534 +
535 +unsigned long ltq_danube_io_region_clock(void)
536 +{
537 + unsigned int ret = ltq_get_pll0_fosc();
538 +
539 + switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
540 + default:
541 + case 0:
542 + return (ret + 1) / 2;
543 + case 1:
544 + return (ret * 2 + 2) / 5;
545 + case 2:
546 + return (ret + 1) / 3;
547 + case 3:
548 + return (ret + 2) / 4;
549 + }
550 +}
551 +
552 +unsigned long ltq_danube_fpi_bus_clock(int fpi)
553 +{
554 + unsigned long ret = ltq_danube_io_region_clock();
555 +
556 + if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
557 + ret >>= 1;
558 + return ret;
559 +}
560 +
561 +unsigned long ltq_danube_cpu_hz(void)
562 +{
563 + switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
564 + case 0:
565 + return CLOCK_333M;
566 + case 4:
567 + return DDR_HZ;
568 + case 8:
569 + return DDR_HZ << 1;
570 + default:
571 + return DDR_HZ >> 1;
572 + }
573 +}
574 +
575 +unsigned long ltq_danube_fpi_hz(void)
576 +{
577 + unsigned long ddr_clock = DDR_HZ;
578 +
579 + if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
580 + return ddr_clock >> 1;
581 + return ddr_clock;
582 +}
583 diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
584 index 8fd13a1..c5782b5 100644
585 --- a/arch/mips/lantiq/xway/sysctrl.c
586 +++ b/arch/mips/lantiq/xway/sysctrl.c
587 @@ -8,17 +8,48 @@
588
589 #include <linux/ioport.h>
590 #include <linux/export.h>
591 +#include <linux/clkdev.h>
592
593 #include <lantiq_soc.h>
594
595 +#include "../clk.h"
596 #include "../devices.h"
597
598 /* clock control register */
599 #define LTQ_CGU_IFCCR 0x0018
600 +/* system clock register */
601 +#define LTQ_CGU_SYS 0x0010
602
603 /* the enable / disable registers */
604 #define LTQ_PMU_PWDCR 0x1C
605 #define LTQ_PMU_PWDSR 0x20
606 +#define LTQ_PMU_PWDCR1 0x24
607 +#define LTQ_PMU_PWDSR1 0x28
608 +
609 +#define PWDCR(x) ((x) ? (LTQ_PMU_PWDCR1) : (LTQ_PMU_PWDCR))
610 +#define PWDSR(x) ((x) ? (LTQ_PMU_PWDSR1) : (LTQ_PMU_PWDSR))
611 +
612 +/* CGU - clock generation unit */
613 +#define CGU_EPHY 0x10
614 +
615 +/* PMU - power management unit */
616 +#define PMU_DMA 0x0020
617 +#define PMU_SPI 0x0100
618 +#define PMU_EPHY 0x0080
619 +#define PMU_USB 0x8041
620 +#define PMU_STP 0x0800
621 +#define PMU_GPT 0x1000
622 +#define PMU_PPE 0x2000
623 +#define PMU_FPI 0x4000
624 +#define PMU_SWITCH 0x10000000
625 +#define PMU_AHBS 0x2000
626 +#define PMU_AHBM 0x8000
627 +#define PMU_PCIE_CLK 0x80000000
628 +
629 +#define PMU1_PCIE_PHY 0x0001
630 +#define PMU1_PCIE_CTL 0x0002
631 +#define PMU1_PCIE_MSI 0x0020
632 +#define PMU1_PCIE_PDI 0x0010
633
634 #define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
635 #define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
636 @@ -36,28 +67,64 @@ void __iomem *ltq_cgu_membase;
637 void __iomem *ltq_ebu_membase;
638 static void __iomem *ltq_pmu_membase;
639
640 -void ltq_cgu_enable(unsigned int clk)
641 +static int ltq_cgu_enable(struct clk *clk)
642 {
643 - ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk, LTQ_CGU_IFCCR);
644 + ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk->bits, LTQ_CGU_IFCCR);
645 + return 0;
646 }
647
648 -void ltq_pmu_enable(unsigned int module)
649 +static void ltq_cgu_disable(struct clk *clk)
650 +{
651 + ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~clk->bits, LTQ_CGU_IFCCR);
652 +}
653 +
654 +static int ltq_pmu_enable(struct clk *clk)
655 {
656 int err = 1000000;
657
658 - ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
659 - do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
660 + ltq_pmu_w32(ltq_pmu_r32(PWDCR(clk->module)) & ~clk->bits,
661 + PWDCR(clk->module));
662 + do {} while (--err && (ltq_pmu_r32(PWDSR(clk->module)) & clk->bits));
663
664 if (!err)
665 panic("activating PMU module failed!\n");
666 +
667 + return 0;
668 }
669 -EXPORT_SYMBOL(ltq_pmu_enable);
670
671 -void ltq_pmu_disable(unsigned int module)
672 +static void ltq_pmu_disable(struct clk *clk)
673 {
674 - ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
675 + ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | clk->bits, LTQ_PMU_PWDCR);
676 +}
677 +
678 +static inline void clkdev_add_pmu(const char *dev, const char *con,
679 + unsigned int module, unsigned int bits)
680 +{
681 + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
682 +
683 + clk->cl.dev_id = dev;
684 + clk->cl.con_id = con;
685 + clk->cl.clk = clk;
686 + clk->enable = ltq_pmu_enable;
687 + clk->disable = ltq_pmu_disable;
688 + clk->module = module;
689 + clk->bits = bits;
690 + clkdev_add(&clk->cl);
691 +}
692 +
693 +static inline void clkdev_add_cgu(const char *dev, const char *con,
694 + unsigned int bits)
695 +{
696 + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
697 +
698 + clk->cl.dev_id = dev;
699 + clk->cl.con_id = con;
700 + clk->cl.clk = clk;
701 + clk->enable = ltq_cgu_enable;
702 + clk->disable = ltq_cgu_disable;
703 + clk->bits = bits;
704 + clkdev_add(&clk->cl);
705 }
706 -EXPORT_SYMBOL(ltq_pmu_disable);
707
708 void __init ltq_soc_init(void)
709 {
710 @@ -75,4 +142,23 @@ void __init ltq_soc_init(void)
711
712 /* make sure to unprotect the memory region where flash is located */
713 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
714 +
715 + /* add our clocks */
716 + clkdev_add_pmu("ltq_dma", NULL, 0, PMU_DMA);
717 + clkdev_add_pmu("ltq_stp", NULL, 0, PMU_STP);
718 + clkdev_add_pmu("ltq_spi", NULL, 0, PMU_SPI);
719 + clkdev_add_pmu("ltq_etop", NULL, 0, PMU_PPE);
720 + if (ltq_is_ase()) {
721 + if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
722 + clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
723 + else
724 + clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
725 + clkdev_add_cgu("ltq_etop", "ephycgu", CGU_EPHY),
726 + clkdev_add_pmu("ltq_etop", "ephy", 0, PMU_EPHY);
727 + } else {
728 + clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
729 + ltq_danube_io_region_clock());
730 + if (ltq_is_ar9())
731 + clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);
732 + }
733 }
734 --
735 1.7.9.1
736