aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-pxa/generic.c62
-rw-r--r--arch/arm/mach-pxa/time.c39
2 files changed, 39 insertions, 62 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 5510f6fdce55..9d6a2c00d762 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -25,10 +25,6 @@
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
32#include <asm/hardware.h> 28#include <asm/hardware.h>
33#include <asm/irq.h> 29#include <asm/irq.h>
34#include <asm/system.h> 30#include <asm/system.h>
@@ -47,64 +43,6 @@
47#include "generic.h" 43#include "generic.h"
48 44
49/* 45/*
50 * This is the PXA2xx sched_clock implementation. This has a resolution
51 * of at least 308ns and a maximum value that depends on the value of
52 * CLOCK_TICK_RATE.
53 *
54 * The return value is guaranteed to be monotonic in that range as
55 * long as there is always less than 582 seconds between successive
56 * calls to this function.
57 */
58unsigned long long sched_clock(void)
59{
60 unsigned long long v = cnt32_to_63(OSCR);
61 /* Note: top bit ov v needs cleared unless multiplier is even. */
62
63#if CLOCK_TICK_RATE == 3686400
64 /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */
65 /* The <<1 is used to get rid of tick.hi top bit */
66 v *= 78125<<1;
67 do_div(v, 288<<1);
68#elif CLOCK_TICK_RATE == 3250000
69 /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */
70 v *= 4000;
71 do_div(v, 13);
72#elif CLOCK_TICK_RATE == 3249600
73 /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */
74 v *= 625000;
75 do_div(v, 2031);
76#else
77#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE"
78 /*
79 * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for
80 * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand
81 * years range and truncation to unsigned long long limits it to
82 * sched_clock's max range of ~584 years. This is nice but with
83 * higher computation cost.
84 */
85 {
86 union {
87 unsigned long long val;
88 struct { unsigned long lo, hi; };
89 } x;
90 unsigned long long y;
91
92 x.val = v;
93 x.hi &= 0x7fffffff;
94 y = (unsigned long long)x.lo * NSEC_PER_SEC;
95 x.lo = y;
96 y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC;
97 x.hi = do_div(y, CLOCK_TICK_RATE);
98 do_div(x.val, CLOCK_TICK_RATE);
99 x.hi += y;
100 v = x.val;
101 }
102#endif
103
104 return v;
105}
106
107/*
108 * Handy function to set GPIO alternate functions 46 * Handy function to set GPIO alternate functions
109 */ 47 */
110 48
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 98d27e646b09..7916311547ca 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -16,11 +16,48 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/clockchips.h> 18#include <linux/clockchips.h>
19#include <linux/sched.h>
19 20
21#include <asm/div64.h>
22#include <asm/cnt32_to_63.h>
20#include <asm/mach/irq.h> 23#include <asm/mach/irq.h>
21#include <asm/mach/time.h> 24#include <asm/mach/time.h>
22#include <asm/arch/pxa-regs.h> 25#include <asm/arch/pxa-regs.h>
23 26
27/*
28 * This is PXA's sched_clock implementation. This has a resolution
29 * of at least 308 ns and a maximum value of 208 days.
30 *
31 * The return value is guaranteed to be monotonic in that range as
32 * long as there is always less than 582 seconds between successive
33 * calls to sched_clock() which should always be the case in practice.
34 */
35
36#define OSCR2NS_SCALE_FACTOR 10
37
38static unsigned long oscr2ns_scale;
39
40static void __init set_oscr2ns_scale(unsigned long oscr_rate)
41{
42 unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR;
43 do_div(v, oscr_rate);
44 oscr2ns_scale = v;
45 /*
46 * We want an even value to automatically clear the top bit
47 * returned by cnt32_to_63() without an additional run time
48 * instruction. So if the LSB is 1 then round it up.
49 */
50 if (oscr2ns_scale & 1)
51 oscr2ns_scale++;
52}
53
54unsigned long long sched_clock(void)
55{
56 unsigned long long v = cnt32_to_63(OSCR);
57 return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
58}
59
60
24static irqreturn_t 61static irqreturn_t
25pxa_ost0_interrupt(int irq, void *dev_id) 62pxa_ost0_interrupt(int irq, void *dev_id)
26{ 63{
@@ -152,6 +189,8 @@ static void __init pxa_timer_init(void)
152 OIER = 0; 189 OIER = 0;
153 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; 190 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
154 191
192 set_oscr2ns_scale(CLOCK_TICK_RATE);
193
155 ckevt_pxa_osmr0.mult = 194 ckevt_pxa_osmr0.mult =
156 div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); 195 div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
157 ckevt_pxa_osmr0.max_delta_ns = 196 ckevt_pxa_osmr0.max_delta_ns =