summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/mchp/clock.c100
-rw-r--r--chip/mchp/clock_chip.h17
-rw-r--r--chip/mchp/config_chip.h1
-rw-r--r--chip/mchp/system.c126
-rw-r--r--include/config.h5
5 files changed, 127 insertions, 122 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 */
diff --git a/chip/mchp/clock_chip.h b/chip/mchp/clock_chip.h
new file mode 100644
index 0000000000..2e7de60358
--- /dev/null
+++ b/chip/mchp/clock_chip.h
@@ -0,0 +1,17 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Microchip MEC1701 specific module for Chrome EC */
+
+#ifndef __CROS_EC_CLOCK_CHIP_H
+#define __CROS_EC_CLOCK_CHIP_H
+
+#include <stdint.h>
+
+void htimer_init(void);
+void system_set_htimer_alarm(uint32_t seconds,
+ uint32_t microseconds);
+
+#endif /* __CROS_EC_I2C_CLOCK_H */
diff --git a/chip/mchp/config_chip.h b/chip/mchp/config_chip.h
index 183440a8c4..8c1cab81a5 100644
--- a/chip/mchp/config_chip.h
+++ b/chip/mchp/config_chip.h
@@ -27,7 +27,6 @@
*/
#define CONFIG_CHIP_PRE_INIT
-
/*
* MCHP EC's have I2C master/slave
* controllers and multiple I2C ports. Any
diff --git a/chip/mchp/system.c b/chip/mchp/system.c
index fa844a2304..689675716d 100644
--- a/chip/mchp/system.c
+++ b/chip/mchp/system.c
@@ -19,6 +19,7 @@
#include "timer.h"
#include "util.h"
#include "spi.h"
+#include "clock_chip.h"
#include "lpc_chip.h"
#include "tfdp_chip.h"
@@ -51,7 +52,6 @@ static void check_reset_cause(void)
MCHP_VBAT_STS |= status;
MCHP_PCR_PWR_RST_STS |= rst_sts;
-
trace0(0, MEC, 0, "check_reset_cause: after clear");
trace11(0, MEC, 0, " VBAT_PFR = 0x%08X", MCHP_VBAT_STS);
trace11(0, MEC, 0, " PCR PWRST = 0x%08X", MCHP_PCR_PWR_RST_STS);
@@ -133,16 +133,35 @@ static void chip_periph_sleep_control(void)
#ifdef CONFIG_CHIP_PRE_INIT
void chip_pre_init(void)
{
+#ifdef CONFIG_MCHP_TFDP
+ uint8_t imgtype;
+#endif
chip_periph_sleep_control();
+
+#ifdef CONFIG_MCHP_TFDP
+ /*
+ * MCHP Enable TFDP for fast debug messages
+ * If not defined then traceN() and TRACEN() macros are empty
+ */
+ tfdp_power(1);
+ tfdp_enable(1, 1);
+ imgtype = MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX);
+ CPRINTS("chip_pre_init: Image type = 0x%02x", imgtype);
+ trace1(0, MEC, 0,
+ "chip_pre_init: Image type = 0x%02x", imgtype);
+
+ trace11(0, MEC, 0,
+ "chip_pre_init: MCHP_VBAT_STS = 0x%0x",
+ MCHP_VBAT_STS);
+ trace11(0, MEC, 0,
+ "chip_pre_init: MCHP_PCR_PWR_RST_STS = 0x%0x",
+ MCHP_VBAT_STS);
+#endif
}
#endif
void system_pre_init(void)
{
-#ifdef CONFIG_MCHP_TFDP
- uint8_t imgtype;
-#endif
-
/*
* Make sure AHB Error capture is enabled.
* Signals bus fault to Cortex-M4 core if an address presented
@@ -178,37 +197,6 @@ void system_pre_init(void)
MCHP_INT_BLK_EN = (0x1Ful << 8) + (0x07ul << 24);
spi_enable(CONFIG_SPI_FLASH_PORT, 1);
-
-#ifdef CONFIG_MCHP_TFDP
- /*
- * MCHP Enable TFDP for fast debug messages
- * If not defined then traceN() and TRACEN() macros are empty
- */
- tfdp_power(1);
- tfdp_enable(1, 1);
- imgtype = MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX);
- CPRINTS("system_pre_init. Image type = 0x%02x", imgtype);
- trace1(0, MEC, 0, "System pre-init. Image type = 0x%02x", imgtype);
-
- /* Debug: dump some signals */
- imgtype = gpio_get_level(GPIO_PCH_RSMRST_L);
- trace1(0, MEC, 0, "PCH_RSMRST_L = %d", imgtype);
-
- imgtype = gpio_get_level(GPIO_RSMRST_L_PGOOD);
- trace1(0, MEC, 0, "RSMRST_L_PGOOD = %d", imgtype);
- imgtype = gpio_get_level(GPIO_POWER_BUTTON_L);
- trace1(0, MEC, 0, "POWER_BUTTON_L = %d", imgtype);
- imgtype = gpio_get_level(GPIO_PMIC_DPWROK);
- trace1(0, MEC, 0, "PMIC_DPWROK = %d", imgtype);
- imgtype = gpio_get_level(GPIO_ALL_SYS_PWRGD);
- trace1(0, MEC, 0, "ALL_SYS_PWRGD = %d", imgtype);
- imgtype = gpio_get_level(GPIO_AC_PRESENT);
- trace1(0, MEC, 0, "AC_PRESENT = %d", imgtype);
- imgtype = gpio_get_level(GPIO_PCH_SLP_SUS_L);
- trace1(0, MEC, 0, "PCH_SLP_SUS_L = %d", imgtype);
- imgtype = gpio_get_level(GPIO_PMIC_INT_L);
- trace1(0, MEC, 0, "PCH_PMIC_INT_L = %d", imgtype);
-#endif
}
void chip_save_reset_flags(int flags)
@@ -249,7 +237,8 @@ void __attribute__((noreturn)) _system_reset(int flags,
/*
* Trigger chip reset
*/
-#ifndef CONFIG_CHIPSET_DEBUG
+#if defined(CONFIG_CHIPSET_DEBUG)
+#else
MCHP_PCR_SYS_RST |= MCHP_PCR_SYS_SOFT_RESET;
#endif
/* Spin and wait for reboot; should never return */
@@ -364,33 +353,34 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds)
/* Disable interrupts */
interrupt_disable();
- for (i = 0; i <= 92; ++i) {
+ for (i = 0; i < MCHP_IRQ_MAX; ++i) {
task_disable_irq(i);
task_clear_pending_irq(i);
}
- for (i = 8; i <= 26; ++i)
+ for (i = MCHP_INT_GIRQ_FIRST; i <= MCHP_INT_GIRQ_LAST; ++i) {
MCHP_INT_DISABLE(i) = 0xffffffff;
-
- MCHP_INT_BLK_DIS |= 0xffff00;
+ MCHP_INT_SOURCE(i) = 0xffffffff;
+ }
/* Disable UART */
MCHP_UART_ACT(0) &= ~0x1;
+#ifdef CONFIG_HOSTCMD_ESPI
+ MCHP_ESPI_ACTIVATE &= ~0x01;
+#else
MCHP_LPC_ACT &= ~0x1;
-
+#endif
/* Disable JTAG */
MCHP_EC_JTAG_EN &= ~1;
- /* Disable 32KHz clock */
- MCHP_VBAT_CE &= ~0x2;
-
/* Stop watchdog */
MCHP_WDG_CTL &= ~1;
/* Stop timers */
MCHP_TMR32_CTL(0) &= ~1;
MCHP_TMR32_CTL(1) &= ~1;
- MCHP_TMR16_CTL(0) &= ~1;
+ for (i = 0; i < MCHP_TMR16_MAX; i++)
+ MCHP_TMR16_CTL(i) &= ~1;
/* Power down ADC */
/*
@@ -401,14 +391,6 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds)
/* Disable blocks */
MCHP_PCR_SLOW_CLK_CTL &= ~(MCHP_PCR_SLOW_CLK_CTL_MASK);
- /*
- * Set sleep state
- * arm sleep state to trigger on next WFI
- */
- CPU_SCB_SYSCTRL |= 0x4;
- MCHP_PCR_SYS_SLP_CTL = MCHP_PCR_SYS_SLP_HEAVY;
- MCHP_PCR_SYS_SLP_CTL = MCHP_PCR_SYS_SLP_ALL;
-
/* Setup GPIOs for hibernate */
if (board_hibernate_late)
board_hibernate_late();
@@ -427,34 +409,36 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds)
task_enable_irq(MCHP_IRQ_GIRQ10);
task_enable_irq(MCHP_IRQ_GIRQ11);
task_enable_irq(MCHP_IRQ_GIRQ12);
+ task_enable_irq(MCHP_IRQ_GIRQ26);
}
if (seconds || microseconds) {
- /*
- * Not needed when using direct mode interrupts.
- * MCHP_INT_BLK_EN |= 1 << MCHP_HTIMER_GIRQ;
- */
- MCHP_INT_ENABLE(MCHP_HTIMER_GIRQ) =
- MCHP_HTIMER_GIRQ_BIT(0);
+ htimer_init();
+ system_set_htimer_alarm(seconds, microseconds);
interrupt_enable();
- task_enable_irq(MCHP_IRQ_HTIMER0);
- if (seconds > 2) {
- ASSERT(seconds <= 0xffff / 8);
- MCHP_HTIMER_CONTROL(0) = 1;
- MCHP_HTIMER_PRELOAD(0) =
- (seconds * 8 + microseconds / 125000);
- } else {
- MCHP_HTIMER_CONTROL(0) = 0;
- MCHP_HTIMER_PRELOAD(0) =
- (seconds * 1000000 + microseconds) * 2 / 71;
- }
+ } else {
+ /* Not using hibernation timer. Disable 32KHz clock */
+ MCHP_VBAT_CE &= ~0x2;
}
+ /*
+ * Set sleep state
+ * arm sleep state to trigger on next WFI
+ */
+ CPU_SCB_SYSCTRL |= 0x4;
+ MCHP_PCR_SYS_SLP_CTL = MCHP_PCR_SYS_SLP_HEAVY;
+ MCHP_PCR_SYS_SLP_CTL = MCHP_PCR_SYS_SLP_ALL;
+
+ asm("dsb");
asm("wfi");
+ asm("isb");
+ asm("nop");
/* Use 48MHz clock to speed through wake-up */
MCHP_PCR_PROC_CLK_CTL = 1;
+ trace0(0, SYS, 0, "Wake from hibernate: _system_reset[0,1]");
+
/* Reboot */
_system_reset(0, 1);
diff --git a/include/config.h b/include/config.h
index b42a6e54d1..6ad80d77e5 100644
--- a/include/config.h
+++ b/include/config.h
@@ -459,6 +459,11 @@
*/
#undef CONFIG_BOARD_FORCE_RESET_PIN
+/*
+ * Call board level configuration at the end of chip level system pre-init.
+ */
+#undef CONFIG_BOARD_SYS_PRE_INIT
+
/* Permanent LM4 boot configuration */
#undef CONFIG_BOOTCFG_VALUE