diff options
author | Scott Worley <scott.worley@microchip.corp-partner.google.com> | 2021-03-10 08:25:41 -0500 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-03-30 06:01:14 +0000 |
commit | 5ee0d735a2626a18e4284bceaaa3218fb35a03a1 (patch) | |
tree | 445573e143218690d1255bfb1451ef19ce6e7b1f /chip/mchp | |
parent | 6954cd5df6c11d0d6b2c92d2c071fd78e4bbc573 (diff) | |
download | chrome-ec-5ee0d735a2626a18e4284bceaaa3218fb35a03a1.tar.gz |
mchp: Update chip clock and system code for MEC172x
Add minor MEC172x changes to chip level clock and system code.
MEC172x implements different 32 KHz clock source selection including
hardware to test and monitor the 32 KHz input source if desired. Change
hard coded EC clock divider values to defined values from chip specific
header files. Add MEC172x chip ID strings. Minor tweak to sleep entry
and exit: MEC172x new port 80h capture hardware does not need to be
manually enabled/disabled in sleep sequence.
BRANCH=none
BUG=none
TEST=Build MCHP MEC170x and MEC152x boards
Signed-off-by: Scott Worley <scott.worley@microchip.corp-partner.google.com>
Change-Id: I46bd3a12541f71f575a0a7af4e07734b74259679
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2748794
Reviewed-by: Martin Yan <martin.yan@microchip.corp-partner.google.com>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Reviewed-by: Ravin Kumar <ravin.kumar@microchip.com>
Tested-by: Martin Yan <martin.yan@microchip.corp-partner.google.com>
Commit-Queue: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'chip/mchp')
-rw-r--r-- | chip/mchp/clock.c | 62 | ||||
-rw-r--r-- | chip/mchp/system.c | 205 |
2 files changed, 195 insertions, 72 deletions
diff --git a/chip/mchp/clock.c b/chip/mchp/clock.c index ca0b943c42..362025ee1c 100644 --- a/chip/mchp/clock.c +++ b/chip/mchp/clock.c @@ -70,6 +70,53 @@ int clock_get_freq(void) return freq; } +/* + * MEC170x and MEC152x have the same 32 KHz clock enable hardware. + * MEC172x 32 KHz clock configuration is different and includes + * hardware to check the crystal before switching and to monitor + * the 32 KHz input if desired. + */ +#ifdef CHIP_FAMILY_MEC172X +/* 32 KHz crystal connected in parallel */ +static inline void config_32k_src_crystal(void) +{ + MCHP_VBAT_CSS = MCHP_VBAT_CSS_XTAL_EN + | MCHP_VBAT_CSS_SRC_XTAL; +} + +/* 32 KHz source is 32KHZ_IN pin which must be configured */ +static inline void config_32k_src_se_input(void) +{ + MCHP_VBAT_CSS = MCHP_VBAT_CSS_SIL32K_EN + | MCHP_VBAT_CSS_SRC_SWPS; +} + +static inline void config_32k_src_sil_osc(void) +{ + MCHP_VBAT_CSS = MCHP_VBAT_CSS_SIL32K_EN; +} + +#else +static void config_32k_src_crystal(void) +{ + MCHP_VBAT_CE = MCHP_VBAT_CE_XOSEL_PAR + | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL; +} + +/* 32 KHz source is 32KHZ_IN pin which must be configured */ +static inline void config_32k_src_se_input(void) +{ + MCHP_VBAT_CE = MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN + | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_INT; +} + +static inline void config_32k_src_sil_osc(void) +{ + MCHP_VBAT_CE = ~(MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN + | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL); +} +#endif + /** clock_init * @note * MCHP MEC implements 4 control bits in the VBAT Clock Enable register. @@ -96,16 +143,13 @@ void clock_init(void) { if (IS_ENABLED(CONFIG_CLOCK_SRC_EXTERNAL)) if (IS_ENABLED(CONFIG_CLOCK_CRYSTAL)) - MCHP_VBAT_CE = MCHP_VBAT_CE_XOSEL_PAR - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL; + config_32k_src_crystal(); else /* 32KHz 50% duty waveform on 32KHZ_IN pin */ - MCHP_VBAT_CE = MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_INT; + config_32k_src_se_input(); else /* Use internal silicon 32KHz OSC */ - MCHP_VBAT_CE = ~(MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN - | MCHP_VBAT_CE_ALWAYS_ON_32K_SRC_CRYSTAL); + config_32k_src_sil_osc(); /* Wait for PLL to lock onto 32KHz source (OSC_LOCK == 1) */ while (!(MCHP_PCR_CHIP_OSC_ID & 0x100)) @@ -127,7 +171,7 @@ static void clock_turbo_disable(void) else #endif /* Use 12 MHz processor clock for power savings */ - MCHP_PCR_PROC_CLK_CTL = 4; + MCHP_PCR_PROC_CLK_CTL = MCHP_PCR_CLK_CTL_12MHZ; } DECLARE_HOOK(HOOK_INIT, clock_turbo_disable, @@ -369,7 +413,9 @@ static void prepare_for_deep_sleep(void) #endif /* stop Port80 capture timer */ +#ifndef CHIP_FAMILY_MEC172X MCHP_P80_ACTIVATE(0) = 0; +#endif /* * Clear SLP_EN bit(s) for wake sources. @@ -446,7 +492,9 @@ static void resume_from_deep_sleep(void) #endif /* re-enable Port 80 capture */ +#ifndef CHIP_FAMILY_MEC172X MCHP_P80_ACTIVATE(0) = 1; +#endif #ifdef CONFIG_ADC MCHP_ADC_CTRL |= 1; diff --git a/chip/mchp/system.c b/chip/mchp/system.c index 9cb19e86f2..c17383bcad 100644 --- a/chip/mchp/system.c +++ b/chip/mchp/system.c @@ -7,29 +7,27 @@ #include <stdnoreturn.h> +#include "common.h" /* includes config.h and board.h */ #include "clock.h" -#include "common.h" +#include "clock_chip.h" #include "console.h" #include "cpu.h" #include "gpio.h" +#include "hooks.h" #include "host_command.h" +#include "lpc_chip.h" #include "registers.h" #include "shared_mem.h" +#include "spi.h" #include "system.h" -#include "hooks.h" #include "task.h" +#include "tfdp_chip.h" #include "timer.h" #include "util.h" -#include "spi.h" -#include "clock_chip.h" -#include "lpc_chip.h" -#include "tfdp_chip.h" - #define CPUTS(outstr) cputs(CC_LPC, outstr) #define CPRINTS(format, args...) cprints(CC_LPC, format, ## args) - /* Index values for hibernate data registers (RAM backed by VBAT) */ enum hibdata_index { HIBDATA_INDEX_SCRATCHPAD = 0, /* General-purpose scratch pad */ @@ -40,6 +38,29 @@ enum hibdata_index { }; /* + * Voltage rail configuration + * MEC172x VTR1 is 3.3V only, VTR2 is auto-detected 3.3 or 1.8V, and + * VTR3 is always 1.8V. + * MEC170x and MEC152x require manual selection of VTR3 for 1.8 or 3.3V. + * The eSPI pins are on VTR3 and require 1.8V + */ +#ifdef CHIP_FAMILY_MEC172X +static void vtr3_voltage_select(int use18v) +{ + (void) use18v; +} +#else +static void vtr3_voltage_select(int use18v) +{ + if (use18v) + MCHP_EC_GPIO_BANK_PWR |= MCHP_EC_GPIO_BANK_PWR_VTR3_18; + else + MCHP_EC_GPIO_BANK_PWR &= ~(MCHP_EC_GPIO_BANK_PWR_VTR3_18); +} +#endif + + +/* * The current logic will set EC_RESET_FLAG_RESET_PIN flag * even if the reset was caused by WDT. MEC170x/MEC152x HW RESET_SYS * status goes active for any of the following: @@ -109,27 +130,21 @@ int system_is_reboot_warm(void) * Keep sleep enables cleared for required blocks: * ECIA, PMC, CPU, ECS and optionally JTAG. * SLEEP_ALL feature will set these upon sleep entry. - * Based on CONFIG_CHIPSET_DEBUG enable or disable JTAG. - * JTAG mode (4-pin or 2-pin SWD + 1-pin SWV) was set - * by Boot-ROM. We can override Boot-ROM JTAG mode - * using - * CONFIG_MCHP_JTAG_MODE + * Based on CONFIG_CHIPSET_DEBUG enable or disable ARM SWD + * 2-pin JTAG mode. */ static void chip_periph_sleep_control(void) { uint32_t d; d = MCHP_PCR_SLP_EN0_SLEEP; -#ifdef CONFIG_CHIPSET_DEBUG - d &= ~(MCHP_PCR_SLP_EN0_JTAG); -#ifdef CONFIG_MCHP_JTAG_MODE - MCHP_EC_JTAG_EN = CONFIG_MCHP_JTAG_MODE; -#else - MCHP_EC_JTAG_EN |= 0x01; -#endif -#else - MCHP_EC_JTAG_EN &= ~0x01; -#endif + + if (IS_ENABLED(CONFIG_CHIPSET_DEBUG)) { + d &= ~(MCHP_PCR_SLP_EN0_JTAG); + MCHP_EC_JTAG_EN = MCHP_JTAG_MODE_SWD | MCHP_JTAG_ENABLE; + } else + MCHP_EC_JTAG_EN &= ~(MCHP_JTAG_ENABLE); + MCHP_PCR_SLP_EN0 = d; MCHP_PCR_SLP_EN1 = MCHP_PCR_SLP_EN1_UNUSED_BLOCKS; MCHP_PCR_SLP_EN2 = MCHP_PCR_SLP_EN2_SLEEP; @@ -140,20 +155,15 @@ 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 - */ - tfdp_power(1); - tfdp_enable(1, 1); - imgtype = MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX); - CPRINTS("chip_pre_init: Image type = 0x%02x", imgtype); -#endif + if (IS_ENABLED(CONFIG_MCHP_TFDP)) { + /* MCHP Enable TFDP for fast debug messages */ + tfdp_power(1); + tfdp_enable(1, 1); + CPRINTS("chip_pre_init: Image type = 0x%02x", + MCHP_VBAT_RAM(MCHP_IMAGETYPE_IDX)); + } } #endif @@ -167,13 +177,14 @@ void system_pre_init(void) MCHP_EC_AHB_ERR = 0; /* write any value to clear */ MCHP_EC_AHB_ERR_EN = 0; /* enable capture of address on error */ -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_EC_GPIO_BANK_PWR |= MCHP_EC_GPIO_BANK_PWR_VTR3_18; -#endif + /* Manual voltage selection only required for MEC170x and MEC152x */ + if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) + vtr3_voltage_select(1); + else + vtr3_voltage_select(0); -#ifndef CONFIG_CHIP_PRE_INIT - chip_periph_sleep_control(); -#endif + if (!IS_ENABLED(CONFIG_CHIP_PRE_INIT)) + chip_periph_sleep_control(); /* Enable direct NVIC */ MCHP_EC_INT_CTRL |= 1; @@ -236,10 +247,9 @@ noreturn void _system_reset(int flags, int wake_from_hibernate) /* * Trigger chip reset */ -#if defined(CONFIG_CHIPSET_DEBUG) -#else - MCHP_PCR_SYS_RST |= MCHP_PCR_SYS_SOFT_RESET; -#endif + if (!IS_ENABLED(CONFIG_DEBUG_BRINGUP)) + MCHP_PCR_SYS_RST |= MCHP_PCR_SYS_SOFT_RESET; + /* Spin and wait for reboot; should never return */ while (1) ; @@ -310,6 +320,39 @@ const char *system_get_chip_name(void) } #endif +#ifdef CHIP_FAMILY_MEC172X +/* + * MEC172x family implements chip ID as a 32-bit + * register where: + * b[31:16] = 16-bit Device ID + * b[15:8] = 8-bit Sub ID + * b[7:0] = Revision + * + * MEC1723N-B0-I/SZ 144 pin: 0x0022_34_xx + * MEC1727N-B0-I/SZ 144 pin: 0x0022_74_xx + * MEC1721N-B0-I/LJ 176 pin: 0x0022_27_xx + * MEC1723N-B0-I/LJ 176 pin: 0x0022_37_xx + * MEC1727N-B0-I/LJ 176 pin: 0x0022_77_xx + */ +const char *system_get_chip_name(void) +{ + switch (MCHP_CHIP_DEVRID32 & ~(MCHP_CHIP_REV_MASK)) { + case 0x00223400: + return "MEC1723NSZ"; + case 0x00227400: + return "MEC1727NSZ"; + case 0x00222700: + return "MEC1721NLJ"; + case 0x00223700: + return "MEC1723NLJ"; + case 0x00227700: + return "MEC1727NLJ"; + default: + return "unknown"; + } +} +#endif + static char to_hex(int x) { if (x >= 0 && x <= 9) @@ -375,16 +418,55 @@ uint32_t system_get_scratchpad(void) return MCHP_VBAT_RAM(HIBDATA_INDEX_SCRATCHPAD); } +/* + * Local function to disable clocks in the chip's host interface + * so the chip can enter deep sleep. Only MEC170X has LPC. + * MEC152x and MEC172x only include eSPI and SPI host interfaces. + * NOTE: we do it this way because the LPC registers are only + * defined for MEC170x and the IS_ENABLED() macro causes the + * compiler to evaluate both true and false code paths. + */ +#if defined(CONFIG_HOSTCMD_ESPI) +static void disable_host_ifc_clocks(void) +{ + MCHP_ESPI_ACTIVATE &= ~0x01; +} +#else +static void disable_host_ifc_clocks(void) +{ + #ifdef CHIP_FAMILY_MEC170X + MCHP_LPC_ACT &= ~0x1; + #endif +} +#endif + + +/* + * Called when hibernation timer is not used in deep sleep. + * Switch 32 KHz clock logic from external 32KHz input to + * internal silicon OSC. + * NOTE: MEC172x auto-switches from external source to silicon + * oscillator. + */ +#ifdef CHIP_FAMILY_MEC172X +static void switch_32k_pin2sil(void) {} +#else +static void switch_32k_pin2sil(void) +{ + MCHP_VBAT_CE &= ~(MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN); +} +#endif + void system_hibernate(uint32_t seconds, uint32_t microseconds) { int i; -#ifdef CONFIG_HOSTCMD_PD - /* Inform the PD MCU that we are going to hibernate. */ - host_command_pd_request_hibernate(); - /* Wait to ensure exchange with PD before hibernating. */ - msleep(100); -#endif + if (IS_ENABLED(CONFIG_HOSTCMD_PD)) { + /* Inform the PD MCU that we are going to hibernate. */ + host_command_pd_request_hibernate(); + /* Wait to ensure exchange with PD before hibernating. */ + msleep(100); + } cflush(); @@ -405,11 +487,9 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds) /* Disable UART */ MCHP_UART_ACT(0) &= ~0x1; -#ifdef CONFIG_HOSTCMD_ESPI - MCHP_ESPI_ACTIVATE &= ~0x01; -#else - MCHP_LPC_ACT &= ~0x1; -#endif + + disable_host_ifc_clocks(); + /* Disable JTAG */ MCHP_EC_JTAG_EN &= ~1; @@ -456,13 +536,8 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds) htimer_init(); system_set_htimer_alarm(seconds, microseconds); interrupt_enable(); - } else { - /* - * Not using hibernation timer. - * Disable external 32KHz clock input. - */ - MCHP_VBAT_CE &= ~(MCHP_VBAT_CE_32K_DOMAIN_32KHZ_IN_PIN); - } + } else + switch_32k_pin2sil(); /* * Set sleep state @@ -477,8 +552,8 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds) asm("isb"); asm("nop"); - /* Use 48MHz clock to speed through wake-up */ - MCHP_PCR_PROC_CLK_CTL = 1; + /* Use fastest clock to speed through wake-up */ + MCHP_PCR_PROC_CLK_CTL = MCHP_PCR_CLK_CTL_FASTEST; /* Reboot */ _system_reset(0, 1); |