diff --git a/board/chell/board.c b/board/chell/board.c index 879de8f715..3b47301806 100644 --- a/board/chell/board.c +++ b/board/chell/board.c @@ -475,3 +475,34 @@ static void board_handle_reboot(void) ; /* wait here */ } DECLARE_HOOK(HOOK_INIT, board_handle_reboot, HOOK_PRIO_FIRST); + +/* + * Various voltage rails will be enabled / disabled by the PMIC when + * GPIO_PMIC_SLP_SUS_L changes. We need to delay the disable of V0.85A + * by approximately 25ms in order to allow V1.00A to sufficiently discharge + * first. + * + * Therefore, after GPIO_PMIC_SLP_SUS_L goes high, ignore the state of + * the V12_EN pin: Keep V0.85A enabled. + * + * When GPIO_PMIC_SLP_SUS_L goes low, delay 25ms, and make V12_EN function + * as normal - this should result in V0.85A discharging immediately after the + * i2c write completes. + */ +void chipset_set_pmic_slp_sus_l(int level) +{ + static int previous_level; + int val; + + gpio_set_level(GPIO_PMIC_SLP_SUS_L, level); + + if (previous_level != level) { + /* Rising edge: Force V0.85A enable. Falling: Pin control. */ + val = level ? 0x80 : 0; + if (!level) + msleep(25); + + i2c_write8(I2C_PORT_PMIC, I2C_ADDR_BD99992, 0x43, val); + previous_level = level; + } +} diff --git a/power/skylake.c b/power/skylake.c index 7346ad95a6..58f2d58f12 100644 --- a/power/skylake.c +++ b/power/skylake.c @@ -72,11 +72,16 @@ void chipset_force_shutdown(void) } } +__attribute__((weak)) void chipset_set_pmic_slp_sus_l(int level) +{ + gpio_set_level(GPIO_PMIC_SLP_SUS_L, level); +} + static void chipset_force_g3(void) { CPRINTS("Forcing fake G3."); - gpio_set_level(GPIO_PMIC_SLP_SUS_L, 0); + chipset_set_pmic_slp_sus_l(0); } void chipset_reset(int cold_reset) @@ -161,7 +166,7 @@ static void handle_slp_sus(enum power_state state) return; /* Always mimic PCH SLP_SUS request for all other states. */ - gpio_set_level(GPIO_PMIC_SLP_SUS_L, gpio_get_level(GPIO_PCH_SLP_SUS_L)); + chipset_set_pmic_slp_sus_l(gpio_get_level(GPIO_PCH_SLP_SUS_L)); } #ifdef CONFIG_BOARD_HAS_RTC_RESET