aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2443
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2010-01-30 04:14:14 -0500
committerBen Dooks <ben-linux@fluff.org>2010-03-07 17:56:13 -0500
commit41f23a09f32124322dc41bea7f65baff6e9b0ac5 (patch)
treea4946823b836a2dc8c63c5dea3961b083ece28fc /arch/arm/mach-s3c2443
parent71ed587d4a5d377ef5a6917043543ff949ff7dcf (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.c93
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
170static 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
181static 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
188static 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
207static 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
168static struct clk clk_armdiv = { 237static 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
624static 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
635static 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
642static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) 695static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
643{ 696{
644 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; 697 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;