aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-01-26 09:41:16 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2009-03-13 05:33:46 -0400
commita2865197a5dad23c619c84f44b7fdf7fdbef3f9c (patch)
treee62afa2bf72a8bad1cbfd400f79b92a13617fac6 /arch/arm/plat-mxc
parent5512e88f3a1f1b498fd07181f14596ee117b3471 (diff)
[ARM] MXC: Use a single function for decoding a PLL
We had 3 versions of this function in clock support for MX1/2/3 Use a single one instead. I picked the one from the MX3 as it seems to calculate more accurate as the other ones. Also, on MX27 and MX31 mfn can be negative, this hasn't been handled correctly on MX27 since now. This patch has been tested on MX27 and MX31 and produces the same clock frequencies for me. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/plat-mxc')
-rw-r--r--arch/arm/plat-mxc/clock.c44
-rw-r--r--arch/arm/plat-mxc/include/mach/clock.h2
2 files changed, 46 insertions, 0 deletions
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 0a38f0b396eb..888dd33abf76 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -328,3 +328,47 @@ static int __init mxc_setup_proc_entry(void)
328 328
329late_initcall(mxc_setup_proc_entry); 329late_initcall(mxc_setup_proc_entry);
330#endif 330#endif
331
332/*
333 * Get the resulting clock rate from a PLL register value and the input
334 * frequency. PLLs with this register layout can at least be found on
335 * MX1, MX21, MX27 and MX31
336 *
337 * mfi + mfn / (mfd + 1)
338 * f = 2 * f_ref * --------------------
339 * pd + 1
340 */
341unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
342{
343 long long ll;
344 int mfn_abs;
345 unsigned int mfi, mfn, mfd, pd;
346
347 mfi = (reg_val >> 10) & 0xf;
348 mfn = reg_val & 0x3ff;
349 mfd = (reg_val >> 16) & 0x3ff;
350 pd = (reg_val >> 26) & 0xf;
351
352 mfi = mfi <= 5 ? 5 : mfi;
353
354 mfn_abs = mfn;
355
356#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
357 if (mfn >= 0x200) {
358 mfn |= 0xFFFFFE00;
359 mfn_abs = -mfn;
360 }
361#endif
362
363 freq *= 2;
364 freq /= pd + 1;
365
366 ll = (unsigned long long)freq * mfn_abs;
367
368 do_div(ll, mfd + 1);
369 if (mfn < 0)
370 ll = -ll;
371 ll = (freq * mfi) + ll;
372
373 return ll;
374}
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index d21f78e78819..b830655514eb 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -63,5 +63,7 @@ struct clk {
63int clk_register(struct clk *clk); 63int clk_register(struct clk *clk);
64void clk_unregister(struct clk *clk); 64void clk_unregister(struct clk *clk);
65 65
66unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
67
66#endif /* __ASSEMBLY__ */ 68#endif /* __ASSEMBLY__ */
67#endif /* __ASM_ARCH_MXC_CLOCK_H__ */ 69#endif /* __ASM_ARCH_MXC_CLOCK_H__ */