diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-01-25 21:16:46 +0000 |
---|---|---|
committer | Vincent Palatin <vpalatin@chromium.org> | 2012-01-25 22:50:07 +0000 |
commit | 645dad5d3f658d7c5e0d54453964e91afe7b43c0 (patch) | |
tree | 432904125c384bc93f3792d337c08e6718fa81f3 /chip/lm4/hwtimer.c | |
parent | c89bea4a5b183f24d71277aa6b9d55c92001eda7 (diff) | |
download | chrome-ec-645dad5d3f658d7c5e0d54453964e91afe7b43c0.tar.gz |
Split the timer code between OS code and hardware dependant code.
Preparatory work to introduce a second SoC : 2/5
The hwtimer.* files implement the driver for the SoC timer block.
The timer.* files provides the OS level clock/timer functions.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=None
TEST=on BDS, check 'waitms' and 'gettime' on the EC console.
Change-Id: Icbc58d9be59ee268e2d5a94f8b20de0cabcdc91d
Diffstat (limited to 'chip/lm4/hwtimer.c')
-rw-r--r-- | chip/lm4/hwtimer.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/chip/lm4/hwtimer.c b/chip/lm4/hwtimer.c new file mode 100644 index 0000000000..9b221010c8 --- /dev/null +++ b/chip/lm4/hwtimer.c @@ -0,0 +1,91 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Hardware timers driver */ + +#include <stdint.h> + +#include "board.h" +#include "hwtimer.h" +#include "registers.h" +#include "task.h" + +#define US_PER_SECOND 1000000 + +/* Divider to get microsecond for the clock */ +#define CLOCKSOURCE_DIVIDER (CPU_CLOCK/US_PER_SECOND) + +void __hw_clock_event_set(uint32_t deadline) +{ + /* set the match on the deadline */ + LM4_TIMER_TAMATCHR(6) = 0xffffffff - deadline; + /* Set the match interrupt */ + LM4_TIMER_IMR(6) |= 0x10; +} + +uint32_t __hw_clock_event_get(void) +{ + return 0xffffffff - LM4_TIMER_TAMATCHR(6); +} + +void __hw_clock_event_clear(void) +{ + /* Disable the match interrupt */ + LM4_TIMER_IMR(6) &= ~0x10; +} + +uint32_t __hw_clock_source_read(void) +{ + return 0xffffffff - LM4_TIMER_TAV(6); +} + +static void __hw_clock_source_irq(void) +{ + uint32_t status = LM4_TIMER_RIS(6); + + /* clear interrupt */ + LM4_TIMER_ICR(6) = status; + + /* + * Find expired timers and set the new timer deadline + * get from the IRQ status if the free running counter as overflowed + */ + process_timers(status & 0x01); +} +DECLARE_IRQ(LM4_IRQ_TIMERW0A, __hw_clock_source_irq, 1); + + +int __hw_clock_source_init(void) +{ + volatile uint32_t scratch __attribute__((unused)); + + /* Use WTIMER0 (timer 6) configured as a free running counter with 1 us + * period */ + + /* Enable WTIMER0 clock */ + LM4_SYSTEM_RCGCWTIMER |= 1; + /* wait 3 clock cycles before using the module */ + scratch = LM4_SYSTEM_RCGCWTIMER; + + /* Ensure timer is disabled : TAEN = TBEN = 0 */ + LM4_TIMER_CTL(6) &= ~0x101; + /* Set overflow interrupt */ + LM4_TIMER_IMR(6) = 0x1; + /* 32-bit timer mode */ + LM4_TIMER_CFG(6) = 4; + /* set the prescaler to increment every microsecond */ + LM4_TIMER_TAPR(6) = CLOCKSOURCE_DIVIDER; + /* Periodic mode, counting down */ + LM4_TIMER_TAMR(6) = 0x22; + /* use the full 32-bits of the timer */ + LM4_TIMER_TAILR(6) = 0xffffffff; + /* Starts counting in timer A */ + LM4_TIMER_CTL(6) |= 0x1; + + /* Enable interrupt */ + task_enable_irq(LM4_IRQ_TIMERW0A); + + return LM4_IRQ_TIMERW0A; +} |