diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2016-07-11 12:38:18 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-07-19 18:34:03 -0700 |
commit | aa471f87480cb0aa0e6a89df3180fdd15f5a6df5 (patch) | |
tree | 8cb88ae6f10eabce85c08c8eac870639e0e04685 | |
parent | 27f6bf27625c717ba42722efcfca47c23207bb21 (diff) | |
download | chrome-ec-aa471f87480cb0aa0e6a89df3180fdd15f5a6df5.tar.gz |
it83xx: Fix timer observation register latch issue
This workaround ensure that we can successfully get
register latch.
Signed-off-by: Dino Li <dino.li@ite.com.tw>
BRANCH=none
BUG=chrome-os-partner:55044
TEST=We simulate the delay time between first and second read,
and prove this method can avoid latch fail.
Change-Id: I7cafb53a8efbb2eee09af29d7365806dc0deb762
Reviewed-on: https://chromium-review.googlesource.com/358730
Commit-Ready: Dino Li <Dino.Li@ite.com.tw>
Tested-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | chip/it83xx/hwtimer.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/chip/it83xx/hwtimer.c b/chip/it83xx/hwtimer.c index aa21092e40..fd081c4092 100644 --- a/chip/it83xx/hwtimer.c +++ b/chip/it83xx/hwtimer.c @@ -96,13 +96,47 @@ static void event_timer_clear_pending_isr(void) task_clear_pending_irq(et_ctrl_regs[EVENT_EXT_TIMER].irq); } -uint32_t __hw_clock_source_read(void) +uint32_t __ram_code __hw_clock_source_read(void) { +#if 0 /* * In combinational mode, the counter observation register of * timer 4(TIMER_H) will increment. */ return IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H); +#else +/* Number of CPU cycles in 125 us */ +#define CYCLES_125NS (125*(PLL_CLOCK/SECOND) / 1000) + /* + * TODO(crosbug.com/p/55044): + * observation register of external timer latch issue. + * we can remove this workaround after version change. + */ + uint32_t prev_mask = get_int_mask(); + uint32_t val; + + interrupt_disable(); + asm volatile( + /* read observation register for the first time */ + "lwi %0,[%1]\n\t" + /* + * the delay time between reading the first and second + * observation registers need to be greater than 0.125us and + * smaller than 0.250us. + */ + ".rept %2\n\t" + "nop\n\t" + ".endr\n\t" + /* read for the second time */ + "lwi %0,[%1]\n\t" + : "=&r"(val) + : "r"((uintptr_t) &IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H)), + "i"(CYCLES_125NS)); + /* restore interrupts */ + set_int_mask(prev_mask); + + return val; +#endif } void __hw_clock_source_set(uint32_t ts) |