summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHu, Hebo <hebo.hu@intel.com>2019-04-24 14:08:19 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-05-07 21:32:41 +0000
commiteaa2616f0765eb7fec5bdddd68a41fbf7c7dc737 (patch)
treeb1dba2ea829e7bd740571213b40084e954eb4eee
parentddeaab3fb8d32d5028970578345772dc2300ab34 (diff)
downloadchrome-ec-eaa2616f0765eb7fec5bdddd68a41fbf7c7dc737.tar.gz
ish/ish5: fix some HPET issues.
1: extra timer 0 and timer 1 interrupt issue no wait settling before write HPET generical interrupt status register, may cause clear irq failed since value may write failed. this can cause extra timer interrupt issue. 2: new comparator value update for timer 1 may failed need wait settling before update timer 1 comparator value in __hw_clock_event_set() 3: need check main counter value's validity after exit TCG low power mode in low power TCG mode, the main counter value will become invalid, after exit TCG mode, HW will restore it, but FW need to wait check if it's valid. BRANCH=none BUG=b:131515624 TEST=tested on arcada platform Change-Id: I84586285ddb150cbae453f24dd172d238ec5b324 Signed-off-by: Hu, Hebo <hebo.hu@intel.com> Reviewed-on: https://chromium-review.googlesource.com/1583664 Commit-Ready: Jack Rosenthal <jrosenth@chromium.org> Tested-by: Hyungwoo Yang <hyungwoo.yang@intel.com> Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Hebo Hu <hebo.hu@intel.corp-partner.google.com> Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1598523 Commit-Queue: Jett Rink <jettrink@chromium.org> Tested-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--chip/ish/hpet.h10
-rw-r--r--chip/ish/hwtimer.c15
2 files changed, 11 insertions, 14 deletions
diff --git a/chip/ish/hpet.h b/chip/ish/hpet.h
index 3823a6e858..7a2a420c82 100644
--- a/chip/ish/hpet.h
+++ b/chip/ish/hpet.h
@@ -47,11 +47,13 @@
* Use this register to see HPET timer are settled after a write.
*/
#define HPET_CTRL_STATUS REG32(ISH_HPET_BASE + 0x160)
-#define HPET_T1_CMP_SETTLING BIT(9)
-#define HPET_T0_CMP_SETTLING (BIT(7) | BIT(8))
-#define HPET_T1_CAP_SETTLING BIT(5)
-#define HPET_T0_CAP_SETTLING BIT(4)
+#define HPET_INT_STATUS_SETTLING BIT(1)
#define HPET_MAIN_COUNTER_SETTLING (BIT(2) | BIT(3))
+#define HPET_T0_CAP_SETTLING BIT(4)
+#define HPET_T1_CAP_SETTLING BIT(5)
+#define HPET_T0_CMP_SETTLING (BIT(7) | BIT(8))
+#define HPET_T1_CMP_SETTLING BIT(9)
+#define HPET_MAIN_COUNTER_VALID BIT(13)
#define HPET_T1_SETTLING (HPET_T1_CAP_SETTLING | \
HPET_T1_CMP_SETTLING)
#define HPET_T0_SETTLING (HPET_T0_CAP_SETTLING | \
diff --git a/chip/ish/hwtimer.c b/chip/ish/hwtimer.c
index 6a0c4ea366..6cd4f854bf 100644
--- a/chip/ish/hwtimer.c
+++ b/chip/ish/hwtimer.c
@@ -146,6 +146,9 @@ static inline uint64_t read_main_timer(void)
timestamp_t t;
uint32_t hi;
+ /* need check main counter if valid when exit low power TCG mode */
+ wait_while_settling(HPET_MAIN_COUNTER_VALID);
+
do {
t.le.hi = HPET_MAIN_COUNTER_64_HI;
t.le.lo = HPET_MAIN_COUNTER_64_LO;
@@ -172,6 +175,7 @@ void __hw_clock_event_set(uint32_t deadline)
* of 12Mhz timer comparator value. Watchdog refresh happens at least
* every 10 seconds.
*/
+ wait_while_settling(HPET_T1_CMP_SETTLING);
HPET_TIMER_COMP(1) = read_main_timer() + scale_us2ticks(remaining_us);
wait_while_settling(HPET_T1_SETTLING);
@@ -212,6 +216,7 @@ void __hw_clock_source_set(uint32_t ts)
static void __hw_clock_source_irq(int timer_id)
{
/* Clear interrupt */
+ wait_while_settling(HPET_INT_STATUS_SETTLING);
HPET_INTR_CLEAR = BIT(timer_id);
/*
@@ -219,16 +224,6 @@ static void __hw_clock_source_irq(int timer_id)
* overflowed).
*/
process_timers(timer_id == 0);
-
- /*
- * Clearing interrupt status before the main counter gets increased
- * generates an extra interrupt.
- * Here, we checks interrupt status register to prevent the extra
- * interrupt. It's safe to clear the interrupt again here since
- * there's at least MINIMUM_EVENT_DELAY_US delay for the next event
- */
- while (HPET_INTR_CLEAR & BIT(timer_id))
- HPET_INTR_CLEAR = BIT(timer_id);
}
void __hw_clock_source_irq_0(void)