2 * OpenBIOS native timer driver
4 * (C) 2004 Stefan Reinauer <stepan@openbios.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
13 #include "drivers/drivers.h"
17 #if defined(CONFIG_X86) || defined(CONFIG_AMD64)
19 void setup_timers(void)
24 static void load_timer2(unsigned int ticks
)
26 /* Set up the timer gate, turn off the speaker */
27 outb((inb(PPC_PORTB
) & ~PPCB_SPKR
) | PPCB_T2GATE
, PPC_PORTB
);
28 outb(TIMER2_SEL
| WORD_ACCESS
| MODE0
| BINARY_COUNT
,
30 outb(ticks
& 0xFF, TIMER2_PORT
);
31 outb(ticks
>> 8, TIMER2_PORT
);
34 void udelay(unsigned int usecs
)
36 load_timer2((usecs
* TICKS_PER_MS
) / 1000);
37 while ((inb(PPC_PORTB
) & PPCB_T2OUT
) == 0);
40 unsigned long currticks(void)
42 static unsigned long totticks
= 0UL; /* High resolution */
43 unsigned long ticks
= 0;
44 unsigned char portb
= inb(PPC_PORTB
);
47 * Read the timer, and hope it hasn't wrapped around
48 * (call this again within 54ms), then restart it
50 outb(TIMER2_SEL
| LATCH_COUNT
, TIMER_MODE_PORT
);
51 ticks
= inb(TIMER2_PORT
);
52 ticks
|= inb(TIMER2_PORT
) << 8;
53 outb(TIMER2_SEL
| WORD_ACCESS
| MODE0
| BINARY_COUNT
,
59 * Check if the timer was running. If not,
60 * result is rubbish and need to start it
62 if (portb
& PPCB_T2GATE
) {
63 totticks
+= (0x10000 - ticks
);
65 /* Set up the timer gate, turn off the speaker */
66 outb((portb
& ~PPCB_SPKR
) | PPCB_T2GATE
, PPC_PORTB
);
68 return totticks
/ TICKS_PER_MS
;
74 void setup_timers(void)
80 * TODO: pass via lb table
83 unsigned long get_timer_freq(void)
88 void udelay(unsigned int usecs
)
90 unsigned long ticksperusec
= get_timer_freq() / 1000000;
91 _wait_ticks(ticksperusec
* usecs
);
96 void ndelay(unsigned int nsecs
)
98 udelay((nsecs
+ 999) / 1000);
101 void mdelay(unsigned int msecs
)
103 udelay(msecs
* 1000);