summaryrefslogtreecommitdiff
path: root/chip/mchp/clock.c
diff options
context:
space:
mode:
authorscott worley <scott.worley@microchip.corp-partner.google.com>2018-05-10 13:59:52 -0400
committerchrome-bot <chrome-bot@chromium.org>2018-06-12 21:50:56 -0700
commitf83b350444ec7a543378589d7533be6514129288 (patch)
tree62a8cce69090048ed881a0a1a223bc5603779b98 /chip/mchp/clock.c
parent201c5fb497d2c810eb95c9ddf05835adcde63b12 (diff)
downloadchrome-ec-f83b350444ec7a543378589d7533be6514129288.tar.gz
ec_chip_mchp: Fix hibernation timer and wake programming
Hibernation timer was not programmed to correct value for some cases and code was duplicated. Not all interrupt sources were properly configured in system hibernate. Remove debug only system pre-init board level call. BRANCH=none BUG=none TEST=Build all boards using chip mchp. Test with EC UART hibernate command. CQ-DEPEND=CL:1053576 Change-Id: I932443fa7a4e284168babdbb7f64033a55427fb2 Signed-off-by: scott worley <scott.worley@microchip.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/1053956 Commit-Ready: Randall Spangler <rspangler@chromium.org> Tested-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip/mchp/clock.c')
-rw-r--r--chip/mchp/clock.c100
1 files changed, 50 insertions, 50 deletions
diff --git a/chip/mchp/clock.c b/chip/mchp/clock.c
index 123e26e851..59731830cf 100644
--- a/chip/mchp/clock.c
+++ b/chip/mchp/clock.c
@@ -143,7 +143,6 @@ DECLARE_HOOK(HOOK_INIT,
clock_turbo_disable,
HOOK_PRIO_INIT_VBOOT_HASH + 1);
-#ifdef CONFIG_LOW_POWER_IDLE
/**
* initialization of Hibernation timer0
* Clear PCR sleep enable.
@@ -152,12 +151,14 @@ DECLARE_HOOK(HOOK_INIT,
* (exception GPIO's) then the MCHP_INT_BLK_EN GIRQ bit should not be
* set.
*/
-static void htimer_init(void)
+void htimer_init(void)
{
MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_HTMR0);
+ MCHP_HTIMER_PRELOAD(0) = 0; /* disable at beginning */
+ MCHP_INT_SOURCE(MCHP_HTIMER_GIRQ) =
+ MCHP_HTIMER_GIRQ_BIT(0);
MCHP_INT_ENABLE(MCHP_HTIMER_GIRQ) =
MCHP_HTIMER_GIRQ_BIT(0);
- MCHP_HTIMER_PRELOAD(0) = 0; /* disable at beginning */
task_enable_irq(MCHP_IRQ_HTIMER0);
}
@@ -168,52 +169,57 @@ static void htimer_init(void)
*
* @param seconds Number of seconds before htimer interrupt
* @param microseconds Number of microseconds before htimer interrupt
- * @note hibernation timer input clock is 32.768KHz and has two
- * divider values.
+ * @note hibernation timer input clock is 32.768KHz.
* Control register bit[0] selects the divider.
- * 0 is divide by 1 for 30.5us per LSB for a maximum of ~2 seconds.
+ * 0 is divide by 1 for 30.5us per LSB for a maximum of
+ * 65535 * 30.5us = 1998817.5 us or 32.786 counts per second
* 1 is divide by 4096 for 0.125s per LSB for a maximum of ~2 hours.
+ * 65535 * 0.125s ~ 8192 s = 2.27 hours
*/
-static void system_set_htimer_alarm(uint32_t seconds,
+void system_set_htimer_alarm(uint32_t seconds,
uint32_t microseconds)
{
- uint32_t hcnt;
-
- if (microseconds >= 1000000) {
- seconds += microseconds / 1000000;
- microseconds -= (microseconds / 1000000) * 1000000;
- }
+ uint32_t hcnt, ns;
+ uint8_t hctrl;
- if (seconds || microseconds) {
-
- /* if (seconds > 2) { */
- if (seconds > 1) {
- /* count from 2 sec to 2 hrs, mec1322 sec 18.10.2 */
- ASSERT(seconds <= 0xffff / 8);
- /* 0.125(=1/8) per clock */
- MCHP_HTIMER_CONTROL(0) = 1;
- /* (number of counts to be loaded)
- * = seconds * ( 8 clocks per second )
- * + microseconds / 125000
- * ---> (0 if (microseconds < 125000)
- */
- hcnt = (seconds * 8 + microseconds / 125000);
+ MCHP_HTIMER_PRELOAD(0) = 0; /* disable */
- } else { /* count up to 2 sec. */
- /* 30.5(= 2/61) usec */
- MCHP_HTIMER_CONTROL(0) = 0;
+ trace12(0, SLP, 0, "sys set htimer: sec=%d us=%d",
+ seconds, microseconds);
- /* (number of counts to be loaded)
- * = (total microseconds) / 30.5;
- */
- hcnt = (seconds * 1000000 + microseconds) *
- 2 / 61;
- }
+ if (microseconds > 1000000ul) {
+ ns = (microseconds / 1000000ul);
+ microseconds %= 1000000ul;
+ if ((0xfffffffful - seconds) > ns)
+ seconds += ns;
+ else
+ seconds = 0xfffffffful;
+ }
- MCHP_HTIMER_PRELOAD(0) = hcnt;
+ if (seconds > 1) {
+ hcnt = (seconds << 3); /* divide by 0.125 */
+ if (hcnt > 0xfffful)
+ hcnt = 0xfffful;
+ hctrl = 1;
+ } else {
+ /*
+ * approximate(~2% error) as seconds is 0 or 1
+ * seconds / 30.5e-6 + microseonds / 30.5
+ */
+ hcnt = (seconds << 15) + (microseconds >> 5) +
+ (microseconds >> 10);
+ hctrl = 0;
}
+
+ trace12(0, SLP, 0,
+ "sys set htimer: ctrl=0x%0x preload=0x%0x",
+ hctrl, hcnt);
+ MCHP_HTIMER_CONTROL(0) = hctrl;
+ MCHP_HTIMER_PRELOAD(0) = hcnt;
}
+#ifdef CONFIG_LOW_POWER_IDLE
+
/**
* return time slept in micro-seconds
*/
@@ -340,17 +346,19 @@ static void prepare_for_deep_sleep(void)
/* Stop timers */
MCHP_TMR32_CTL(0) &= ~1;
MCHP_TMR32_CTL(1) &= ~1;
+#ifdef CONFIG_WATCHDOG_HELP
MCHP_TMR16_CTL(0) &= ~1;
+ MCHP_INT_DISABLE(MCHP_TMR16_GIRQ) =
+ MCHP_TMR16_GIRQ_BIT(0);
+ MCHP_INT_SOURCE(MCHP_TMR16_GIRQ) =
+ MCHP_TMR16_GIRQ_BIT(0);
+#endif
MCHP_INT_DISABLE(MCHP_TMR32_GIRQ) =
MCHP_TMR32_GIRQ_BIT(0) +
MCHP_TMR32_GIRQ_BIT(1);
MCHP_INT_SOURCE(MCHP_TMR32_GIRQ) =
MCHP_TMR32_GIRQ_BIT(0) +
MCHP_TMR32_GIRQ_BIT(1);
- MCHP_INT_DISABLE(MCHP_TMR16_GIRQ) =
- MCHP_TMR16_GIRQ_BIT(0);
- MCHP_INT_SOURCE(MCHP_TMR16_GIRQ) =
- MCHP_TMR16_GIRQ_BIT(0);
#ifdef CONFIG_WATCHDOG
/* Stop watchdog */
@@ -359,19 +367,11 @@ static void prepare_for_deep_sleep(void)
#ifdef CONFIG_HOSTCMD_ESPI
- #ifdef CONFIG_POWER_S0IX
MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_ESPI;
MCHP_INT_ENABLE(22) = MCHP_INT22_WAKE_ONLY_ESPI;
- #else
- MCHP_ESPI_ACTIVATE &= ~1;
- #endif
#else
- #ifdef CONFIG_POWER_S0IX
MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_LPC;
MCHP_INT_ENABLE(22) = MCHP_INT22_WAKE_ONLY_LPC;
- #else
- MCHP_LPC_ACT |= 1;
- #endif
#endif
#ifdef CONFIG_ADC
@@ -402,7 +402,7 @@ static void prepare_for_deep_sleep(void)
#ifdef CONFIG_CHIPSET_DEBUG
/* Disable JTAG and preserve mode */
- /* MCHP_EC_JTAG_EN &= ~(MCHP_JTAG_ENABLE); */
+ MCHP_EC_JTAG_EN &= ~(MCHP_JTAG_ENABLE);
#endif
/* call board level */