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 | } |
