diff --git a/chip/mec1322/system.c b/chip/mec1322/system.c index 2ab4aa1356..269cc31116 100644 --- a/chip/mec1322/system.c +++ b/chip/mec1322/system.c @@ -182,6 +182,11 @@ uint32_t system_get_scratchpad(void) return MEC1322_VBAT_RAM(HIBDATA_INDEX_SCRATCHPAD); } +/* Convert a GPIO to a port + mask, used in the skip table below. */ +#define PORT_MASK_PAIR(gpio) \ + { gpio_list[(gpio)].port, \ + GPIO_MASK_TO_NUM(gpio_list[(gpio)].mask) } + static void system_set_gpio_power(int enabled, uint32_t *backup_gpio_ctl) { int i, j, k; @@ -195,14 +200,37 @@ static void system_set_gpio_power(int enabled, uint32_t *backup_gpio_ctl) }; const int skip[][2] = { -#if defined(BOARD_GLADOS) || defined(BOARD_KUNIMITSU) - /* - * TODO(crosbug.com/p/42774): Remove this - * once we have a pull-down on PCH_RTCRST. - */ - {16, 3}, /* Leave PCH_RTCRST deasserted */ +#ifdef BOARD_GLADOS + /* + * Leave PCH RTCRST deasserted. + * TODO(crosbug.com/p/42774): Remove this once we have a + * pull-down on PCH_RTCRST. + */ + PORT_MASK_PAIR(GPIO_PCH_RTCRST), #endif - {20, 5}, /* GPIO 205 doesn't exist */ + + /* + * Leave USB-C charging enabled in hibernate, in order to + * allow wake-on-plug. 5V enable must be pulled low. + */ +#ifdef CONFIG_USB_PD_PORT_COUNT +#if CONFIG_USB_PD_PORT_COUNT > 0 + PORT_MASK_PAIR(GPIO_USB_C0_5V_EN), + PORT_MASK_PAIR(GPIO_USB_C0_CHARGE_EN_L), +#endif +#if CONFIG_USB_PD_PORT_COUNT > 1 + PORT_MASK_PAIR(GPIO_USB_C1_5V_EN), + PORT_MASK_PAIR(GPIO_USB_C1_CHARGE_EN_L), +#endif +#endif /* CONFIG_USB_PD_PORT_COUNT */ + + /* + * MEC1322 datasheet, sec. 20.6: VCC1_RST# cannot be used + * as a GPIO pin. + */ + {13, 1}, + /* GPIO 205 doesn't exist. */ + {20, 5}, }; for (i = 0; i < ARRAY_SIZE(pins); ++i) { @@ -231,6 +259,23 @@ static void system_set_gpio_power(int enabled, uint32_t *backup_gpio_ctl) } } } + +#ifdef CONFIG_USB_PD_PORT_COUNT + if (!enabled) { + /* + * Leave USB-C charging enabled in hibernate, in order to + * allow wake-on-plug. 5V enable must be pulled low. + */ +#if CONFIG_USB_PD_PORT_COUNT > 0 + gpio_set_flags(GPIO_USB_C0_5V_EN, GPIO_PULL_DOWN | GPIO_INPUT); + gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, 0); +#endif +#if CONFIG_USB_PD_PORT_COUNT > 1 + gpio_set_flags(GPIO_USB_C1_5V_EN, GPIO_PULL_DOWN | GPIO_INPUT); + gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, 0); +#endif + } +#endif /* CONFIG_USB_PD_PORT_COUNT */ } void system_hibernate(uint32_t seconds, uint32_t microseconds) @@ -297,7 +342,10 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds) MEC1322_PCR_SYS_SLP_CTL = (MEC1322_PCR_SYS_SLP_CTL & ~0x7) | 0x2; CPU_SCB_SYSCTRL |= 0x4; + /* Attempt to backup GPIO states if we need to restore them on wake. */ +#ifndef CONFIG_HIBERNATE_RESET_ON_WAKE if (shared_mem_acquire(512, &backup_gpio_ctl) != EC_SUCCESS) +#endif backup_gpio_ctl = NULL; system_set_gpio_power(0, (uint32_t *)backup_gpio_ctl); diff --git a/include/config.h b/include/config.h index 0058391ac4..0fa815b695 100644 --- a/include/config.h +++ b/include/config.h @@ -892,6 +892,12 @@ #undef CONFIG_HIBERNATE_BATT_PCT #undef CONFIG_HIBERNATE_BATT_SEC +/* + * Perform a system reset on wake from hibernate. This is the default behavior, + * and the only chip-supported behavior for certain ECs. + */ +#define CONFIG_HIBERNATE_RESET_ON_WAKE + /* For ECs with multiple wakeup pins, define enabled wakeup pins */ #undef CONFIG_HIBERNATE_WAKEUP_PINS