2 * linux/arch/arm/mach-ebsa110/time.c
4 * Copyright (C) 2001 Russell King
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 #include <linux/sched.h>
11 #include <linux/init.h>
15 #define PIT_CTRL (PIT_BASE + 0x0d)
16 #define PIT_T2 (PIT_BASE + 0x09)
17 #define PIT_T1 (PIT_BASE + 0x05)
18 #define PIT_T0 (PIT_BASE + 0x01)
21 * This is the rate at which your MCLK signal toggles (in Hz)
22 * This was measured on a 10 digit frequency counter sampling
28 * This is the rate at which the PIT timers get clocked
30 #define CLKBY7 (MCLK / 7)
33 * If CLKBY7 is larger than this, then we must do software
34 * division of the timer interrupt.
43 * This is the counter value
45 #define COUNT ((CLKBY7 + (DIVISOR * HZ / 2)) / (DIVISOR * HZ))
47 extern unsigned long (*gettimeoffset)(void);
49 static unsigned long divisor;
52 * Get the time offset from the system PIT. Note that if we have missed an
53 * interrupt, then the PIT counter will roll over (ie, be negative).
54 * This actually works out to be convenient.
56 static unsigned long ebsa110_gettimeoffset(void)
58 unsigned long offset, count;
60 __raw_writeb(0x40, PIT_CTRL);
61 count = __raw_readb(PIT_T1);
62 count |= __raw_readb(PIT_T1) << 8;
65 * If count > COUNT, make the number negative.
70 offset = COUNT * (DIVISOR - divisor);
74 * `offset' is in units of timer counts. Convert
75 * offset to units of microseconds.
77 offset = offset * (1000000 / HZ) / (COUNT * DIVISOR);
82 int ebsa110_reset_timer(void)
86 /* latch and read timer 1 */
87 __raw_writeb(0x40, PIT_CTRL);
88 count = __raw_readb(PIT_T1);
89 count |= __raw_readb(PIT_T1) << 8;
93 __raw_writeb(count & 0xff, PIT_T1);
94 __raw_writeb(count >> 8, PIT_T1);
102 void __init ebsa110_setup_timer(void)
105 * Timer 1, mode 2, LSB/MSB
107 __raw_writeb(0x70, PIT_CTRL);
108 __raw_writeb(COUNT & 0xff, PIT_T1);
109 __raw_writeb(COUNT >> 8, PIT_T1);
110 divisor = DIVISOR - 1;
112 gettimeoffset = ebsa110_gettimeoffset;