diff options
author | Heiko St?bner <heiko@sntech.de> | 2011-10-14 02:08:56 -0400 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2011-10-14 02:15:49 -0400 |
commit | aab08eebdf87d3e6eda5c81f119423af63f5aee1 (patch) | |
tree | dc8b3182c00b3e4b4989d6c9a559153068804094 | |
parent | d9a3bfbd7e80ecf24d2322659d5c0542f9d95e78 (diff) |
ARM: S3C2443: Move clk_arm and clk_armdiv to common code
The system-layout of the armdiv and armclk is common to
S3C2443/S3C2416/S3C2450 and only differs in the array of
possible dividers. Therefore it is possible to reuse the
clock definitions for all of these SoCs.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r-- | arch/arm/mach-s3c2443/clock.c | 85 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/s3c2443-clock.c | 87 |
2 files changed, 89 insertions, 83 deletions
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 88edc55838a1..6fda4bf09cdd 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c | |||
@@ -61,10 +61,10 @@ | |||
61 | * | 61 | * |
62 | * this clock is sourced from msysclk and can have a number of | 62 | * this clock is sourced from msysclk and can have a number of |
63 | * divider values applied to it to then be fed into armclk. | 63 | * divider values applied to it to then be fed into armclk. |
64 | * The real clock definition is done in s3c2443-clock.c, | ||
65 | * only the armdiv divisor table must be defined here. | ||
64 | */ | 66 | */ |
65 | 67 | ||
66 | /* armdiv divisor table */ | ||
67 | |||
68 | static unsigned int armdiv[16] = { | 68 | static unsigned int armdiv[16] = { |
69 | [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, | 69 | [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, |
70 | [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, | 70 | [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, |
@@ -83,85 +83,6 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0) | |||
83 | return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; | 83 | return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; |
84 | } | 84 | } |
85 | 85 | ||
86 | static unsigned long s3c2443_armclk_roundrate(struct clk *clk, | ||
87 | unsigned long rate) | ||
88 | { | ||
89 | unsigned long parent = clk_get_rate(clk->parent); | ||
90 | unsigned long calc; | ||
91 | unsigned best = 256; /* bigger than any value */ | ||
92 | unsigned div; | ||
93 | int ptr; | ||
94 | |||
95 | for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) { | ||
96 | div = armdiv[ptr]; | ||
97 | calc = parent / div; | ||
98 | if (calc <= rate && div < best) | ||
99 | best = div; | ||
100 | } | ||
101 | |||
102 | return parent / best; | ||
103 | } | ||
104 | |||
105 | static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate) | ||
106 | { | ||
107 | unsigned long parent = clk_get_rate(clk->parent); | ||
108 | unsigned long calc; | ||
109 | unsigned div; | ||
110 | unsigned best = 256; /* bigger than any value */ | ||
111 | int ptr; | ||
112 | int val = -1; | ||
113 | |||
114 | for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) { | ||
115 | div = armdiv[ptr]; | ||
116 | calc = parent / div; | ||
117 | if (calc <= rate && div < best) { | ||
118 | best = div; | ||
119 | val = ptr; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | if (val >= 0) { | ||
124 | unsigned long clkcon0; | ||
125 | |||
126 | clkcon0 = __raw_readl(S3C2443_CLKDIV0); | ||
127 | clkcon0 &= ~S3C2443_CLKDIV0_ARMDIV_MASK; | ||
128 | clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT; | ||
129 | __raw_writel(clkcon0, S3C2443_CLKDIV0); | ||
130 | } | ||
131 | |||
132 | return (val == -1) ? -EINVAL : 0; | ||
133 | } | ||
134 | |||
135 | static struct clk clk_armdiv = { | ||
136 | .name = "armdiv", | ||
137 | .parent = &clk_msysclk.clk, | ||
138 | .ops = &(struct clk_ops) { | ||
139 | .round_rate = s3c2443_armclk_roundrate, | ||
140 | .set_rate = s3c2443_armclk_setrate, | ||
141 | }, | ||
142 | }; | ||
143 | |||
144 | /* armclk | ||
145 | * | ||
146 | * this is the clock fed into the ARM core itself, from armdiv or from hclk. | ||
147 | */ | ||
148 | |||
149 | static struct clk *clk_arm_sources[] = { | ||
150 | [0] = &clk_armdiv, | ||
151 | [1] = &clk_h, | ||
152 | }; | ||
153 | |||
154 | static struct clksrc_clk clk_arm = { | ||
155 | .clk = { | ||
156 | .name = "armclk", | ||
157 | }, | ||
158 | .sources = &(struct clksrc_sources) { | ||
159 | .sources = clk_arm_sources, | ||
160 | .nr_sources = ARRAY_SIZE(clk_arm_sources), | ||
161 | }, | ||
162 | .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, | ||
163 | }; | ||
164 | |||
165 | /* hsspi | 86 | /* hsspi |
166 | * | 87 | * |
167 | * high-speed spi clock, sourced from esysclk | 88 | * high-speed spi clock, sourced from esysclk |
@@ -260,14 +181,12 @@ static struct clk init_clocks[] = { | |||
260 | /* clocks to add straight away */ | 181 | /* clocks to add straight away */ |
261 | 182 | ||
262 | static struct clksrc_clk *clksrcs[] __initdata = { | 183 | static struct clksrc_clk *clksrcs[] __initdata = { |
263 | &clk_arm, | ||
264 | &clk_hsspi, | 184 | &clk_hsspi, |
265 | &clk_hsmmc_div, | 185 | &clk_hsmmc_div, |
266 | }; | 186 | }; |
267 | 187 | ||
268 | static struct clk *clks[] __initdata = { | 188 | static struct clk *clks[] __initdata = { |
269 | &clk_hsmmc, | 189 | &clk_hsmmc, |
270 | &clk_armdiv, | ||
271 | }; | 190 | }; |
272 | 191 | ||
273 | void __init_or_cpufreq s3c2443_setup_clocks(void) | 192 | void __init_or_cpufreq s3c2443_setup_clocks(void) |
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c index 3f2117b8c0d4..f9c5b0343cf3 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c | |||
@@ -160,10 +160,95 @@ static struct clk clk_prediv = { | |||
160 | }, | 160 | }, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | /* armdiv | ||
164 | * | ||
165 | * this clock is sourced from msysclk and can have a number of | ||
166 | * divider values applied to it to then be fed into armclk. | ||
167 | */ | ||
168 | |||
163 | static unsigned int *armdiv; | 169 | static unsigned int *armdiv; |
164 | static int nr_armdiv; | 170 | static int nr_armdiv; |
165 | static int armdivmask; | 171 | static int armdivmask; |
166 | 172 | ||
173 | static unsigned long s3c2443_armclk_roundrate(struct clk *clk, | ||
174 | unsigned long rate) | ||
175 | { | ||
176 | unsigned long parent = clk_get_rate(clk->parent); | ||
177 | unsigned long calc; | ||
178 | unsigned best = 256; /* bigger than any value */ | ||
179 | unsigned div; | ||
180 | int ptr; | ||
181 | |||
182 | for (ptr = 0; ptr < nr_armdiv; ptr++) { | ||
183 | div = armdiv[ptr]; | ||
184 | calc = parent / div; | ||
185 | if (calc <= rate && div < best) | ||
186 | best = div; | ||
187 | } | ||
188 | |||
189 | return parent / best; | ||
190 | } | ||
191 | |||
192 | static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate) | ||
193 | { | ||
194 | unsigned long parent = clk_get_rate(clk->parent); | ||
195 | unsigned long calc; | ||
196 | unsigned div; | ||
197 | unsigned best = 256; /* bigger than any value */ | ||
198 | int ptr; | ||
199 | int val = -1; | ||
200 | |||
201 | for (ptr = 0; ptr < nr_armdiv; ptr++) { | ||
202 | div = armdiv[ptr]; | ||
203 | calc = parent / div; | ||
204 | if (calc <= rate && div < best) { | ||
205 | best = div; | ||
206 | val = ptr; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | if (val >= 0) { | ||
211 | unsigned long clkcon0; | ||
212 | |||
213 | clkcon0 = __raw_readl(S3C2443_CLKDIV0); | ||
214 | clkcon0 &= ~armdivmask; | ||
215 | clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT; | ||
216 | __raw_writel(clkcon0, S3C2443_CLKDIV0); | ||
217 | } | ||
218 | |||
219 | return (val == -1) ? -EINVAL : 0; | ||
220 | } | ||
221 | |||
222 | static struct clk clk_armdiv = { | ||
223 | .name = "armdiv", | ||
224 | .parent = &clk_msysclk.clk, | ||
225 | .ops = &(struct clk_ops) { | ||
226 | .round_rate = s3c2443_armclk_roundrate, | ||
227 | .set_rate = s3c2443_armclk_setrate, | ||
228 | }, | ||
229 | }; | ||
230 | |||
231 | /* armclk | ||
232 | * | ||
233 | * this is the clock fed into the ARM core itself, from armdiv or from hclk. | ||
234 | */ | ||
235 | |||
236 | static struct clk *clk_arm_sources[] = { | ||
237 | [0] = &clk_armdiv, | ||
238 | [1] = &clk_h, | ||
239 | }; | ||
240 | |||
241 | static struct clksrc_clk clk_arm = { | ||
242 | .clk = { | ||
243 | .name = "armclk", | ||
244 | }, | ||
245 | .sources = &(struct clksrc_sources) { | ||
246 | .sources = clk_arm_sources, | ||
247 | .nr_sources = ARRAY_SIZE(clk_arm_sources), | ||
248 | }, | ||
249 | .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, | ||
250 | }; | ||
251 | |||
167 | /* usbhost | 252 | /* usbhost |
168 | * | 253 | * |
169 | * usb host bus-clock, usually 48MHz to provide USB bus clock timing | 254 | * usb host bus-clock, usually 48MHz to provide USB bus clock timing |
@@ -462,6 +547,7 @@ static struct clk *clks[] __initdata = { | |||
462 | &clk_ext, | 547 | &clk_ext, |
463 | &clk_epll, | 548 | &clk_epll, |
464 | &clk_usb_bus, | 549 | &clk_usb_bus, |
550 | &clk_armdiv, | ||
465 | }; | 551 | }; |
466 | 552 | ||
467 | static struct clksrc_clk *clksrcs[] __initdata = { | 553 | static struct clksrc_clk *clksrcs[] __initdata = { |
@@ -471,6 +557,7 @@ static struct clksrc_clk *clksrcs[] __initdata = { | |||
471 | &clk_epllref, | 557 | &clk_epllref, |
472 | &clk_esysclk, | 558 | &clk_esysclk, |
473 | &clk_msysclk, | 559 | &clk_msysclk, |
560 | &clk_arm, | ||
474 | }; | 561 | }; |
475 | 562 | ||
476 | void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, | 563 | void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, |