diff options
author | Graeme Russ <graeme.russ@gmail.com> | 2009-02-24 21:14:45 +1100 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2009-03-20 22:39:13 +0100 |
commit | 8c63d47651f77d9fb887cad433370b866eb0a193 (patch) | |
tree | 3b1462085a3aceec7390c05e7ab8184124967d14 /cpu/i386/sc520 | |
parent | 6d7f610b09f813b1239eedcbfe921cfd439aea25 (diff) | |
download | u-boot-imx-8c63d47651f77d9fb887cad433370b866eb0a193.zip u-boot-imx-8c63d47651f77d9fb887cad433370b866eb0a193.tar.gz u-boot-imx-8c63d47651f77d9fb887cad433370b866eb0a193.tar.bz2 |
Implement SC520 timers
Signed-off-by: Graeme Russ <graeme.russ at gmail.com>
Diffstat (limited to 'cpu/i386/sc520')
-rw-r--r-- | cpu/i386/sc520/sc520_timer.c | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/cpu/i386/sc520/sc520_timer.c b/cpu/i386/sc520/sc520_timer.c index 7578511..2cb8656 100644 --- a/cpu/i386/sc520/sc520_timer.c +++ b/cpu/i386/sc520/sc520_timer.c @@ -27,47 +27,56 @@ #include <asm/interrupt.h> #include <asm/ic/sc520.h> -void reset_timer(void) +void sc520_timer_isr(void) { - write_mmcr_word(SC520_GPTMR0CNT, 0); - write_mmcr_word(SC520_GPTMR0CTL, 0x6001); - + /* Ack the GP Timer Interrupt */ + write_mmcr_byte (SC520_GPTMRSTA, 0x02); } -ulong get_timer(ulong base) +int timer_init(void) { - /* fixme: 30 or 33 */ - return read_mmcr_word(SC520_GPTMR0CNT) / 33; -} + /* Map GP Timer 1 to Master PIC IR0 */ + write_mmcr_byte (SC520_GPTMR1MAP, 0x01); -void set_timer(ulong t) -{ - /* FixMe: use two cascade coupled timers */ - write_mmcr_word(SC520_GPTMR0CTL, 0x4001); - write_mmcr_word(SC520_GPTMR0CNT, t*33); - write_mmcr_word(SC520_GPTMR0CTL, 0x6001); -} + /* Disable GP Timers 1 & 2 - Allow configuration writes */ + write_mmcr_word (SC520_GPTMR1CTL, 0x4000); + write_mmcr_word (SC520_GPTMR2CTL, 0x4000); + + /* Reset GP Timers 1 & 2 */ + write_mmcr_word (SC520_GPTMR1CNT, 0x0000); + write_mmcr_word (SC520_GPTMR2CNT, 0x0000); + + /* Setup GP Timer 2 as a 100kHz (10us) prescaler */ + write_mmcr_word (SC520_GPTMR2MAXCMPA, 83); + write_mmcr_word (SC520_GPTMR2CTL, 0xc001); + + /* Setup GP Timer 1 as a 1000 Hz (1ms) interrupt generator */ + write_mmcr_word (SC520_GPTMR1MAXCMPA, 100); + write_mmcr_word (SC520_GPTMR1CTL, 0xe009); + /* Clear the GP Timers status register */ + write_mmcr_byte (SC520_GPTMRSTA, 0x07); + + /* Register the SC520 specific timer interrupt handler */ + register_timer_isr (sc520_timer_isr); + + /* Install interrupt handler for GP Timer 1 */ + irq_install_handler (0, timer_isr, NULL); + unmask_irq (0); + + return 0; +} void udelay(unsigned long usec) { - int m=0; + int m = 0; long u; - read_mmcr_word(SC520_SWTMRMILLI); - read_mmcr_word(SC520_SWTMRMICRO); - -#if 0 - /* do not enable this line, udelay is used in the serial driver -> recursion */ - printf("udelay: %ld m.u %d.%d tm.tu %d.%d\n", usec, m, u, tm, tu); -#endif - while (1) { - - m += read_mmcr_word(SC520_SWTMRMILLI); - u = read_mmcr_word(SC520_SWTMRMICRO) + (m * 1000); + read_mmcr_word (SC520_SWTMRMILLI); + read_mmcr_word (SC520_SWTMRMICRO); - if (usec <= u) { - break; - } - } + do { + m += read_mmcr_word (SC520_SWTMRMILLI); + u = read_mmcr_word (SC520_SWTMRMICRO) + (m * 1000); + } while (u < usec); } |