aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s3c24xx
diff options
context:
space:
mode:
authorHeiko St?bner <heiko@sntech.de>2011-10-14 02:08:56 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-10-14 02:15:49 -0400
commitaab08eebdf87d3e6eda5c81f119423af63f5aee1 (patch)
treedc8b3182c00b3e4b4989d6c9a559153068804094 /arch/arm/plat-s3c24xx
parentd9a3bfbd7e80ecf24d2322659d5c0542f9d95e78 (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>
Diffstat (limited to 'arch/arm/plat-s3c24xx')
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c87
1 files changed, 87 insertions, 0 deletions
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
163static unsigned int *armdiv; 169static unsigned int *armdiv;
164static int nr_armdiv; 170static int nr_armdiv;
165static int armdivmask; 171static int armdivmask;
166 172
173static 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
192static 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
222static 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
236static struct clk *clk_arm_sources[] = {
237 [0] = &clk_armdiv,
238 [1] = &clk_h,
239};
240
241static 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
467static struct clksrc_clk *clksrcs[] __initdata = { 553static 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
476void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, 563void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,