diff options
author | Mikael Pettersson <mikpe@it.uu.se> | 2009-10-29 14:46:54 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-10-29 14:46:54 -0400 |
commit | a91549a8f27e63e0e537fe1c20d4845581de894f (patch) | |
tree | 6cf4a9ecf379cc4bdaa8d988c45702135aecdaa3 | |
parent | 012abeea669ea49636cf952d13298bb68654146a (diff) |
iop: clocksource support
This updates the IOP platform to expose the free-running
timer 1 as a clocksource object. This timer is now also
properly initialised, which requires a new write_tcr1()
function from the mach-specific code. Apart from the
explicit initialisation, there is no functional change
in how timer 1 is programmed.
Tested on n2100, compile-tested for all plat-iop machines.
Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | arch/arm/include/asm/hardware/iop3xx.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/include/mach/time.h | 5 | ||||
-rw-r--r-- | arch/arm/plat-iop/time.c | 45 |
3 files changed, 55 insertions, 0 deletions
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h index 8d60ad267e3a..643b7b95b25b 100644 --- a/arch/arm/include/asm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h | |||
@@ -260,6 +260,11 @@ static inline u32 read_tcr1(void) | |||
260 | return val; | 260 | return val; |
261 | } | 261 | } |
262 | 262 | ||
263 | static inline void write_tcr1(u32 val) | ||
264 | { | ||
265 | asm volatile("mcr p6, 0, %0, c3, c1, 0" : : "r" (val)); | ||
266 | } | ||
267 | |||
263 | static inline void write_trr0(u32 val) | 268 | static inline void write_trr0(u32 val) |
264 | { | 269 | { |
265 | asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val)); | 270 | asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val)); |
diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h index d6d52527589d..9fb2768c84bb 100644 --- a/arch/arm/mach-iop13xx/include/mach/time.h +++ b/arch/arm/mach-iop13xx/include/mach/time.h | |||
@@ -90,6 +90,11 @@ static inline u32 read_tcr1(void) | |||
90 | return val; | 90 | return val; |
91 | } | 91 | } |
92 | 92 | ||
93 | static inline void write_tcr1(u32 val) | ||
94 | { | ||
95 | asm volatile("mcr p6, 0, %0, c3, c9, 0" : : "r" (val)); | ||
96 | } | ||
97 | |||
93 | static inline void write_trr0(u32 val) | 98 | static inline void write_trr0(u32 val) |
94 | { | 99 | { |
95 | asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val)); | 100 | asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val)); |
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 8da95d57c21f..5506c9b45612 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/timex.h> | 20 | #include <linux/timex.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/clocksource.h> | ||
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
23 | #include <asm/irq.h> | 24 | #include <asm/irq.h> |
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
@@ -26,6 +27,43 @@ | |||
26 | #include <asm/mach/time.h> | 27 | #include <asm/mach/time.h> |
27 | #include <mach/time.h> | 28 | #include <mach/time.h> |
28 | 29 | ||
30 | /* | ||
31 | * IOP clocksource (free-running timer 1). | ||
32 | */ | ||
33 | static cycle_t iop_clocksource_read(struct clocksource *unused) | ||
34 | { | ||
35 | return 0xffffffffu - read_tcr1(); | ||
36 | } | ||
37 | |||
38 | static struct clocksource iop_clocksource = { | ||
39 | .name = "iop_timer1", | ||
40 | .rating = 300, | ||
41 | .read = iop_clocksource_read, | ||
42 | .mask = CLOCKSOURCE_MASK(32), | ||
43 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
44 | }; | ||
45 | |||
46 | static void __init iop_clocksource_set_hz(struct clocksource *cs, unsigned int hz) | ||
47 | { | ||
48 | u64 temp; | ||
49 | u32 shift; | ||
50 | |||
51 | /* Find shift and mult values for hz. */ | ||
52 | shift = 32; | ||
53 | do { | ||
54 | temp = (u64) NSEC_PER_SEC << shift; | ||
55 | do_div(temp, hz); | ||
56 | if ((temp >> 32) == 0) | ||
57 | break; | ||
58 | } while (--shift != 0); | ||
59 | |||
60 | cs->shift = shift; | ||
61 | cs->mult = (u32) temp; | ||
62 | |||
63 | printk(KERN_INFO "clocksource: %s uses shift %u mult %#x\n", | ||
64 | cs->name, cs->shift, cs->mult); | ||
65 | } | ||
66 | |||
29 | static unsigned long ticks_per_jiffy; | 67 | static unsigned long ticks_per_jiffy; |
30 | static unsigned long ticks_per_usec; | 68 | static unsigned long ticks_per_usec; |
31 | static unsigned long next_jiffy_time; | 69 | static unsigned long next_jiffy_time; |
@@ -99,8 +137,15 @@ void __init iop_init_time(unsigned long tick_rate) | |||
99 | */ | 137 | */ |
100 | write_trr0(ticks_per_jiffy - 1); | 138 | write_trr0(ticks_per_jiffy - 1); |
101 | write_tmr0(timer_ctl); | 139 | write_tmr0(timer_ctl); |
140 | |||
141 | /* | ||
142 | * Set up free-running clocksource timer 1. | ||
143 | */ | ||
102 | write_trr1(0xffffffff); | 144 | write_trr1(0xffffffff); |
145 | write_tcr1(0xffffffff); | ||
103 | write_tmr1(timer_ctl); | 146 | write_tmr1(timer_ctl); |
147 | iop_clocksource_set_hz(&iop_clocksource, tick_rate); | ||
148 | clocksource_register(&iop_clocksource); | ||
104 | 149 | ||
105 | setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); | 150 | setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); |
106 | } | 151 | } |