it8380dev: modify hwtimer and LPC wake up

1. In combinational mode and clock source is 8MHz,
   if timer 3 counter register always equals to 7, then timer 4 will be a
   32-bit MHz free-running counter.
2. Fix TIMER_32P768K_CNT_TO_US(), each count should be 30.5175 us,
   not 32.768us.
3. Fix TIMER_CNT_8M_32P768K().
4. Make sure LPC wake up interrupt is enabled before entering doze /
   deep doze mode.

Signed-off-by: Dino Li <dino.li@ite.com.tw>

BRANCH=none
BUG=none
TEST=1. Console commands: 'gettime', 'timerinfo', 'waitms', and 'forcetime'.
     2. Enabled Hook debug, no warning message received (48hrs).
     3. Tested ectool command 'version' x 2000.

Change-Id: I796d985361d3c18bc5813c58705b41923e28c5b1
Reviewed-on: https://chromium-review.googlesource.com/310039
Commit-Ready: Dino Li <dino.li@ite.com.tw>
Tested-by: Dino Li <dino.li@ite.com.tw>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Dino Li
2015-11-03 01:40:09 +08:00
committed by chrome-bot
parent f9ffa951c1
commit 032846bc32
6 changed files with 59 additions and 210 deletions

View File

@@ -40,8 +40,8 @@ static int console_in_use_timeout_sec = 5;
static timestamp_t console_expire_time;
/* clock source is 32.768KHz */
#define TIMER_32P768K_CNT_TO_US(cnt) ((cnt) * 32768 / 1000)
#define TIMER_CNT_8M_32P768K(cnt) (((cnt) / 262) + 1)
#define TIMER_32P768K_CNT_TO_US(cnt) ((uint64_t)(cnt) * 1000000 / 32768)
#define TIMER_CNT_8M_32P768K(cnt) (((cnt) / (8000000 / 32768)) + 1)
#endif /*CONFIG_LOW_POWER_IDLE */
static int freq;
@@ -79,6 +79,13 @@ void clock_init(void)
/* Default doze mode */
IT83XX_ECPM_PLLCTRL = EC_PLL_DOZE;
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
IT83XX_WUC_WUESR4 = 0xff;
task_clear_pending_irq(IT83XX_IRQ_WKINTAD);
/* bit2, wake-up enable for LPC access */
IT83XX_WUC_WUENR4 |= (1 << 2);
#endif
}
int clock_get_freq(void)
@@ -152,9 +159,6 @@ static void clock_htimer_enable(void)
{
uint32_t c;
/* disable free running interrupt */
task_disable_irq(et_ctrl_regs[FREE_EXT_TIMER_H].irq);
task_disable_irq(et_ctrl_regs[FREE_EXT_TIMER_L].irq);
/* change event timer clock source to 32.768 KHz */
c = TIMER_CNT_8M_32P768K(IT83XX_ETWD_ETXCNTOR(EVENT_EXT_TIMER));
clock_event_timer_clock_change(EXT_PSR_32P768K_HZ, c);
@@ -173,10 +177,6 @@ static int clock_allow_low_power_idle(void)
SLEEP_SET_HTIMER_DELAY_USEC)
return 0;
if (TIMER_L_COUNT_TO_US(IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_L)) <
SLEEP_SET_HTIMER_DELAY_USEC)
return 0;
sleep_mode_t0 = get_time();
if ((sleep_mode_t0.le.lo > (0xffffffff - SLEEP_FTIMER_SKIP_USEC)) ||
(sleep_mode_t0.le.lo < SLEEP_FTIMER_SKIP_USEC))
@@ -209,17 +209,6 @@ void clock_sleep_mode_wakeup_isr(void)
c = 0xffffffff - IT83XX_ETWD_ETXCNTOR(LOW_POWER_EXT_TIMER);
st_us = TIMER_32P768K_CNT_TO_US(c);
sleep_mode_t1.val = sleep_mode_t0.val + st_us;
/*
* When TIMER_L underflow, and because the observation value
* equals to counter setting register, we need a window of
* 64us (at minimum) to reset the value of TIMER_L back to
* 0xfffff8(TIMER_L_COUNT_TO_US(0xffffffff))
*/
c = TIMER_L_US_TO_COUNT(0xffffffff - sleep_mode_t1.le.lo);
if (TIMER_L_COUNT_TO_US(c) < 64) {
sleep_mode_t1.le.lo |= 0x3F;
sleep_mode_t1.le.lo &= ~(1 << 6);
}
__hw_clock_source_set(sleep_mode_t1.le.lo);
/* reset event timer and clock source is 8 MHz */
@@ -243,12 +232,6 @@ void __idle(void)
ext_timer_ms(LOW_POWER_EXT_TIMER, EXT_PSR_32P768K_HZ, 1, 0,
0xffffffff, 1, 1);
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
IT83XX_WUC_WUESR4 = 0xff;
task_clear_pending_irq(IT83XX_IRQ_WKINTAD);
/* bit2, wake-up enable for LPC access */
IT83XX_WUC_WUENR4 |= (1 << 2);
#endif
/*
* Print when the idle task starts. This is the lowest priority task,
* so this only starts once all other tasks have gotten a chance to do
@@ -257,20 +240,13 @@ void __idle(void)
CPRINTS("low power idle task started");
while (1) {
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
BRAM_LPC_ACCESS = LPC_ACCESS_INT_BUSY;
/* LPC access interrupt pending. */
if (IT83XX_WUC_WUESR4 & (1 << 2)) {
task_enable_irq(IT83XX_IRQ_WKINTAD);
continue;
}
BRAM_LPC_ACCESS = 0;
task_enable_irq(IT83XX_IRQ_WKINTAD);
#endif
allow_sleep = 0;
if (DEEP_SLEEP_ALLOWED)
allow_sleep = clock_allow_low_power_idle();
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
task_enable_irq(IT83XX_IRQ_WKINTAD);
#endif
if (allow_sleep) {
interrupt_disable();
/* reset low power mode hw timer */
@@ -293,6 +269,9 @@ void __idle(void)
asm("standby wake_grant");
idle_doze_cnt++;
}
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
task_disable_irq(IT83XX_IRQ_WKINTAD);
#endif
}
}
#endif /* CONFIG_LOW_POWER_IDLE */

View File

@@ -451,12 +451,6 @@ static void __gpio_irq(void)
#endif
if (irq == IT83XX_IRQ_WKINTAD) {
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
if (BRAM_LPC_ACCESS == LPC_ACCESS_INT_BUSY)
task_disable_irq(IT83XX_IRQ_WKINTAD);
#else
task_disable_irq(IT83XX_IRQ_WKINTAD);
#endif
IT83XX_WUC_WUESR4 = 0xff;
task_clear_pending_irq(IT83XX_IRQ_WKINTAD);
return;

View File

@@ -21,36 +21,31 @@
* The IT839X series support combinational mode for combining specific pairs of
* timers: 3(24-bit) and 4(32-bit) / timer 5(24-bit) and 6(32-bit) /
* timer 7(24-bit) and 8(32-bit).
* That means we will have a 56-bit timer if timer 3(TIMER_L) and
* timer 4(TIMER_H) is combined (bit3 @ IT83XX_ETWD_ETXCTRL).
* For a 32-bit MHz free-running counter, we select 8MHz clock source
* for timer 3(TIMER_L) and 4(TIMER_H).
* Counter setting value register(IT83XX_ETWD_ETXCNTLR) and counter observation
* value register(IT83XX_ETWD_ETXCNTOR) of timer 3 and 4 need to be shifted by
* 3 (2^3). So that each count will be equal to 0.125us.
*
* 32-bit MHz free-running counter: We combine (bit3@IT83XX_ETWD_ETXCTRL)
* timer 3(TIMER_L) and 4(TIMER_H) and set clock source register to 8MHz.
* In combinational mode, the counter register(IT83XX_ETWD_ETXCNTLR) of timer 3
* is a fixed value = 7, and observation register(IT83XX_ETWD_ETXCNTOR)
* of timer 4 will increase one per-us.
*
* For example, if
* __hw_clock_source_set() set 0 us, the counter setting register are
* timer 3(TIMER_L) ((0xffffffff << 3) & 0xffffff) = 0xfffff8
* timer 4(TIMER_H) (0xffffffff >> (24-3)) = 0x000007ff
* The 56-bit 8MHz timer = 0x000007fffffff8
* 0x000007fffffff8 / (2^3) = 0xffffffff(32-bit MHz free-running counter)
* __hw_clock_source_set() set 0 us, the counter setting registers are
* timer 3(TIMER_L) = 0x000007 (fixed, will not change)
* timer 4(TIMER_H) = 0xffffffff
*
* Note:
* In combinational mode, the counter observation value of
* timer 4(TIMER_H), 6, 8 will in incrementing order.
* For the above example, the counter observation value registers will be
* timer 3(TIMER_L) 0xfffff8
* timer 4(TIMER_H) ~0x000007ff = 0xfffff800
* timer 3(TIMER_L) 0x0000007
* timer 4(TIMER_H) ~0xffffffff = 0x00000000
*
* The following will describe timer 3 and 4's operation in combinational mode:
* 1. When timer 3(TIMER_L) observation value counting down to 0,
* 1. When timer 3(TIMER_L) has completed each counting (per-us),
timer 4(TIMER_H) observation value++.
* 2. Timer 3(TIMER_L) observation value = counter setting register.
* 3. Timer 3(TIMER_L) interrupt occurs if interrupt is enabled.
* 4. When timer 4(TIMER_H) observation value overflows.
* 5. Timer 4(TIMER_H) observation value = ~counter setting register.
* 6. Timer 4(TIMER_H) interrupt occurs.
* 2. When timer 4(TIMER_H) observation value overflows:
* timer 4(TIMER_H) observation value = ~counter setting register.
* 3. Timer 4(TIMER_H) interrupt occurs.
*
* IT839X only supports terminal count interrupt. We need a separate
* 8 MHz 32-bit timer to handle events.
@@ -74,41 +69,21 @@ const struct ext_timer_ctrl_t et_ctrl_regs[] = {
};
BUILD_ASSERT(ARRAY_SIZE(et_ctrl_regs) == EXT_TIMER_COUNT);
static void free_run_timer_config_counter(uint32_t us)
{
/* bit0, timer stop */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) &= ~(1 << 0);
/*
* microseconds to timer counter,
* timer 3(TIMER_L) and 4(TIMER_H) combinational mode
*/
IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) = TIMER_H_US_TO_COUNT(us);
IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_L) = TIMER_L_US_TO_COUNT(us);
/* bit[0,1], timer start and reset */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= 3;
}
static void free_run_timer_clear_pending_isr(void)
{
/* w/c interrupt status */
task_clear_pending_irq(et_ctrl_regs[FREE_EXT_TIMER_L].irq);
task_clear_pending_irq(et_ctrl_regs[FREE_EXT_TIMER_H].irq);
}
static void free_run_timer_overflow(void)
{
/*
* If timer counter 4(TIMER_H) + timer counter 3(TIMER_L)
* != 0x000007fffffff8.
* If timer 4 (TIMER_H) counter register != 0xffffffff.
* This usually happens once after sysjump, force time, and etc.
* (when __hw_clock_source_set is called and param 'ts' != 0)
*/
if ((IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) != TIMER_H_CNT_COMP) ||
(IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_L) != TIMER_L_CNT_COMP))
free_run_timer_config_counter(0xffffffff);
if (IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) != 0xffffffff) {
/* set timer counter register */
IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) = 0xffffffff;
/* bit[1], timer reset */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= (1 << 1);
}
/* w/c interrupt status */
free_run_timer_clear_pending_isr();
task_clear_pending_irq(et_ctrl_regs[FREE_EXT_TIMER_H].irq);
/* timer overflow */
process_timers(1);
update_exc_start_time();
@@ -122,48 +97,19 @@ static void event_timer_clear_pending_isr(void)
uint32_t __hw_clock_source_read(void)
{
uint32_t l_cnt, h_cnt;
/*
* get timer counter observation value, timer 3(TIMER_L) and 4(TIMER_H)
* combinational mode.
* In combinational mode, the counter observation register of
* timer 4(TIMER_H) will in incrementing order.
*/
h_cnt = IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H);
l_cnt = IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_L);
/* timer 3(TIMER_L) overflow, get counter observation value again */
if (h_cnt != IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H)) {
h_cnt = IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H);
l_cnt = IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_L);
}
/* timer counter observation value to microseconds */
return 0xffffffff - (TIMER_L_COUNT_TO_US(l_cnt) |
TIMER_H_COUNT_TO_US(h_cnt));
return IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H);
}
void __hw_clock_source_set(uint32_t ts)
{
uint32_t start_us;
/* counting down timer */
start_us = 0xffffffff - ts;
/* timer 3(TIMER_L) and timer 4(TIMER_H) are not enabled */
if ((IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) & 0x09) != 0x09) {
/* bit3, timer 3 and timer 4 combinational mode */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= (1 << 3);
/* microseconds to timer counter, clock source is 8mhz */
ext_timer_ms(FREE_EXT_TIMER_H, EXT_PSR_8M_HZ, 0, 1,
TIMER_H_US_TO_COUNT(start_us), 1, 1);
ext_timer_ms(FREE_EXT_TIMER_L, EXT_PSR_8M_HZ, 1, 1,
TIMER_L_US_TO_COUNT(start_us), 1, 1);
} else {
/* set timer counter only */
free_run_timer_config_counter(start_us);
free_run_timer_clear_pending_isr();
task_enable_irq(et_ctrl_regs[FREE_EXT_TIMER_H].irq);
task_enable_irq(et_ctrl_regs[FREE_EXT_TIMER_L].irq);
}
/* counting down timer, microseconds to timer counter register */
IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) = 0xffffffff - ts;
/* bit[1], timer reset */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= (1 << 1);
}
void __hw_clock_event_set(uint32_t deadline)
@@ -205,7 +151,12 @@ void __hw_clock_event_clear(void)
int __hw_clock_source_init(uint32_t start_t)
{
/* enable free running timer */
/* bit3, timer 3 and timer 4 combinational mode */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= (1 << 3);
/* init free running timer (timer 4, TIMER_H), clock source is 8mhz */
ext_timer_ms(FREE_EXT_TIMER_H, EXT_PSR_8M_HZ, 0, 1, 0xffffffff, 1, 1);
/* 1us counter settiing (timer 3, TIMER_L) */
ext_timer_ms(FREE_EXT_TIMER_L, EXT_PSR_8M_HZ, 1, 0, 7, 1, 1);
__hw_clock_source_set(start_t);
/* init event timer */
ext_timer_ms(EVENT_EXT_TIMER, EXT_PSR_8M_HZ, 0, 0, 0xffffffff, 1, 1);
@@ -247,39 +198,6 @@ static void __hw_clock_source_irq(void)
}
#endif
/* Interrupt of free running timer TIMER_L. */
if (irq == et_ctrl_regs[FREE_EXT_TIMER_L].irq) {
/* w/c interrupt status */
task_clear_pending_irq(et_ctrl_regs[FREE_EXT_TIMER_L].irq);
/* disable timer 3(TIMER_L) interrupt */
task_disable_irq(et_ctrl_regs[FREE_EXT_TIMER_L].irq);
/* No need to set timer counter */
if (IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_L) == TIMER_L_CNT_COMP)
return;
/*
* If timer counter 3(TIMER_L) != 0xfffff8.
* This usually happens once after sysjump, force time, and etc.
* (when __hw_clock_source_set is called and param 'ts' != 0)
*
* The interrupt is used to make sure the counter of
* timer 3(TIMER_L) is
* 0xfffff8(TIMER_L_COUNT_TO_US(0xffffffff)).
*/
if (IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H)) {
/* bit0, timer stop */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) &= ~(1 << 0);
IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_L) =
TIMER_L_US_TO_COUNT(0xffffffff);
IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_H) -= 1;
/* bit[0,1], timer start and reset */
IT83XX_ETWD_ETXCTRL(FREE_EXT_TIMER_L) |= 3;
update_exc_start_time();
} else {
free_run_timer_overflow();
}
return;
}
/* Interrupt of free running timer TIMER_H. */
if (irq == et_ctrl_regs[FREE_EXT_TIMER_H].irq) {
free_run_timer_overflow();

View File

@@ -10,22 +10,11 @@
#define TIMER_COUNT_1US_SHIFT 3
/* Combinational mode, microseconds to timer counter setting register */
#define TIMER_H_US_TO_COUNT(us) ((us) >> (24 - TIMER_COUNT_1US_SHIFT))
#define TIMER_L_US_TO_COUNT(us) (((us) << TIMER_COUNT_1US_SHIFT) & 0x00ffffff)
/* Free running timer counter observation value to microseconds */
#define TIMER_H_COUNT_TO_US(cnt) ((~(cnt)) << (24 - TIMER_COUNT_1US_SHIFT))
#define TIMER_L_COUNT_TO_US(cnt) (((cnt) & 0x00ffffff) >> TIMER_COUNT_1US_SHIFT)
/* Microseconds to event timer counter setting register */
#define EVENT_TIMER_US_TO_COUNT(us) ((us) << TIMER_COUNT_1US_SHIFT)
/* Event timer counter observation value to microseconds */
#define EVENT_TIMER_COUNT_TO_US(cnt) ((cnt) >> TIMER_COUNT_1US_SHIFT)
#define TIMER_H_CNT_COMP TIMER_H_US_TO_COUNT(0xffffffff)
#define TIMER_L_CNT_COMP TIMER_L_US_TO_COUNT(0xffffffff)
#define FREE_EXT_TIMER_L EXT_TIMER_3
#define FREE_EXT_TIMER_H EXT_TIMER_4
#define FAN_CTRL_EXT_TIMER EXT_TIMER_5

View File

@@ -966,8 +966,7 @@ enum bram_indices {
BRAM_IDX_RESET_FLAGS2 = 2,
BRAM_IDX_RESET_FLAGS3 = 3,
BRAM_IDX_LPC_ACCESS = 4,
/* index 5 ~ 7 are reserved */
/* index 4 ~ 7 are reserved */
BRAM_IDX_SCRATCHPAD = 8,
BRAM_IDX_SCRATCHPAD1 = 9,
@@ -984,9 +983,6 @@ enum bram_indices {
#define BRAM_RESET_FLAGS2 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS2)
#define BRAM_RESET_FLAGS3 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS3)
#define BRAM_LPC_ACCESS IT83XX_BRAM_BANK0(BRAM_IDX_LPC_ACCESS)
#define LPC_ACCESS_INT_BUSY 0x33
#define BRAM_SCRATCHPAD IT83XX_BRAM_BANK0(BRAM_IDX_SCRATCHPAD)
#define BRAM_SCRATCHPAD1 IT83XX_BRAM_BANK0(BRAM_IDX_SCRATCHPAD1)
#define BRAM_SCRATCHPAD2 IT83XX_BRAM_BANK0(BRAM_IDX_SCRATCHPAD2)

View File

@@ -60,10 +60,6 @@ static uint64_t exc_total_time; /* Total time in exceptions */
static uint32_t svc_calls; /* Number of service calls */
static uint32_t task_switches; /* Number of times active task changed */
static uint32_t irq_dist[CONFIG_IRQ_COUNT]; /* Distribution of IRQ calls */
#if defined(CONFIG_LOW_POWER_IDLE) && defined(CHIP_FAMILY_IT83XX)
static uint32_t exc_current_fth;
static uint32_t exc_current_ftl;
#endif
#endif
extern int __task_start(void);
@@ -79,22 +75,9 @@ void __idle(void)
*/
cprints(CC_TASK, "idle task started");
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
IT83XX_WUC_WUESR4 = 0xff;
task_clear_pending_irq(IT83XX_IRQ_WKINTAD);
/* bit2, wake-up enable for LPC access */
IT83XX_WUC_WUENR4 |= (1 << 2);
#endif
while (1) {
#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
BRAM_LPC_ACCESS = LPC_ACCESS_INT_BUSY;
/* LPC access interrupt pending. */
if (IT83XX_WUC_WUESR4 & (1 << 2)) {
task_enable_irq(IT83XX_IRQ_WKINTAD);
continue;
}
BRAM_LPC_ACCESS = 0x00;
#if defined(CHIP_FAMILY_IT83XX) && defined(CONFIG_LPC) \
&& defined(CONFIG_IT83XX_LPC_ACCESS_INT)
task_enable_irq(IT83XX_IRQ_WKINTAD);
#endif
@@ -108,6 +91,11 @@ void __idle(void)
* (sleep / deep sleep, depending on chip config).
*/
asm("standby wake_grant");
#if defined(CHIP_FAMILY_IT83XX) && defined(CONFIG_LPC) \
&& defined(CONFIG_IT83XX_LPC_ACCESS_INT)
task_disable_irq(IT83XX_IRQ_WKINTAD);
#endif
}
}
#endif /* !CONFIG_LOW_POWER_IDLE */
@@ -349,10 +337,6 @@ void update_exc_start_time(void)
{
#ifdef CONFIG_TASK_PROFILING
exc_start_time = get_time().val;
#if defined(CONFIG_LOW_POWER_IDLE) && defined(CHIP_FAMILY_IT83XX)
exc_current_fth = IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H);
exc_current_ftl = IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_L);
#endif
#endif
}
@@ -390,10 +374,6 @@ void end_irq_handler(void)
{
#ifdef CONFIG_TASK_PROFILING
uint64_t t, p;
#if defined(CONFIG_LOW_POWER_IDLE) && defined(CHIP_FAMILY_IT83XX)
uint32_t c;
#endif
/*
* save r0 and fp (fp for restore r0-r5, r15, fp, lp and sp
* while interrupt exit.
@@ -401,13 +381,6 @@ void end_irq_handler(void)
asm volatile ("smw.adm $r0, [$sp], $r0, 8");
t = get_time().val;
#if defined(CONFIG_LOW_POWER_IDLE) && defined(CHIP_FAMILY_IT83XX)
if (exc_current_fth != IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H)) {
c = (IT83XX_ETWD_ETXCNTLR(FREE_EXT_TIMER_L) + exc_current_ftl) -
IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_L);
t = exc_start_time + (c >> TIMER_COUNT_1US_SHIFT);
}
#endif
p = t - exc_start_time;
exc_total_time += p;