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
16 #if defined(CONFIG_X86) || defined(CONFIG_AMD64)
18 void setup_timers(void)
23 static void load_timer2(unsigned int ticks
)
25 /* Set up the timer gate, turn off the speaker */
26 outb((inb(PPC_PORTB
) & ~PPCB_SPKR
) | PPCB_T2GATE
, PPC_PORTB
);
27 outb(TIMER2_SEL
| WORD_ACCESS
| MODE0
| BINARY_COUNT
,
29 outb(ticks
& 0xFF, TIMER2_PORT
);
30 outb(ticks
>> 8, TIMER2_PORT
);
33 void udelay(unsigned int usecs
)
35 load_timer2((usecs
* TICKS_PER_MS
) / 1000);
36 while ((inb(PPC_PORTB
) & PPCB_T2OUT
) == 0);
39 unsigned long currticks(void)
41 static unsigned long totticks
= 0UL; /* High resolution */
42 unsigned long ticks
= 0;
43 unsigned char portb
= inb(PPC_PORTB
);
46 * Read the timer, and hope it hasn't wrapped around
47 * (call this again within 54ms), then restart it
49 outb(TIMER2_SEL
| LATCH_COUNT
, TIMER_MODE_PORT
);
50 ticks
= inb(TIMER2_PORT
);
51 ticks
|= inb(TIMER2_PORT
) << 8;
52 outb(TIMER2_SEL
| WORD_ACCESS
| MODE0
| BINARY_COUNT
,
58 * Check if the timer was running. If not,
59 * result is rubbish and need to start it
61 if (portb
& PPCB_T2GATE
) {
62 totticks
+= (0x10000 - ticks
);
64 /* Set up the timer gate, turn off the speaker */
65 outb((portb
& ~PPCB_SPKR
) | PPCB_T2GATE
, PPC_PORTB
);
67 return totticks
/ TICKS_PER_MS
;
73 void setup_timers(void)
79 * TODO: pass via lb table
82 unsigned long get_timer_freq(void)
87 void udelay(unsigned int usecs
)
89 extern void _wait_ticks(unsigned long);
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);