aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-12-04 14:42:09 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-12-07 11:06:55 -0500
commit2dc20a51dc1e2da6eae1182cfe4c4835fca26017 (patch)
tree206a73320b1d41451884f0ca5d0796af9a34c50e /arch/arm
parent752bee178ee107aa3dd87a9aeba970444034c6fb (diff)
[ARM] 3981/1: sched_clock for PXA2xx
Here's a 63-bit implementation of shed_clock() for PXA2xx. The actual period depends on the value of CLOCK_TICK_RATE and whether or not reduced scaling factors were provided for it. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-pxa/generic.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 45fb2c3bcf82..6ae605857ca9 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -25,6 +25,10 @@
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/string.h> 26#include <linux/string.h>
27 27
28#include <linux/sched.h>
29#include <asm/cnt32_to_63.h>
30#include <asm/div64.h>
31
28#include <asm/hardware.h> 32#include <asm/hardware.h>
29#include <asm/irq.h> 33#include <asm/irq.h>
30#include <asm/system.h> 34#include <asm/system.h>
@@ -41,6 +45,62 @@
41#include "generic.h" 45#include "generic.h"
42 46
43/* 47/*
48 * This is the PXA2xx sched_clock implementation. This has a resolution
49 * of at least 308ns and a maximum value that depends on the value of
50 * CLOCK_TICK_RATE.
51 *
52 * The return value is guaranteed to be monotonic in that range as
53 * long as there is always less than 582 seconds between successive
54 * calls to this function.
55 */
56unsigned long long sched_clock(void)
57{
58 unsigned long long v = cnt32_to_63(OSCR);
59 /* Note: top bit ov v needs cleared unless multiplier is even. */
60
61#if CLOCK_TICK_RATE == 3686400
62 /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */
63 /* The <<1 is used to get rid of tick.hi top bit */
64 v *= 78125<<1;
65 do_div(v, 288<<1);
66#elif CLOCK_TICK_RATE == 3250000
67 /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */
68 v *= 4000;
69 do_div(v, 13);
70#elif CLOCK_TICK_RATE == 3249600
71 /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */
72 v *= 625000;
73 do_div(v, 2031);
74#else
75#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE"
76 /*
77 * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for
78 * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand
79 * years range which is nice, but with higher computation cost.
80 */
81 {
82 union {
83 unsigned long long val;
84 struct { unsigned long lo, hi; };
85 } x;
86 unsigned long long y;
87
88 x.val = v;
89 x.hi &= 0x7fffffff;
90 y = (unsigned long long)x.lo * NSEC_PER_SEC;
91 x.lo = y;
92 y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC;
93 x.hi = do_div(y, CLOCK_TICK_RATE);
94 do_div(x.val, CLOCK_TICK_RATE);
95 x.hi += y;
96 v = x.val;
97 }
98#endif
99
100 return v;
101}
102
103/*
44 * Handy function to set GPIO alternate functions 104 * Handy function to set GPIO alternate functions
45 */ 105 */
46 106