|
|
1.1 root 1: /*
2: * OpenBIOS native timer driver
3: *
4: * (C) 2004 Stefan Reinauer <[email protected]>
5: *
6: * This program is free software; you can redistribute it and/or
7: * modify it under the terms of the GNU General Public License
8: * version 2
9: *
10: */
11:
12: #include "config.h"
13: #include "drivers/drivers.h"
14: #include "timer.h"
15: #include "asm/io.h"
16:
17: #if defined(CONFIG_X86) || defined(CONFIG_AMD64)
18:
19: void setup_timers(void)
20: {
21: /* nothing to do */
22: }
23:
24: static void load_timer2(unsigned int ticks)
25: {
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,
29: TIMER_MODE_PORT);
30: outb(ticks & 0xFF, TIMER2_PORT);
31: outb(ticks >> 8, TIMER2_PORT);
32: }
33:
34: void udelay(unsigned int usecs)
35: {
36: load_timer2((usecs * TICKS_PER_MS) / 1000);
37: while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
38: }
39:
40: unsigned long currticks(void)
41: {
42: static unsigned long totticks = 0UL; /* High resolution */
43: unsigned long ticks = 0;
44: unsigned char portb = inb(PPC_PORTB);
45:
46: /*
47: * Read the timer, and hope it hasn't wrapped around
48: * (call this again within 54ms), then restart it
49: */
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,
54: TIMER_MODE_PORT);
55: outb(0, TIMER2_PORT);
56: outb(0, TIMER2_PORT);
57:
58: /*
59: * Check if the timer was running. If not,
60: * result is rubbish and need to start it
61: */
62: if (portb & PPCB_T2GATE) {
63: totticks += (0x10000 - ticks);
64: } else {
65: /* Set up the timer gate, turn off the speaker */
66: outb((portb & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB);
67: }
68: return totticks / TICKS_PER_MS;
69: }
70: #endif
71:
72: #ifdef CONFIG_PPC
73:
74: void setup_timers(void)
75: {
76: /* nothing to do */
77: }
78:
79: /*
80: * TODO: pass via lb table
81: */
82:
83: unsigned long get_timer_freq(void)
84: {
85: return 10000000 / 4;
86: }
87:
88: void udelay(unsigned int usecs)
89: {
90: unsigned long ticksperusec = get_timer_freq() / 1000000;
91: _wait_ticks(ticksperusec * usecs);
92: }
93:
94: #endif
95:
96: void ndelay(unsigned int nsecs)
97: {
98: udelay((nsecs + 999) / 1000);
99: }
100:
101: void mdelay(unsigned int msecs)
102: {
103: udelay(msecs * 1000);
104: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.