nuc: Get more accurate value of deep idle time.

We should consider the interval between the calling __hw_clock_event_set and
entering deep idle. In order to get more accurate value of deep idle time, FW
should record the time-stamp before entering deep idle and calculate the deep
idle time based on it.

Modified drivers:
1. hwtimer_chip.h: Add new function declarations for deep idle time caculation.
2. hwtimer.c: Add new functionsfor deep idle time caculation.
3. clock.c: Modified for calculating more accurate deep idle time.

BUG=chrome-os-partner:34346
TEST=make buildall -j; test nuvoton IC specific drivers
BRANCH=none

Change-Id: Id037c4dc3564659e4ad493f2fc3ffc5d06c18b06
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/320071
Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Mulin Chao
2015-12-30 10:16:40 +08:00
committed by chrome-bot
parent c6773e6765
commit 3d752a3bf6
3 changed files with 21 additions and 8 deletions

View File

@@ -234,7 +234,7 @@ void __idle(void)
#else
timestamp_t t0, t1;
uint32_t next_evt_us;
uint32_t next_evt_us, evt_count;
/*
* Initialize console in use to true and specify the console expire
@@ -272,13 +272,17 @@ void __idle(void)
NPCX_PMCSR = IDLE_PARAMS;
/* UART-rx(console) become to GPIO (NONE INT mode) */
clock_uart2gpio();
/* Get current counter value of event timer */
evt_count = __hw_clock_event_count();
/* Enter deep idle */
asm("wfi");
/* Get time delay cause of deep idle */
next_evt_us = __hw_clock_get_sleep_time(evt_count);
/* GPIO back to UART-rx (console) */
clock_gpio2uart();
/* Get time delay cause of deep idle */
next_evt_us = __hw_clock_get_sleep_time();
/* Fast forward timer according to wake-up timer. */
t1.val = t0.val + next_evt_us;
/* Record time spent in deep sleep. */

View File

@@ -108,8 +108,14 @@ uint32_t __hw_clock_event_get(void)
return evt_expired_us;
}
/* Get current counter value of event timer */
uint32_t __hw_clock_event_count(void)
{
return NPCX_ITCNT16(ITIM_EVENT_NO);
}
/* Returns time delay cause of deep idle */
uint32_t __hw_clock_get_sleep_time(void)
uint32_t __hw_clock_get_sleep_time(uint32_t pre_evt_cnt)
{
fp_t evt_tick = FLOAT_TO_FP(SECOND/(float)INT_32K_CLOCK);
uint32_t sleep_time;
@@ -118,10 +124,10 @@ uint32_t __hw_clock_get_sleep_time(void)
interrupt_disable();
/* Event has been triggered but timer ISR dosen't handle it */
if (IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_TO_STS))
sleep_time = FP_TO_INT((fp_inter_t)(evt_cnt+1) * evt_tick);
sleep_time = FP_TO_INT((fp_inter_t)(pre_evt_cnt+1) * evt_tick);
/* Event hasn't been triggered */
else
sleep_time = FP_TO_INT((fp_inter_t)(evt_cnt+1 - cnt) *
sleep_time = FP_TO_INT((fp_inter_t)(pre_evt_cnt+1 - cnt) *
evt_tick);
interrupt_enable();

View File

@@ -21,7 +21,10 @@ enum ITIM_SOURCE_CLOCK_T {
/* Initialize ITIM16 timer */
void init_hw_timer(int itim_no, enum ITIM_SOURCE_CLOCK_T source);
/* Returns time delay cause of deep idle */
uint32_t __hw_clock_get_sleep_time(void);
/* Returns the counter value of event timer */
uint32_t __hw_clock_event_count(void);
/* Returns time delay because of deep idle */
uint32_t __hw_clock_get_sleep_time(uint32_t pre_evt_cnt);
#endif /* __CROS_EC_HWTIMER_CHIP_H */