From dbc861c5f0115ec673be2a7c6837d19dc9e3c4c1 Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Sun, 5 Aug 2012 20:47:54 -0700 Subject: add a function to fast forward system timer When we wake up from a deep sleep mode, the system timer clock might have been stopped. We need to be able to set using another time source (e.g. the RTC). Signed-off-by: Vincent Palatin BUG=chrome-os-partner:8866 TEST=make BOARD=snow && make BOARD=link on Snow, on a software implementing STOP mode, check the system time is still accurate by comparing it to the wall clock. Change-Id: Ieddbb423d052c7aceb398470866b25b25a74c0a0 Reviewed-on: https://gerrit.chromium.org/gerrit/29314 Reviewed-by: Randall Spangler Commit-Ready: Vincent Palatin Tested-by: Vincent Palatin --- chip/lm4/hwtimer.c | 8 +++++++- chip/stm32/hwtimer.c | 9 +++++++-- core/cortex-m/timer.c | 8 ++++++++ include/hwtimer.h | 3 +++ include/timer.h | 8 ++++++++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/chip/lm4/hwtimer.c b/chip/lm4/hwtimer.c index b3c8498294..9c23cbf961 100644 --- a/chip/lm4/hwtimer.c +++ b/chip/lm4/hwtimer.c @@ -42,6 +42,12 @@ uint32_t __hw_clock_source_read(void) } +void __hw_clock_source_set(uint32_t ts) +{ + LM4_TIMER_TAV(6) = 0xffffffff - ts; +} + + static void __hw_clock_source_irq(void) { uint32_t status = LM4_TIMER_RIS(6); @@ -99,7 +105,7 @@ int __hw_clock_source_init(uint32_t start_t) LM4_TIMER_CTL(6) |= 0x1; /* Override the count with the start value now that counting has * started. */ - LM4_TIMER_TAV(6) = 0xffffffff - start_t; + __hw_clock_source_set(start_t); /* Enable interrupt */ task_enable_irq(LM4_IRQ_TIMERW0A); diff --git a/chip/stm32/hwtimer.c b/chip/stm32/hwtimer.c index f43a444088..1dbf2b5606 100644 --- a/chip/stm32/hwtimer.c +++ b/chip/stm32/hwtimer.c @@ -84,6 +84,12 @@ uint32_t __hw_clock_source_read(void) return (hi << 16) | lo; } +void __hw_clock_source_set(uint32_t ts) +{ + STM32_TIM_CNT(3) = ts >> 16; + STM32_TIM_CNT(4) = ts & 0xffff; +} + static void __hw_clock_source_irq(void) { uint32_t stat_tim3 = STM32_TIM_SR(3); @@ -147,8 +153,7 @@ int __hw_clock_source_init(uint32_t start_t) /* Override the count with the start value now that counting has * started. */ - STM32_TIM_CNT(3) = start_t >> 16; - STM32_TIM_CNT(4) = start_t & 0xffff; + __hw_clock_source_set(start_t); /* Enable timer interrupts */ task_enable_irq(STM32_IRQ_TIM3); diff --git a/core/cortex-m/timer.c b/core/cortex-m/timer.c index 994f9c1245..10370aeeb6 100644 --- a/core/cortex-m/timer.c +++ b/core/cortex-m/timer.c @@ -169,6 +169,14 @@ timestamp_t get_time(void) } +void force_time(timestamp_t ts) +{ + clksrc_high = ts.le.hi; + __hw_clock_source_set(ts.le.lo); + /* some timers might be already expired : process them */ + task_trigger_irq(timer_irq); +} + void timer_print_info(void) { uint64_t t = get_time().val; diff --git a/include/hwtimer.h b/include/hwtimer.h index fdf1d94852..b9b2270fd6 100644 --- a/include/hwtimer.h +++ b/include/hwtimer.h @@ -52,6 +52,9 @@ void __hw_clock_event_clear(void); /* Returns the value of the free-running counter used as clock. */ uint32_t __hw_clock_source_read(void); +/* Override the current value of the hardware counter */ +void __hw_clock_source_set(uint32_t ts); + /** * Initializes the hardware timer used to provide clock services, using the * specified start timer value. diff --git a/include/timer.h b/include/timer.h index d3a4989e05..0a4273ff25 100644 --- a/include/timer.h +++ b/include/timer.h @@ -53,6 +53,14 @@ void usleep(unsigned us); /* Get the current timestamp from the system timer. */ timestamp_t get_time(void); +/* Force the current value of the system timer. + * + * This function is for the power management implementation which wants to fix + * the system time when waking up from a mode with clocks turned off. + * Note: must be called with interrupts disabled. + */ +void force_time(timestamp_t ts); + /* Print the current timer information using the command output channel. This * may be called from interrupt level. */ void timer_print_info(void); -- cgit v1.2.1