summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2003-01-27 00:10:48 +0000
committerRussell King <rmk@flint.arm.linux.org.uk>2003-01-27 00:10:48 +0000
commitaa2cbc19b92e37e54e5af342699e2bc51e67c1dc (patch)
treef215384b3f1c02b3a41b4e18cc4496644aff2ae5 /include
parentbc870c88cafc75983907f5e95184d74537777d1b (diff)
[ARM] Remove 200Hz -> 100Hz conversion for ebsa110 timer.
We now really run the ebsa110 kernel timer at 200Hz, and convert where necessary to 100Hz for user space.
Diffstat (limited to 'include')
-rw-r--r--include/asm-arm/arch-ebsa110/param.h1
-rw-r--r--include/asm-arm/arch-ebsa110/time.h86
2 files changed, 79 insertions, 8 deletions
diff --git a/include/asm-arm/arch-ebsa110/param.h b/include/asm-arm/arch-ebsa110/param.h
index f077b717193d..13a9fc1b7a25 100644
--- a/include/asm-arm/arch-ebsa110/param.h
+++ b/include/asm-arm/arch-ebsa110/param.h
@@ -1,3 +1,4 @@
/*
* linux/include/asm-arm/arch-ebsa110/param.h
*/
+#define __KERNEL_HZ 200
diff --git a/include/asm-arm/arch-ebsa110/time.h b/include/asm-arm/arch-ebsa110/time.h
index 278c8e3632a1..30c90e607546 100644
--- a/include/asm-arm/arch-ebsa110/time.h
+++ b/include/asm-arm/arch-ebsa110/time.h
@@ -17,17 +17,80 @@
*/
#include <asm/leds.h>
+#include <asm/io.h>
-extern int ebsa110_reset_timer(void);
-extern void ebsa110_setup_timer(void);
+extern unsigned long (*gettimeoffset)(void);
+
+#define PIT_CTRL (PIT_BASE + 0x0d)
+#define PIT_T2 (PIT_BASE + 0x09)
+#define PIT_T1 (PIT_BASE + 0x05)
+#define PIT_T0 (PIT_BASE + 0x01)
+
+/*
+ * This is the rate at which your MCLK signal toggles (in Hz)
+ * This was measured on a 10 digit frequency counter sampling
+ * over 1 second.
+ */
+#define MCLK 47894000
+
+/*
+ * This is the rate at which the PIT timers get clocked
+ */
+#define CLKBY7 (MCLK / 7)
+
+/*
+ * This is the counter value. We tick at 200Hz on this platform.
+ */
+#define COUNT ((CLKBY7 + (HZ / 2)) / HZ)
+
+/*
+ * Get the time offset from the system PIT. Note that if we have missed an
+ * interrupt, then the PIT counter will roll over (ie, be negative).
+ * This actually works out to be convenient.
+ */
+static unsigned long ebsa110_gettimeoffset(void)
+{
+ unsigned long offset, count;
+
+ __raw_writeb(0x40, PIT_CTRL);
+ count = __raw_readb(PIT_T1);
+ count |= __raw_readb(PIT_T1) << 8;
+
+ /*
+ * If count > COUNT, make the number negative.
+ */
+ if (count > COUNT)
+ count |= 0xffff0000;
+
+ offset = COUNT;
+ offset -= count;
+
+ /*
+ * `offset' is in units of timer counts. Convert
+ * offset to units of microseconds.
+ */
+ offset = offset * (1000000 / HZ) / COUNT;
+
+ return offset;
+}
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- if (ebsa110_reset_timer()) {
- do_leds();
- do_timer(regs);
- do_profile(regs);
- }
+ u32 count;
+
+ /* latch and read timer 1 */
+ __raw_writeb(0x40, PIT_CTRL);
+ count = __raw_readb(PIT_T1);
+ count |= __raw_readb(PIT_T1) << 8;
+
+ count += COUNT;
+
+ __raw_writeb(count & 0xff, PIT_T1);
+ __raw_writeb(count >> 8, PIT_T1);
+
+ do_leds();
+ do_timer(regs);
+ do_profile(regs);
}
/*
@@ -35,7 +98,14 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
void __init time_init(void)
{
- ebsa110_setup_timer();
+ /*
+ * Timer 1, mode 2, LSB/MSB
+ */
+ __raw_writeb(0x70, PIT_CTRL);
+ __raw_writeb(COUNT & 0xff, PIT_T1);
+ __raw_writeb(COUNT >> 8, PIT_T1);
+
+ gettimeoffset = ebsa110_gettimeoffset;
timer_irq.handler = timer_interrupt;