diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-10-21 09:07:00 -0400 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2008-12-15 16:53:58 -0500 |
commit | 4b31d8b2256db3ed825a63603f223f84d927ca39 (patch) | |
tree | 256cfe52c637140342791d230c0f3de4b725284b /arch/arm | |
parent | 952b564b4d26964e3114d02368741e192e30ae28 (diff) |
[ARM] S3C64XX: Add initial clock framework
Add the initial clocks definitions for the s3c6400
and s3c6410. Move the epll and ext clock from the
s3c2443 support into the common code.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-s3c2412/clock.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-s3c2443/clock.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-s3c6410/cpu.c | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c/clock.c | 10 | ||||
-rw-r--r-- | arch/arm/plat-s3c/include/plat/clock.h | 8 | ||||
-rw-r--r-- | arch/arm/plat-s3c64xx/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c64xx/clock.c | 258 |
7 files changed, 279 insertions, 20 deletions
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index 96d9eb15424f..3ce15e082e77 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c | |||
@@ -93,12 +93,6 @@ static int s3c2412_upll_enable(struct clk *clk, int enable) | |||
93 | 93 | ||
94 | /* clock selections */ | 94 | /* clock selections */ |
95 | 95 | ||
96 | /* CPU EXTCLK input */ | ||
97 | static struct clk clk_ext = { | ||
98 | .name = "extclk", | ||
99 | .id = -1, | ||
100 | }; | ||
101 | |||
102 | static struct clk clk_erefclk = { | 96 | static struct clk clk_erefclk = { |
103 | .name = "erefclk", | 97 | .name = "erefclk", |
104 | .id = -1, | 98 | .id = -1, |
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 1df8429242b8..363f39608783 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c | |||
@@ -147,12 +147,6 @@ static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk, | |||
147 | 147 | ||
148 | /* clock selections */ | 148 | /* clock selections */ |
149 | 149 | ||
150 | /* CPU EXTCLK input */ | ||
151 | static struct clk clk_ext = { | ||
152 | .name = "ext", | ||
153 | .id = -1, | ||
154 | }; | ||
155 | |||
156 | static struct clk clk_mpllref = { | 150 | static struct clk clk_mpllref = { |
157 | .name = "mpllref", | 151 | .name = "mpllref", |
158 | .parent = &clk_xtal, | 152 | .parent = &clk_xtal, |
@@ -167,14 +161,6 @@ static struct clk clk_mpll = { | |||
167 | }; | 161 | }; |
168 | #endif | 162 | #endif |
169 | 163 | ||
170 | static struct clk clk_epllref; | ||
171 | |||
172 | static struct clk clk_epll = { | ||
173 | .name = "epll", | ||
174 | .parent = &clk_epllref, | ||
175 | .id = -1, | ||
176 | }; | ||
177 | |||
178 | static struct clk clk_i2s_ext = { | 164 | static struct clk clk_i2s_ext = { |
179 | .name = "i2s-ext", | 165 | .name = "i2s-ext", |
180 | .id = -1, | 166 | .id = -1, |
@@ -1072,6 +1058,7 @@ void __init s3c2443_init_clocks(int xtal) | |||
1072 | } | 1058 | } |
1073 | 1059 | ||
1074 | clk_epll.rate = s3c2443_get_epll(epllcon, xtal); | 1060 | clk_epll.rate = s3c2443_get_epll(epllcon, xtal); |
1061 | clk_epll.parent = &clk_epllref; | ||
1075 | clk_usb_bus.parent = &clk_usb_bus_host; | 1062 | clk_usb_bus.parent = &clk_usb_bus_host; |
1076 | 1063 | ||
1077 | /* ensure usb bus clock is within correct rate of 48MHz */ | 1064 | /* ensure usb bus clock is within correct rate of 48MHz */ |
diff --git a/arch/arm/mach-s3c6410/cpu.c b/arch/arm/mach-s3c6410/cpu.c index c3e317c16502..94a6204ee55a 100644 --- a/arch/arm/mach-s3c6410/cpu.c +++ b/arch/arm/mach-s3c6410/cpu.c | |||
@@ -56,6 +56,7 @@ void __init s3c6410_init_clocks(int xtal) | |||
56 | { | 56 | { |
57 | printk(KERN_INFO "%s: initialising clocks\n", __func__); | 57 | printk(KERN_INFO "%s: initialising clocks\n", __func__); |
58 | s3c24xx_register_baseclocks(xtal); | 58 | s3c24xx_register_baseclocks(xtal); |
59 | s3c64xx_register_clocks(); | ||
59 | } | 60 | } |
60 | 61 | ||
61 | void __init s3c6410_init_irq(void) | 62 | void __init s3c6410_init_irq(void) |
diff --git a/arch/arm/plat-s3c/clock.c b/arch/arm/plat-s3c/clock.c index da7ac07c7a0b..1054d18828fd 100644 --- a/arch/arm/plat-s3c/clock.c +++ b/arch/arm/plat-s3c/clock.c | |||
@@ -239,6 +239,16 @@ struct clk clk_xtal = { | |||
239 | .ctrlbit = 0, | 239 | .ctrlbit = 0, |
240 | }; | 240 | }; |
241 | 241 | ||
242 | struct clk clk_ext = { | ||
243 | .name = "ext", | ||
244 | .id = -1, | ||
245 | }; | ||
246 | |||
247 | struct clk clk_epll = { | ||
248 | .name = "epll", | ||
249 | .id = -1, | ||
250 | }; | ||
251 | |||
242 | struct clk clk_mpll = { | 252 | struct clk clk_mpll = { |
243 | .name = "mpll", | 253 | .name = "mpll", |
244 | .id = -1, | 254 | .id = -1, |
diff --git a/arch/arm/plat-s3c/include/plat/clock.h b/arch/arm/plat-s3c/include/plat/clock.h index d871609738f9..6a2c5af10009 100644 --- a/arch/arm/plat-s3c/include/plat/clock.h +++ b/arch/arm/plat-s3c/include/plat/clock.h | |||
@@ -45,7 +45,13 @@ extern struct clk clk_h; | |||
45 | extern struct clk clk_p; | 45 | extern struct clk clk_p; |
46 | extern struct clk clk_mpll; | 46 | extern struct clk clk_mpll; |
47 | extern struct clk clk_upll; | 47 | extern struct clk clk_upll; |
48 | extern struct clk clk_epll; | ||
48 | extern struct clk clk_xtal; | 49 | extern struct clk clk_xtal; |
50 | extern struct clk clk_ext; | ||
51 | |||
52 | /* S3C64XX specific clocks */ | ||
53 | extern struct clk clk_27m; | ||
54 | extern struct clk clk_48m; | ||
49 | 55 | ||
50 | /* exports for arch/arm/mach-s3c2410 | 56 | /* exports for arch/arm/mach-s3c2410 |
51 | * | 57 | * |
@@ -61,6 +67,8 @@ extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); | |||
61 | 67 | ||
62 | extern int s3c24xx_register_baseclocks(unsigned long xtal); | 68 | extern int s3c24xx_register_baseclocks(unsigned long xtal); |
63 | 69 | ||
70 | extern void s3c64xx_register_clocks(void); | ||
71 | |||
64 | extern void s3c24xx_setup_clocks(unsigned long fclk, | 72 | extern void s3c24xx_setup_clocks(unsigned long fclk, |
65 | unsigned long hclk, | 73 | unsigned long hclk, |
66 | unsigned long pclk); | 74 | unsigned long pclk); |
diff --git a/arch/arm/plat-s3c64xx/Makefile b/arch/arm/plat-s3c64xx/Makefile index 26b5714ee736..15f717fd1483 100644 --- a/arch/arm/plat-s3c64xx/Makefile +++ b/arch/arm/plat-s3c64xx/Makefile | |||
@@ -15,6 +15,7 @@ obj- := | |||
15 | obj-y += dev-uart.o | 15 | obj-y += dev-uart.o |
16 | obj-y += cpu.o | 16 | obj-y += cpu.o |
17 | obj-y += irq.o | 17 | obj-y += irq.o |
18 | obj-y += clock.o | ||
18 | 19 | ||
19 | # CPU support | 20 | # CPU support |
20 | 21 | ||
diff --git a/arch/arm/plat-s3c64xx/clock.c b/arch/arm/plat-s3c64xx/clock.c new file mode 100644 index 000000000000..e7c2994e2d32 --- /dev/null +++ b/arch/arm/plat-s3c64xx/clock.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* linux/arch/arm/plat-s3c64xx/clock.c | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * S3C64XX Base clock support | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/init.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/io.h> | ||
21 | |||
22 | #include <mach/hardware.h> | ||
23 | #include <mach/map.h> | ||
24 | |||
25 | #include <plat/regs-clock.h> | ||
26 | #include <plat/cpu.h> | ||
27 | #include <plat/devs.h> | ||
28 | #include <plat/clock.h> | ||
29 | |||
30 | struct clk clk_27m = { | ||
31 | .name = "clk_27m", | ||
32 | .id = -1, | ||
33 | .rate = 27000000, | ||
34 | }; | ||
35 | |||
36 | struct clk clk_48m = { | ||
37 | .name = "clk_48m", | ||
38 | .id = -1, | ||
39 | .rate = 48000000, | ||
40 | }; | ||
41 | |||
42 | static int inline s3c64xx_gate(void __iomem *reg, | ||
43 | struct clk *clk, | ||
44 | int enable) | ||
45 | { | ||
46 | unsigned int ctrlbit = clk->ctrlbit; | ||
47 | u32 con; | ||
48 | |||
49 | con = __raw_readl(reg); | ||
50 | |||
51 | if (enable) | ||
52 | con |= ctrlbit; | ||
53 | else | ||
54 | con &= ~ctrlbit; | ||
55 | |||
56 | __raw_writel(con, reg); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int s3c64xx_pclk_ctrl(struct clk *clk, int enable) | ||
61 | { | ||
62 | return s3c64xx_gate(S3C_PCLK_GATE, clk, enable); | ||
63 | } | ||
64 | |||
65 | static int s3c64xx_hclk_ctrl(struct clk *clk, int enable) | ||
66 | { | ||
67 | return s3c64xx_gate(S3C_HCLK_GATE, clk, enable); | ||
68 | } | ||
69 | |||
70 | static int s3c6xx_sclk_ctrl(struct clk *clk, int enable) | ||
71 | { | ||
72 | return s3c64xx_gate(S3C_SCLK_GATE, clk, enable); | ||
73 | } | ||
74 | |||
75 | static struct clk init_clocks_disable[] = { | ||
76 | { | ||
77 | .name = "nand", | ||
78 | .id = -1, | ||
79 | .parent = &clk_h, | ||
80 | }, { | ||
81 | .name = "adc", | ||
82 | .id = -1, | ||
83 | .parent = &clk_p, | ||
84 | .enable = s3c64xx_pclk_ctrl, | ||
85 | .ctrlbit = S3C_CLKCON_PCLK_TSADC, | ||
86 | }, { | ||
87 | .name = "i2c", | ||
88 | .id = -1, | ||
89 | .parent = &clk_p, | ||
90 | .enable = s3c64xx_pclk_ctrl, | ||
91 | .ctrlbit = S3C_CLKCON_PCLK_IIC, | ||
92 | }, { | ||
93 | .name = "iis", | ||
94 | .id = 0, | ||
95 | .parent = &clk_p, | ||
96 | .enable = s3c64xx_pclk_ctrl, | ||
97 | .ctrlbit = S3C_CLKCON_PCLK_IIS0, | ||
98 | }, { | ||
99 | .name = "iis", | ||
100 | .id = 1, | ||
101 | .parent = &clk_p, | ||
102 | .enable = s3c64xx_pclk_ctrl, | ||
103 | .ctrlbit = S3C_CLKCON_PCLK_IIS1, | ||
104 | }, { | ||
105 | .name = "spi", | ||
106 | .id = 0, | ||
107 | .parent = &clk_p, | ||
108 | .enable = s3c64xx_pclk_ctrl, | ||
109 | .ctrlbit = S3C_CLKCON_PCLK_SPI0, | ||
110 | }, { | ||
111 | .name = "spi", | ||
112 | .id = 1, | ||
113 | .parent = &clk_p, | ||
114 | .enable = s3c64xx_pclk_ctrl, | ||
115 | .ctrlbit = S3C_CLKCON_PCLK_SPI1, | ||
116 | }, { | ||
117 | .name = "48m", | ||
118 | .id = 0, | ||
119 | .parent = &clk_48m, | ||
120 | .enable = s3c64xx_sclk_ctrl, | ||
121 | .ctrlbit = S3C_CLKCON_SCLK_MMC0_48, | ||
122 | }, { | ||
123 | .name = "48m", | ||
124 | .id = 1, | ||
125 | .parent = &clk_48m, | ||
126 | .enable = s3c64xx_sclk_ctrl, | ||
127 | .ctrlbit = S3C_CLKCON_SCLK_MMC1_48, | ||
128 | }, { | ||
129 | .name = "48m", | ||
130 | .id = 2, | ||
131 | .parent = &clk_48m, | ||
132 | .enable = s3c64xx_sclk_ctrl, | ||
133 | .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, | ||
134 | }, | ||
135 | }; | ||
136 | |||
137 | static struct clk init_clocks[] = { | ||
138 | { | ||
139 | .name = "lcd", | ||
140 | .id = -1, | ||
141 | .parent = &clk_h, | ||
142 | .enable = s3c64xx_hclk_ctrl, | ||
143 | .ctrlbit = S3C_CLKCON_HCLK_LCD, | ||
144 | }, { | ||
145 | .name = "gpio", | ||
146 | .id = -1, | ||
147 | .parent = &clk_p, | ||
148 | .enable = s3c64xx_pclk_ctrl, | ||
149 | .ctrlbit = S3C_CLKCON_PCLK_GPIO, | ||
150 | }, { | ||
151 | .name = "usb-host", | ||
152 | .id = -1, | ||
153 | .parent = &clk_h, | ||
154 | .enable = s3c64xx_hclk_ctrl, | ||
155 | .ctrlbit = S3C_CLKCON_SCLK_UHOST, | ||
156 | }, { | ||
157 | .name = "hsmmc", | ||
158 | .id = 0, | ||
159 | .parent = &clk_h, | ||
160 | .enable = s3c64xx_hclk_ctrl, | ||
161 | .ctrlbit = S3C_CLKCON_HCLK_HSMMC0, | ||
162 | }, { | ||
163 | .name = "hsmmc", | ||
164 | .id = 1, | ||
165 | .parent = &clk_h, | ||
166 | .enable = s3c64xx_hclk_ctrl, | ||
167 | .ctrlbit = S3C_CLKCON_HCLK_HSMMC1, | ||
168 | }, { | ||
169 | .name = "hsmmc", | ||
170 | .id = 2, | ||
171 | .parent = &clk_h, | ||
172 | .enable = s3c64xx_hclk_ctrl, | ||
173 | .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, | ||
174 | }, { | ||
175 | .name = "timers", | ||
176 | .id = -1, | ||
177 | .parent = &clk_p, | ||
178 | .enable = s3c64xx_pclk_ctrl, | ||
179 | .ctrlbit = S3C_CLKCON_PCLK_PWM, | ||
180 | }, { | ||
181 | .name = "uart", | ||
182 | .id = 0, | ||
183 | .parent = &clk_p, | ||
184 | .enable = s3c64xx_pclk_ctrl, | ||
185 | .ctrlbit = S3C_CLKCON_PCLK_UART0, | ||
186 | }, { | ||
187 | .name = "uart", | ||
188 | .id = 1, | ||
189 | .parent = &clk_p, | ||
190 | .enable = s3c64xx_pclk_ctrl, | ||
191 | .ctrlbit = S3C_CLKCON_PCLK_UART1, | ||
192 | }, { | ||
193 | .name = "uart", | ||
194 | .id = 2, | ||
195 | .parent = &clk_p, | ||
196 | .enable = s3c64xx_pclk_ctrl, | ||
197 | .ctrlbit = S3C_CLKCON_PCLK_UART2, | ||
198 | }, { | ||
199 | .name = "uart", | ||
200 | .id = 3, | ||
201 | .parent = &clk_p, | ||
202 | .enable = s3c64xx_pclk_ctrl, | ||
203 | .ctrlbit = S3C_CLKCON_PCLK_UART3, | ||
204 | }, { | ||
205 | .name = "rtc", | ||
206 | .id = -1, | ||
207 | .parent = &clk_p, | ||
208 | .enable = s3c64xx_pclk_ctrl, | ||
209 | .ctrlbit = S3C_CLKCON_PCLK_RTC, | ||
210 | }, { | ||
211 | .name = "watchdog", | ||
212 | .id = -1, | ||
213 | .parent = &clk_p, | ||
214 | .ctrlbit = S3C_CLKCON_PCLK_WDT, | ||
215 | }, { | ||
216 | .name = "ac97", | ||
217 | .id = -1, | ||
218 | .parent = &clk_p, | ||
219 | .ctrlbit = S3C_CLKCON_PCLK_AC97, | ||
220 | } | ||
221 | }; | ||
222 | |||
223 | static struct clk *clks[] __initdata = { | ||
224 | &clk_ext, | ||
225 | &clk_epll, | ||
226 | &clk_27m, | ||
227 | &clk_48m, | ||
228 | }; | ||
229 | |||
230 | void s3c64xx_register_clocks(void) | ||
231 | { | ||
232 | struct clk *clkp; | ||
233 | int ret; | ||
234 | int ptr; | ||
235 | |||
236 | s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); | ||
237 | |||
238 | clkp = init_clocks; | ||
239 | for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { | ||
240 | ret = s3c24xx_register_clock(clkp); | ||
241 | if (ret < 0) { | ||
242 | printk(KERN_ERR "Failed to register clock %s (%d)\n", | ||
243 | clkp->name, ret); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | clkp = init_clocks_disable; | ||
248 | for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { | ||
249 | |||
250 | ret = s3c24xx_register_clock(clkp); | ||
251 | if (ret < 0) { | ||
252 | printk(KERN_ERR "Failed to register clock %s (%d)\n", | ||
253 | clkp->name, ret); | ||
254 | } | ||
255 | |||
256 | (clkp->enable)(clkp, 0); | ||
257 | } | ||
258 | } | ||