diff options
author | wanzongshun <mcuos.com@gmail.com> | 2009-07-30 21:30:32 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-08-01 11:23:57 -0400 |
commit | ae45b1c618d9e645a5e1decff31b710f739745fa (patch) | |
tree | de581101750f9b1a040fbb131740424649995281 /arch | |
parent | 897bd6a363770ced6b78f6ae8882325c7590ed8b (diff) |
ARM: 5634/1: Add static setting cpu frequence for w90p910 platform
Add static setting cpu frequence for w90p910 platform.
Signed-off-by: Wan ZongShun <mcuos.com@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-w90x900/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-w90x900/clksel.c | 91 | ||||
-rw-r--r-- | arch/arm/mach-w90x900/cpu.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-w90x900/include/mach/regs-clock.h | 22 | ||||
-rw-r--r-- | arch/arm/mach-w90x900/include/mach/regs-ebi.h | 33 | ||||
-rw-r--r-- | arch/arm/mach-w90x900/w90p910.c | 80 |
6 files changed, 228 insertions, 1 deletions
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile index d50c94f4dbdf..3ccd625455cf 100644 --- a/arch/arm/mach-w90x900/Makefile +++ b/arch/arm/mach-w90x900/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | # Object file lists. | 5 | # Object file lists. |
6 | 6 | ||
7 | obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o | 7 | obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o |
8 | 8 | obj-y += clksel.o | |
9 | # W90X900 CPU support files | 9 | # W90X900 CPU support files |
10 | 10 | ||
11 | obj-$(CONFIG_CPU_W90P910) += w90p910.o | 11 | obj-$(CONFIG_CPU_W90P910) += w90p910.o |
diff --git a/arch/arm/mach-w90x900/clksel.c b/arch/arm/mach-w90x900/clksel.c new file mode 100644 index 000000000000..5a77eb91cb16 --- /dev/null +++ b/arch/arm/mach-w90x900/clksel.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-w90x900/clksel.c | ||
3 | * | ||
4 | * Copyright (c) 2008 Nuvoton technology corporation | ||
5 | * | ||
6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation;version 2 of the License. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/io.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <mach/regs-clock.h> | ||
26 | |||
27 | #define PLL0 0x00 | ||
28 | #define PLL1 0x01 | ||
29 | #define OTHER 0x02 | ||
30 | #define EXT 0x03 | ||
31 | #define MSOFFSET 0x0C | ||
32 | #define ATAOFFSET 0x0a | ||
33 | #define LCDOFFSET 0x06 | ||
34 | #define AUDOFFSET 0x04 | ||
35 | #define CPUOFFSET 0x00 | ||
36 | |||
37 | static DEFINE_MUTEX(clksel_sem); | ||
38 | |||
39 | static void clock_source_select(const char *dev_id, unsigned int clkval) | ||
40 | { | ||
41 | unsigned int clksel, offset; | ||
42 | |||
43 | clksel = __raw_readl(REG_CLKSEL); | ||
44 | |||
45 | if (strcmp(dev_id, "w90p910-ms") == 0) | ||
46 | offset = MSOFFSET; | ||
47 | else if (strcmp(dev_id, "w90p910-atapi") == 0) | ||
48 | offset = ATAOFFSET; | ||
49 | else if (strcmp(dev_id, "w90p910-lcd") == 0) | ||
50 | offset = LCDOFFSET; | ||
51 | else if (strcmp(dev_id, "w90p910-audio") == 0) | ||
52 | offset = AUDOFFSET; | ||
53 | else | ||
54 | offset = CPUOFFSET; | ||
55 | |||
56 | clksel &= ~(0x03 << offset); | ||
57 | clksel |= (clkval << offset); | ||
58 | |||
59 | __raw_writel(clksel, REG_CLKSEL); | ||
60 | } | ||
61 | |||
62 | void w90p910_clock_source(struct device *dev, unsigned char *src) | ||
63 | { | ||
64 | unsigned int clkval; | ||
65 | const char *dev_id; | ||
66 | |||
67 | BUG_ON(!src); | ||
68 | clkval = 0; | ||
69 | |||
70 | mutex_lock(&clksel_sem); | ||
71 | |||
72 | if (dev) | ||
73 | dev_id = dev_name(dev); | ||
74 | else | ||
75 | dev_id = "cpufreq"; | ||
76 | |||
77 | if (strcmp(src, "pll0") == 0) | ||
78 | clkval = PLL0; | ||
79 | else if (strcmp(src, "pll1") == 0) | ||
80 | clkval = PLL1; | ||
81 | else if (strcmp(src, "ext") == 0) | ||
82 | clkval = EXT; | ||
83 | else if (strcmp(src, "oth") == 0) | ||
84 | clkval = OTHER; | ||
85 | |||
86 | clock_source_select(dev_id, clkval); | ||
87 | |||
88 | mutex_unlock(&clksel_sem); | ||
89 | } | ||
90 | EXPORT_SYMBOL(w90p910_clock_source); | ||
91 | |||
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h index 57b5dbabeb41..ddde959d8987 100644 --- a/arch/arm/mach-w90x900/cpu.h +++ b/arch/arm/mach-w90x900/cpu.h | |||
@@ -45,6 +45,7 @@ extern void w90p910_init_clocks(void); | |||
45 | extern void w90p910_map_io(struct map_desc *mach_desc, int size); | 45 | extern void w90p910_map_io(struct map_desc *mach_desc, int size); |
46 | extern struct platform_device w90p910_serial_device; | 46 | extern struct platform_device w90p910_serial_device; |
47 | extern struct sys_timer w90x900_timer; | 47 | extern struct sys_timer w90x900_timer; |
48 | extern void w90p910_clock_source(struct device *dev, unsigned char *src); | ||
48 | 49 | ||
49 | #define W90X900_8250PORT(name) \ | 50 | #define W90X900_8250PORT(name) \ |
50 | { \ | 51 | { \ |
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h index f10b6a8dc069..516d6b477b61 100644 --- a/arch/arm/mach-w90x900/include/mach/regs-clock.h +++ b/arch/arm/mach-w90x900/include/mach/regs-clock.h | |||
@@ -28,4 +28,26 @@ | |||
28 | #define REG_CLKEN1 (CLK_BA + 0x24) | 28 | #define REG_CLKEN1 (CLK_BA + 0x24) |
29 | #define REG_CLKDIV1 (CLK_BA + 0x28) | 29 | #define REG_CLKDIV1 (CLK_BA + 0x28) |
30 | 30 | ||
31 | /* Define PLL freq setting */ | ||
32 | #define PLL_DISABLE 0x12B63 | ||
33 | #define PLL_66MHZ 0x2B63 | ||
34 | #define PLL_100MHZ 0x4F64 | ||
35 | #define PLL_120MHZ 0x4F63 | ||
36 | #define PLL_166MHZ 0x4124 | ||
37 | #define PLL_200MHZ 0x4F24 | ||
38 | |||
39 | /* Define AHB:CPUFREQ ratio */ | ||
40 | #define AHB_CPUCLK_1_1 0x00 | ||
41 | #define AHB_CPUCLK_1_2 0x01 | ||
42 | #define AHB_CPUCLK_1_4 0x02 | ||
43 | #define AHB_CPUCLK_1_8 0x03 | ||
44 | |||
45 | /* Define APB:AHB ratio */ | ||
46 | #define APB_AHB_1_2 0x01 | ||
47 | #define APB_AHB_1_4 0x02 | ||
48 | #define APB_AHB_1_8 0x03 | ||
49 | |||
50 | /* Define clock skew */ | ||
51 | #define DEFAULTSKEW 0x48 | ||
52 | |||
31 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ | 53 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ |
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/include/mach/regs-ebi.h new file mode 100644 index 000000000000..b68455e7f88b --- /dev/null +++ b/arch/arm/mach-w90x900/include/mach/regs-ebi.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-w90x900/include/mach/regs-ebi.h | ||
3 | * | ||
4 | * Copyright (c) 2009 Nuvoton technology corporation. | ||
5 | * | ||
6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation;version 2 of the License. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_ARCH_REGS_EBI_H | ||
15 | #define __ASM_ARCH_REGS_EBI_H | ||
16 | |||
17 | /* EBI Control Registers */ | ||
18 | |||
19 | #define EBI_BA W90X900_VA_EBI | ||
20 | #define REG_EBICON (EBI_BA + 0x00) | ||
21 | #define REG_ROMCON (EBI_BA + 0x04) | ||
22 | #define REG_SDCONF0 (EBI_BA + 0x08) | ||
23 | #define REG_SDCONF1 (EBI_BA + 0x0C) | ||
24 | #define REG_SDTIME0 (EBI_BA + 0x10) | ||
25 | #define REG_SDTIME1 (EBI_BA + 0x14) | ||
26 | #define REG_EXT0CON (EBI_BA + 0x18) | ||
27 | #define REG_EXT1CON (EBI_BA + 0x1C) | ||
28 | #define REG_EXT2CON (EBI_BA + 0x20) | ||
29 | #define REG_EXT3CON (EBI_BA + 0x24) | ||
30 | #define REG_EXT4CON (EBI_BA + 0x28) | ||
31 | #define REG_CKSKEW (EBI_BA + 0x2C) | ||
32 | |||
33 | #endif /* __ASM_ARCH_REGS_EBI_H */ | ||
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c index 6ebf5cfc78da..8444eababaab 100644 --- a/arch/arm/mach-w90x900/w90p910.c +++ b/arch/arm/mach-w90x900/w90p910.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/serial_8250.h> | 26 | #include <linux/serial_8250.h> |
27 | #include <linux/delay.h> | ||
27 | 28 | ||
28 | #include <asm/mach/arch.h> | 29 | #include <asm/mach/arch.h> |
29 | #include <asm/mach/map.h> | 30 | #include <asm/mach/map.h> |
@@ -32,6 +33,8 @@ | |||
32 | 33 | ||
33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
34 | #include <mach/regs-serial.h> | 35 | #include <mach/regs-serial.h> |
36 | #include <mach/regs-clock.h> | ||
37 | #include <mach/regs-ebi.h> | ||
35 | 38 | ||
36 | #include "cpu.h" | 39 | #include "cpu.h" |
37 | #include "clock.h" | 40 | #include "clock.h" |
@@ -123,6 +126,83 @@ void __init w90p910_map_io(struct map_desc *mach_desc, int mach_size) | |||
123 | printk(KERN_ERR "CPU type 0x%08lx is not W90P910\n", idcode); | 126 | printk(KERN_ERR "CPU type 0x%08lx is not W90P910\n", idcode); |
124 | } | 127 | } |
125 | 128 | ||
129 | /*Set W90P910 cpu frequence*/ | ||
130 | static int __init w90p910_set_clkval(unsigned int cpufreq) | ||
131 | { | ||
132 | unsigned int pllclk, ahbclk, apbclk, val; | ||
133 | |||
134 | pllclk = 0; | ||
135 | ahbclk = 0; | ||
136 | apbclk = 0; | ||
137 | |||
138 | switch (cpufreq) { | ||
139 | case 66: | ||
140 | pllclk = PLL_66MHZ; | ||
141 | ahbclk = AHB_CPUCLK_1_1; | ||
142 | apbclk = APB_AHB_1_2; | ||
143 | break; | ||
144 | |||
145 | case 100: | ||
146 | pllclk = PLL_100MHZ; | ||
147 | ahbclk = AHB_CPUCLK_1_1; | ||
148 | apbclk = APB_AHB_1_2; | ||
149 | break; | ||
150 | |||
151 | case 120: | ||
152 | pllclk = PLL_120MHZ; | ||
153 | ahbclk = AHB_CPUCLK_1_2; | ||
154 | apbclk = APB_AHB_1_2; | ||
155 | break; | ||
156 | |||
157 | case 166: | ||
158 | pllclk = PLL_166MHZ; | ||
159 | ahbclk = AHB_CPUCLK_1_2; | ||
160 | apbclk = APB_AHB_1_2; | ||
161 | break; | ||
162 | |||
163 | case 200: | ||
164 | pllclk = PLL_200MHZ; | ||
165 | ahbclk = AHB_CPUCLK_1_2; | ||
166 | apbclk = APB_AHB_1_2; | ||
167 | break; | ||
168 | } | ||
169 | |||
170 | __raw_writel(pllclk, REG_PLLCON0); | ||
171 | |||
172 | val = __raw_readl(REG_CLKDIV); | ||
173 | val &= ~(0x03 << 24 | 0x03 << 26); | ||
174 | val |= (ahbclk << 24 | apbclk << 26); | ||
175 | __raw_writel(val, REG_CLKDIV); | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | static int __init w90p910_set_cpufreq(char *str) | ||
180 | { | ||
181 | unsigned long cpufreq, val; | ||
182 | |||
183 | if (!*str) | ||
184 | return 0; | ||
185 | |||
186 | strict_strtoul(str, 0, &cpufreq); | ||
187 | |||
188 | w90p910_clock_source(NULL, "ext"); | ||
189 | |||
190 | w90p910_set_clkval(cpufreq); | ||
191 | |||
192 | mdelay(1); | ||
193 | |||
194 | val = __raw_readl(REG_CKSKEW); | ||
195 | val &= ~0xff; | ||
196 | val |= DEFAULTSKEW; | ||
197 | __raw_writel(val, REG_CKSKEW); | ||
198 | |||
199 | w90p910_clock_source(NULL, "pll0"); | ||
200 | |||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | __setup("cpufreq=", w90p910_set_cpufreq); | ||
205 | |||
126 | /*Init W90P910 clock*/ | 206 | /*Init W90P910 clock*/ |
127 | 207 | ||
128 | void __init w90p910_init_clocks(void) | 208 | void __init w90p910_init_clocks(void) |