1 From 418e330dc60aaabdb5cf4509ec08cce07d63f32e 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 26/70] MIPS: lantiq: convert xway to clkdev api
6 Unify xway/ase clock code and add clkdev hooks to sysctrl.c
8 Signed-off-by: John Crispin <blogic@openwrt.org>
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
21 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
22 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
24 #define LTQ_PMU_BASE_ADDR 0x1F102000
25 #define LTQ_PMU_SIZE 0x1000
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
37 #define LTQ_ETOP_BASE_ADDR 0x1E180000
38 #define LTQ_ETOP_SIZE 0x40000
40 extern __iomem void *ltq_ebu_membase;
41 extern __iomem void *ltq_cgu_membase;
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);
47 static inline int ltq_is_ase(void)
49 return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
50 --- a/arch/mips/lantiq/xway/Makefile
51 +++ b/arch/mips/lantiq/xway/Makefile
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
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
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
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.
71 - * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
74 -#include <linux/io.h>
75 -#include <linux/export.h>
76 -#include <linux/init.h>
77 -#include <linux/clk.h>
79 -#include <asm/time.h>
81 -#include <asm/div64.h>
83 -#include <lantiq_soc.h>
86 -#define LTQ_CGU_SYS 0x0010
88 -unsigned int ltq_get_io_region_clock(void)
92 -EXPORT_SYMBOL(ltq_get_io_region_clock);
94 -unsigned int ltq_get_fpi_bus_clock(int fpi)
98 -EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
100 -unsigned int ltq_get_cpu_hz(void)
102 - if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
107 -EXPORT_SYMBOL(ltq_get_cpu_hz);
109 -unsigned int ltq_get_fpi_hz(void)
113 -EXPORT_SYMBOL(ltq_get_fpi_hz);
114 --- a/arch/mips/lantiq/xway/clk-xway.c
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.
122 - * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
125 -#include <linux/io.h>
126 -#include <linux/export.h>
127 -#include <linux/init.h>
128 -#include <linux/clk.h>
130 -#include <asm/time.h>
131 -#include <asm/irq.h>
132 -#include <asm/div64.h>
134 -#include <lantiq_soc.h>
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]
140 -#define BASIC_FREQUENCY_1 35328000
141 -#define BASIC_FREQUENCY_2 36000000
142 -#define BASIS_REQUENCY_USB 12000000
144 -#define GET_BITS(x, msb, lsb) \
145 - (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
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
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)
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)
184 -static unsigned int ltq_get_pll0_fdiv(void);
186 -static inline unsigned int get_input_clock(int pll)
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;
195 - return BASIC_FREQUENCY_2;
198 - return BASIS_REQUENCY_USB;
199 - else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
200 - return BASIC_FREQUENCY_1;
202 - return BASIC_FREQUENCY_2;
204 - switch (CGU_PLL2_SRC) {
206 - return ltq_get_pll0_fdiv();
208 - return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
209 - BASIC_FREQUENCY_1 :
212 - return BASIS_REQUENCY_USB;
219 -static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
221 - u64 res, clock = get_input_clock(pll);
228 -static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
231 - unsigned int num = ((N + 1) << 10) + K;
232 - unsigned int den = (M + 1) << 10;
234 - return cal_dsm(pll, num, den);
237 -static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
240 - unsigned int num = ((N + 1) << 11) + K + 512;
241 - unsigned int den = (M + 1) << 11;
243 - return cal_dsm(pll, num, den);
246 -static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
249 - unsigned int num = K >= 512 ?
250 - ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
251 - unsigned int den = (M + 1) << 12;
253 - return cal_dsm(pll, num, den);
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)
260 - return mash_dsm(pll, M, N, K);
261 - else if (!phase_div_en)
262 - return mash_dsm(pll, M, N, K);
264 - return ssff_dsm_2(pll, M, N, K);
267 -static inline unsigned int ltq_get_pll0_fosc(void)
269 - if (CGU_PLL0_BYPASS)
270 - return get_input_clock(0);
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);
281 -static unsigned int ltq_get_pll0_fdiv(void)
283 - unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
285 - return (ltq_get_pll0_fosc() + (div >> 1)) / div;
288 -unsigned int ltq_get_io_region_clock(void)
290 - unsigned int ret = ltq_get_pll0_fosc();
292 - switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
295 - return (ret + 1) / 2;
297 - return (ret * 2 + 2) / 5;
299 - return (ret + 1) / 3;
301 - return (ret + 2) / 4;
304 -EXPORT_SYMBOL(ltq_get_io_region_clock);
306 -unsigned int ltq_get_fpi_bus_clock(int fpi)
308 - unsigned int ret = ltq_get_io_region_clock();
310 - if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
314 -EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
316 -unsigned int ltq_get_cpu_hz(void)
318 - switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
324 - return DDR_HZ << 1;
326 - return DDR_HZ >> 1;
329 -EXPORT_SYMBOL(ltq_get_cpu_hz);
331 -unsigned int ltq_get_fpi_hz(void)
333 - unsigned int ddr_clock = DDR_HZ;
335 - if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
336 - return ddr_clock >> 1;
339 -EXPORT_SYMBOL(ltq_get_fpi_hz);
341 +++ b/arch/mips/lantiq/xway/clk.c
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.
348 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
351 +#include <linux/io.h>
352 +#include <linux/export.h>
353 +#include <linux/init.h>
354 +#include <linux/clk.h>
356 +#include <asm/time.h>
357 +#include <asm/irq.h>
358 +#include <asm/div64.h>
360 +#include <lantiq_soc.h>
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]
368 +#define BASIC_FREQUENCY_1 35328000
369 +#define BASIC_FREQUENCY_2 36000000
370 +#define BASIS_REQUENCY_USB 12000000
372 +#define GET_BITS(x, msb, lsb) \
373 + (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
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
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)
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)
414 +#define LTQ_CGU_SYS_VR9 0x0c
415 +#define LTQ_CGU_IF_CLK_VR9 0x24
418 +static unsigned int ltq_get_pll0_fdiv(void);
420 +static inline unsigned int get_input_clock(int pll)
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;
429 + return BASIC_FREQUENCY_2;
432 + return BASIS_REQUENCY_USB;
433 + else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
434 + return BASIC_FREQUENCY_1;
436 + return BASIC_FREQUENCY_2;
438 + switch (CGU_PLL2_SRC) {
440 + return ltq_get_pll0_fdiv();
442 + return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
443 + BASIC_FREQUENCY_1 :
446 + return BASIS_REQUENCY_USB;
453 +static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
455 + u64 res, clock = get_input_clock(pll);
462 +static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
465 + unsigned int num = ((N + 1) << 10) + K;
466 + unsigned int den = (M + 1) << 10;
468 + return cal_dsm(pll, num, den);
471 +static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
474 + unsigned int num = ((N + 1) << 11) + K + 512;
475 + unsigned int den = (M + 1) << 11;
477 + return cal_dsm(pll, num, den);
480 +static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
483 + unsigned int num = K >= 512 ?
484 + ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
485 + unsigned int den = (M + 1) << 12;
487 + return cal_dsm(pll, num, den);
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)
494 + return mash_dsm(pll, M, N, K);
495 + else if (!phase_div_en)
496 + return mash_dsm(pll, M, N, K);
498 + return ssff_dsm_2(pll, M, N, K);
501 +static inline unsigned int ltq_get_pll0_fosc(void)
503 + if (CGU_PLL0_BYPASS)
504 + return get_input_clock(0);
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);
515 +static unsigned int ltq_get_pll0_fdiv(void)
517 + unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
519 + return (ltq_get_pll0_fosc() + (div >> 1)) / div;
522 +unsigned long ltq_danube_io_region_clock(void)
524 + unsigned int ret = ltq_get_pll0_fosc();
526 + switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
529 + return (ret + 1) / 2;
531 + return (ret * 2 + 2) / 5;
533 + return (ret + 1) / 3;
535 + return (ret + 2) / 4;
539 +unsigned long ltq_danube_fpi_bus_clock(int fpi)
541 + unsigned long ret = ltq_danube_io_region_clock();
543 + if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
548 +unsigned long ltq_danube_cpu_hz(void)
550 + switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
556 + return DDR_HZ << 1;
558 + return DDR_HZ >> 1;
562 +unsigned long ltq_danube_fpi_hz(void)
564 + unsigned long ddr_clock = DDR_HZ;
566 + if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
567 + return ddr_clock >> 1;
570 --- a/arch/mips/lantiq/xway/sysctrl.c
571 +++ b/arch/mips/lantiq/xway/sysctrl.c
574 #include <linux/ioport.h>
575 #include <linux/export.h>
576 +#include <linux/clkdev.h>
578 #include <lantiq_soc.h>
581 #include "../devices.h"
583 /* clock control register */
584 #define LTQ_CGU_IFCCR 0x0018
585 +/* system clock register */
586 +#define LTQ_CGU_SYS 0x0010
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
594 +#define PWDCR(x) ((x) ? (LTQ_PMU_PWDCR1) : (LTQ_PMU_PWDCR))
595 +#define PWDSR(x) ((x) ? (LTQ_PMU_PWDSR1) : (LTQ_PMU_PWDSR))
597 +/* CGU - clock generation unit */
598 +#define CGU_EPHY 0x10
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
614 +#define PMU1_PCIE_PHY 0x0001
615 +#define PMU1_PCIE_CTL 0x0002
616 +#define PMU1_PCIE_MSI 0x0020
617 +#define PMU1_PCIE_PDI 0x0010
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;
625 -void ltq_cgu_enable(unsigned int clk)
626 +static int ltq_cgu_enable(struct clk *clk)
628 + ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | clk->bits, LTQ_CGU_IFCCR);
632 +static void ltq_cgu_disable(struct clk *clk)
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);
638 -void ltq_pmu_enable(unsigned int module)
639 +static int ltq_pmu_enable(struct clk *clk)
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));
650 panic("activating PMU module failed!\n");
655 +static void ltq_pmu_disable(struct clk *clk)
657 + ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | clk->bits, LTQ_PMU_PWDCR);
660 +static inline void clkdev_add_pmu(const char *dev, const char *con,
661 + unsigned int module, unsigned int bits)
663 + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
665 + clk->cl.dev_id = dev;
666 + clk->cl.con_id = con;
668 + clk->enable = ltq_pmu_enable;
669 + clk->disable = ltq_pmu_disable;
670 + clk->module = module;
672 + clkdev_add(&clk->cl);
674 -EXPORT_SYMBOL(ltq_pmu_enable);
676 -void ltq_pmu_disable(unsigned int module)
677 +static inline void clkdev_add_cgu(const char *dev, const char *con,
680 - ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
681 + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
683 + clk->cl.dev_id = dev;
684 + clk->cl.con_id = con;
686 + clk->enable = ltq_cgu_enable;
687 + clk->disable = ltq_cgu_disable;
689 + clkdev_add(&clk->cl);
691 -EXPORT_SYMBOL(ltq_pmu_disable);
693 void __init ltq_soc_init(void)
695 @@ -75,4 +142,23 @@ void __init ltq_soc_init(void)
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);
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);
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);
713 + clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
714 + ltq_danube_io_region_clock());
716 + clkdev_add_pmu("ltq_etop", "switch", 0, PMU_SWITCH);