aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-w90x900/Makefile2
-rw-r--r--arch/arm/mach-w90x900/clksel.c91
-rw-r--r--arch/arm/mach-w90x900/cpu.h1
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-clock.h22
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-ebi.h33
-rw-r--r--arch/arm/mach-w90x900/w90p910.c80
6 files changed, 228 insertions, 1 deletions
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile
index d50c94f4dbd..3ccd625455c 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
7obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o 7obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o
8 8obj-y += clksel.o
9# W90X900 CPU support files 9# W90X900 CPU support files
10 10
11obj-$(CONFIG_CPU_W90P910) += w90p910.o 11obj-$(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 00000000000..5a77eb91cb1
--- /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
37static DEFINE_MUTEX(clksel_sem);
38
39static 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
62void 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}
90EXPORT_SYMBOL(w90p910_clock_source);
91
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
index 57b5dbabeb4..ddde959d898 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);
45extern void w90p910_map_io(struct map_desc *mach_desc, int size); 45extern void w90p910_map_io(struct map_desc *mach_desc, int size);
46extern struct platform_device w90p910_serial_device; 46extern struct platform_device w90p910_serial_device;
47extern struct sys_timer w90x900_timer; 47extern struct sys_timer w90x900_timer;
48extern 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 f10b6a8dc06..516d6b477b6 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 00000000000..b68455e7f88
--- /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 6ebf5cfc78d..8444eababaa 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*/
130static 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}
179static 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
128void __init w90p910_init_clocks(void) 208void __init w90p910_init_clocks(void)