[ARM] 4294/1: ns9xxx: Determine system clock from PLL register settings
authorUwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Wed, 28 Mar 2007 17:06:41 +0000 (18:06 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 21 Apr 2007 19:51:11 +0000 (20:51 +0100)
The function attribute const is abused here as the PLL register is read.  But I
think this is all right because the PLL register cannot change without a reset.

Note: This patch depends on 4293/1

Signed-off-by: Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
include/asm-arm/arch-ns9xxx/clock.h

index a7c5ab3d90116088d381f48b567d7cec191233f4..bf30cbdcc2bf2d3ec47a7a5fd519015a7c77b931 100644 (file)
 #ifndef __ASM_ARCH_CLOCK_H
 #define __ASM_ARCH_CLOCK_H
 
+#include <asm/arch-ns9xxx/regs-sys.h>
+
+#define CRYSTAL 29491200 /* Hz */
+
+/* The HRM calls this value f_vco */
 static inline u32 ns9xxx_systemclock(void) __attribute__((const));
 static inline u32 ns9xxx_systemclock(void)
 {
+       u32 pll = SYS_PLL;
+
        /*
-        * This should be a multiple of HZ * TIMERCLOCKSELECT (in time.c)
+        * The system clock should be a multiple of HZ * TIMERCLOCKSELECT (in
+        * time.c).
+        *
+        * The following values are given:
+        *   - TIMERCLOCKSELECT == 2^i for an i in {0 .. 6}
+        *   - CRYSTAL == 29491200 == 2^17 * 3^2 * 5^2
+        *   - ND in {0 .. 31}
+        *   - FS in {0 .. 3}
+        *
+        * Assuming the worst, we consider:
+        *   - TIMERCLOCKSELECT == 64
+        *   - ND == 0
+        *   - FS == 3
+        *
+        * So HZ should be a divisor of:
+        *      (CRYSTAL * (ND + 1) >> FS) / TIMERCLOCKSELECT
+        *   == (2^17 * 3^2 * 5^2 * 1 >> 3) / 64
+        *   == 2^8 * 3^2 * 5^2
+        *   == 57600
+        *
+        * Currently HZ is defined to be 100 for this platform.
+        *
+        * Fine.
         */
-       return 353894400;
+       return CRYSTAL * (REGGET(pll, SYS_PLL, ND) + 1)
+               >> REGGET(pll, SYS_PLL, FS);
 }
 
 static inline u32 ns9xxx_cpuclock(void) __attribute__((const));