diff options
author | Ben Dooks <ben-linux@fluff.org> | 2010-01-30 04:14:14 -0500 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2010-03-07 17:56:13 -0500 |
commit | 41f23a09f32124322dc41bea7f65baff6e9b0ac5 (patch) | |
tree | a4946823b836a2dc8c63c5dea3961b083ece28fc /arch/arm/mach-s3c2443 | |
parent | 71ed587d4a5d377ef5a6917043543ff949ff7dcf (diff) |
ARM: S3C2443: Add set_rate and round_rate calls for armdiv clock
Add set_rate and round_rate calls to armdiv for future use with cpu
frequency scaling.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm/mach-s3c2443')
-rw-r--r-- | arch/arm/mach-s3c2443/clock.c | 93 |
1 files changed, 73 insertions, 20 deletions
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 177719c7c267..62cd4eaee01b 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c | |||
@@ -165,10 +165,83 @@ static struct clksrc_clk clk_msysclk = { | |||
165 | * divider values applied to it to then be fed into armclk. | 165 | * divider values applied to it to then be fed into armclk. |
166 | */ | 166 | */ |
167 | 167 | ||
168 | /* armdiv divisor table */ | ||
169 | |||
170 | static unsigned int armdiv[16] = { | ||
171 | [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, | ||
172 | [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, | ||
173 | [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3, | ||
174 | [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4, | ||
175 | [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6, | ||
176 | [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8, | ||
177 | [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12, | ||
178 | [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16, | ||
179 | }; | ||
180 | |||
181 | static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0) | ||
182 | { | ||
183 | clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK; | ||
184 | |||
185 | return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; | ||
186 | } | ||
187 | |||
188 | static unsigned long s3c2443_armclk_roundrate(struct clk *clk, | ||
189 | unsigned long rate) | ||
190 | { | ||
191 | unsigned long parent = clk_get_rate(clk->parent); | ||
192 | unsigned long calc; | ||
193 | unsigned best = 256; /* bigger than any value */ | ||
194 | unsigned div; | ||
195 | int ptr; | ||
196 | |||
197 | for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) { | ||
198 | div = armdiv[ptr]; | ||
199 | calc = parent / div; | ||
200 | if (calc <= rate && div < best) | ||
201 | best = div; | ||
202 | } | ||
203 | |||
204 | return parent / best; | ||
205 | } | ||
206 | |||
207 | static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate) | ||
208 | { | ||
209 | unsigned long parent = clk_get_rate(clk->parent); | ||
210 | unsigned long calc; | ||
211 | unsigned div; | ||
212 | unsigned best = 256; /* bigger than any value */ | ||
213 | int ptr; | ||
214 | int val = -1; | ||
215 | |||
216 | for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) { | ||
217 | div = armdiv[ptr]; | ||
218 | calc = parent / div; | ||
219 | if (calc <= rate && div < best) { | ||
220 | best = div; | ||
221 | val = ptr; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | if (val >= 0) { | ||
226 | unsigned long clkcon0; | ||
227 | |||
228 | clkcon0 = __raw_readl(S3C2443_CLKDIV0); | ||
229 | clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK; | ||
230 | clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT; | ||
231 | __raw_writel(clkcon0, S3C2443_CLKDIV0); | ||
232 | } | ||
233 | |||
234 | return (val == -1) ? -EINVAL : 0; | ||
235 | } | ||
236 | |||
168 | static struct clk clk_armdiv = { | 237 | static struct clk clk_armdiv = { |
169 | .name = "armdiv", | 238 | .name = "armdiv", |
170 | .id = -1, | 239 | .id = -1, |
171 | .parent = &clk_msysclk.clk, | 240 | .parent = &clk_msysclk.clk, |
241 | .ops = &(struct clk_ops) { | ||
242 | .round_rate = s3c2443_armclk_roundrate, | ||
243 | .set_rate = s3c2443_armclk_setrate, | ||
244 | }, | ||
172 | }; | 245 | }; |
173 | 246 | ||
174 | /* armclk | 247 | /* armclk |
@@ -619,26 +692,6 @@ static void __init s3c2443_clk_initparents(void) | |||
619 | s3c_set_clksrc(init_list[ptr], true); | 692 | s3c_set_clksrc(init_list[ptr], true); |
620 | } | 693 | } |
621 | 694 | ||
622 | /* armdiv divisor table */ | ||
623 | |||
624 | static unsigned int armdiv[16] = { | ||
625 | [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, | ||
626 | [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, | ||
627 | [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3, | ||
628 | [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4, | ||
629 | [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6, | ||
630 | [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8, | ||
631 | [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12, | ||
632 | [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16, | ||
633 | }; | ||
634 | |||
635 | static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0) | ||
636 | { | ||
637 | clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK; | ||
638 | |||
639 | return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; | ||
640 | } | ||
641 | |||
642 | static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) | 695 | static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) |
643 | { | 696 | { |
644 | clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; | 697 | clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; |