summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2012-08-05 20:47:54 -0700
committerGerrit <chrome-bot@google.com>2012-08-06 18:55:00 -0700
commitdbc861c5f0115ec673be2a7c6837d19dc9e3c4c1 (patch)
tree5f1082ee2e4c0a6bc7e75c70ea42a92c1cd5dcd7
parentd8e04f0db75a0088121981df3bd57c3dccb10945 (diff)
downloadchrome-ec-dbc861c5f0115ec673be2a7c6837d19dc9e3c4c1.tar.gz
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 <vpalatin@chromium.org> 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 <rspangler@chromium.org> Commit-Ready: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--chip/lm4/hwtimer.c8
-rw-r--r--chip/stm32/hwtimer.c9
-rw-r--r--core/cortex-m/timer.c8
-rw-r--r--include/hwtimer.h3
-rw-r--r--include/timer.h8
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);