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