1 /* Calypso DBB internal Timer Driver */
3 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <calypso/timer.h>
28 #include <calypso/irq.h>
30 #define BASE_ADDR_TIMER 0xfffe3800
31 #define TIMER2_OFFSET 0x3000
33 #define TIMER_REG(n, m) (((n)-1) ? (BASE_ADDR_TIMER + TIMER2_OFFSET + (m)) : (BASE_ADDR_TIMER + (m)))
42 CNTL_START = (1 << 0),
43 CNTL_AUTO_RELOAD = (1 << 1),
44 CNTL_CLOCK_ENABLE = (1 << 5),
47 /* Regular Timers (1 and 2) */
49 void hwtimer_enable(int num, int on)
53 if (num < 1 || num > 2) {
54 printf("Unknown timer %u\n", num);
58 ctl = readb(TIMER_REG(num, CNTL_TIMER));
60 ctl |= CNTL_START|CNTL_CLOCK_ENABLE;
63 writeb(ctl, TIMER_REG(num, CNTL_TIMER));
66 void hwtimer_config(int num, uint8_t pre_scale, int auto_reload)
70 ctl = (pre_scale & 0x7) << 2;
72 ctl |= CNTL_AUTO_RELOAD;
74 writeb(ctl, TIMER_REG(num, CNTL_TIMER));
77 void hwtimer_load(int num, uint16_t val)
79 writew(val, TIMER_REG(num, LOAD_TIMER));
82 uint16_t hwtimer_read(int num)
84 uint8_t ctl = readb(TIMER_REG(num, CNTL_TIMER));
86 /* somehow a read results in an abort */
87 if ((ctl & (CNTL_START|CNTL_CLOCK_ENABLE)) != (CNTL_START|CNTL_CLOCK_ENABLE))
89 return readw(TIMER_REG(num, READ_TIMER));
92 void hwtimer_init(void)
94 writeb(CNTL_CLOCK_ENABLE, TIMER_REG(1, CNTL_TIMER));
95 writeb(CNTL_CLOCK_ENABLE, TIMER_REG(2, CNTL_TIMER));
100 #define BASE_ADDR_WDOG 0xfffff800
101 #define WDOG_REG(m) (BASE_ADDR_WDOG + m)
104 WD_CNTL_TIMER = CNTL_TIMER,
105 WD_LOAD_TIMER = LOAD_TIMER,
106 WD_READ_TIMER = 0x02,
110 static void wdog_irq(enum irq_nr nr)
112 puts("=> WATCHDOG\n");
115 void wdog_enable(int on)
118 irq_config(IRQ_WATCHDOG, 0, 0, 0);
119 irq_register_handler(IRQ_WATCHDOG, &wdog_irq);
120 irq_enable(IRQ_WATCHDOG);
121 writew(0x8000, WDOG_REG(WD_MODE));
123 writew(0xF5, WDOG_REG(WD_MODE));
124 writew(0xA0, WDOG_REG(WD_MODE));