npcx: Fix hwtimers

- Wait for ITEN bit to be set / cleared, since writing this bit just
  sets a 'request'.
- Ensure ITIM_EVENT_NO reg is set with minimum value 1, per the
  datasheet.
- Don't dsleep if our wake event is in the past (eg. wake event will
  occur any time now)

BUG=chrome-os-partner:59240
BRANCH=gru
TEST=Manual on kevin, verify that dsleep period never exceeds expected
wait period. Also verify that EC watchdog doesn't occur after 5 hours in
S3.

Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: Iedb2723c3f12b74dea66082b1d8b8ce1b6e7d945
Reviewed-on: https://chromium-review.googlesource.com/409672
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
This commit is contained in:
Shawn Nematbakhsh
2016-11-04 14:33:24 -07:00
committed by chrome-bot
parent 5e8a2255ab
commit ebdb6a62aa
2 changed files with 21 additions and 6 deletions

View File

@@ -286,6 +286,7 @@ void __idle(void)
#else
timestamp_t t0, t1;
uint32_t next_evt;
uint32_t next_evt_us;
uint16_t evt_count;
@@ -307,12 +308,16 @@ void __idle(void)
/* Compute event delay */
t0 = get_time();
next_evt_us = __hw_clock_event_get() - t0.le.lo;
next_evt = __hw_clock_event_get();
/* Do we have enough time before next event to deep sleep. */
if (DEEP_SLEEP_ALLOWED && (next_evt_us > WAKE_INTERVAL)
/* Make sure it's over console expired time */
&& (t0.val > console_expire_time.val)) {
if (DEEP_SLEEP_ALLOWED &&
/* Ensure event hasn't already expired */
next_evt > t0.le.lo &&
/* Ensure we have sufficient time before expiration */
next_evt - t0.le.lo > WAKE_INTERVAL &&
/* Make sure it's over console expired time */
t0.val > console_expire_time.val) {
#if DEBUG_CLK
/* Use GPIO to indicate SLEEP mode */
CLEAR_BIT(NPCX_PDOUT(0), 0);

View File

@@ -16,6 +16,7 @@
#include "console.h"
#include "task.h"
#include "timer.h"
#include "util.h"
/* Use ITIM32 as main hardware timer */
#define TICK_ITIM32_MAX_CNT 0xFFFFFFFF
@@ -86,6 +87,7 @@ void __hw_clock_event_set(uint32_t deadline)
/* Event module disable */
CLEAR_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN);
/*
* ITIM count down : event expired : Unit: 1/32768 sec
* It must exceed evt_expired_us for process_timers function
@@ -96,11 +98,20 @@ void __hw_clock_event_set(uint32_t deadline)
evt_cnt, evt_cnt_us);
evt_cnt = TICK_EVT_MAX_CNT;
}
NPCX_ITCNT16(ITIM_EVENT_NO) = evt_cnt;
/* Wait for module disable to take effect before updating count */
while (IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN))
;
NPCX_ITCNT16(ITIM_EVENT_NO) = MAX(evt_cnt, 1);
/* Event module enable */
SET_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN);
/* Wait for module enable */
while (!IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN))
;
/* Enable interrupt of ITIM */
task_enable_irq(ITIM16_INT(ITIM_EVENT_NO));
}
@@ -200,7 +211,6 @@ void hw_clock_source_set_preload(uint32_t ts, uint8_t clear)
{
/* ITIM32 module disable */
CLEAR_BIT(NPCX_ITCTS(ITIM32), NPCX_ITCTS_ITEN);
CLEAR_BIT(NPCX_ITCTS(ITIM32), NPCX_ITCTS_CKSEL);
/* Set preload counter to current time */