diff options
Diffstat (limited to 'power/stoney.c')
-rw-r--r-- | power/stoney.c | 286 |
1 files changed, 0 insertions, 286 deletions
diff --git a/power/stoney.c b/power/stoney.c deleted file mode 100644 index 9bbfc75d33..0000000000 --- a/power/stoney.c +++ /dev/null @@ -1,286 +0,0 @@ -/* 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. - */ - -/* Stoney power sequencing module for Chrome EC */ - -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "ec_commands.h" -#include "gpio.h" -#include "hooks.h" -#include "lid_switch.h" -#include "power.h" -#include "power_button.h" -#include "system.h" -#include "timer.h" -#include "usb_charge.h" -#include "util.h" -#include "wireless.h" -#include "registers.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CHIPSET, outstr) -#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ##args) - -#define IN_S5_PGOOD POWER_SIGNAL_MASK(X86_S5_PGOOD) - -static int forcing_shutdown; /* Forced shutdown in progress? */ - -void chipset_force_shutdown(enum chipset_shutdown_reason reason) -{ - CPRINTS("%s()", __func__); - - if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) { - forcing_shutdown = 1; - power_button_pch_press(); - report_ap_reset(reason); - } -} - -static void chipset_force_g3(void) -{ - /* Disable system power ("*_A" rails) in G3. */ - gpio_set_level(GPIO_EN_PWR_A, 0); -} - -void chipset_reset(enum chipset_reset_reason reason) -{ - CPRINTS("%s: %d", __func__, reason); - - if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { - CPRINTS("Can't reset: SOC is off"); - return; - } - - report_ap_reset(reason); - /* - * Send a pulse to SYS_RST to trigger a warm reset. - */ - gpio_set_level(GPIO_SYS_RESET_L, 0); - usleep(32 * MSEC); - gpio_set_level(GPIO_SYS_RESET_L, 1); -} - -void chipset_throttle_cpu(int throttle) -{ - CPRINTS("%s(%d)", __func__, throttle); - if (IS_ENABLED(CONFIG_CPU_PROCHOT_ACTIVE_LOW)) - throttle = !throttle; - - if (chipset_in_state(CHIPSET_STATE_ON)) - gpio_set_level(GPIO_CPU_PROCHOT, throttle); -} - -void chipset_handle_espi_reset_assert(void) -{ - /* - * eSPI_Reset# pin being asserted without RSMRST# being asserted - * means there is an unexpected power loss (global reset event). - * In this case, check if the shutdown is forced by the EC (due - * to battery, thermal, or console command). The forced shutdown - * initiates a power button press that we need to release. - * - * NOTE: S5_PGOOD input is passed through to the RSMRST# output to - * the AP. - */ - if ((power_get_signals() & IN_S5_PGOOD) && forcing_shutdown) { - power_button_pch_release(); - forcing_shutdown = 0; - } -} - -enum power_state power_chipset_init(void) -{ - /* Pause in S5 when shutting down. */ - power_set_pause_in_s5(1); - - /* - * If we're switching between images without rebooting, see if the x86 - * is already powered on; if so, leave it there instead of cycling - * through G3. - */ - if (system_jumped_to_this_image()) { - if (gpio_get_level(GPIO_S0_PGOOD)) { - /* Disable idle task deep sleep when in S0. */ - disable_sleep(SLEEP_MASK_AP_RUN); - - CPRINTS("already in S0"); - return POWER_S0; - } - - CPRINTS("forcing G3"); - chipset_force_g3(); - } - return POWER_G3; -} - -static void handle_pass_through(enum gpio_signal pin_in, - enum gpio_signal pin_out) -{ - /* - * Pass through asynchronously, as SOC may not react - * immediately to power changes. - */ - int in_level = gpio_get_level(pin_in); - int out_level = gpio_get_level(pin_out); - - /* - * Only pass through high S0_PGOOD (S0 power) when S5_PGOOD (S5 power) - * is also high (S0_PGOOD is pulled high in G3 when S5_PGOOD is low). - */ - if ((pin_in == GPIO_S0_PGOOD) && !gpio_get_level(GPIO_S5_PGOOD)) - in_level = 0; - - /* Nothing to do. */ - if (in_level == out_level) - return; - - /* - * SOC requires a delay of 1ms with stable power before - * asserting PWR_GOOD. - */ - if ((pin_in == GPIO_S0_PGOOD) && in_level) - msleep(1); - - gpio_set_level(pin_out, in_level); - - CPRINTS("Pass through %s: %d", gpio_get_name(pin_in), in_level); -} - -enum power_state power_handle_state(enum power_state state) -{ - handle_pass_through(GPIO_S5_PGOOD, GPIO_PCH_RSMRST_L); - - handle_pass_through(GPIO_S0_PGOOD, GPIO_PCH_SYS_PWROK); - - if (state == POWER_S5 && forcing_shutdown) { - power_button_pch_release(); - forcing_shutdown = 0; - } - - switch (state) { - case POWER_G3: - break; - - case POWER_G3S5: - /* Exit SOC G3 */ - /* Enable system power ("*_A" rails) in S5. */ - gpio_set_level(GPIO_EN_PWR_A, 1); - - /* - * Callback to do pre-initialization within the context of - * chipset task. - */ - if (IS_ENABLED(CONFIG_CHIPSET_HAS_PRE_INIT_CALLBACK)) - chipset_pre_init_callback(); - - if (power_wait_signals(IN_S5_PGOOD)) { - chipset_force_g3(); - return POWER_G3; - } - - CPRINTS("Exit SOC G3"); - - return POWER_S5; - - case POWER_S5: - if (!power_has_signals(IN_S5_PGOOD)) { - /* Required rail went away */ - return POWER_S5G3; - } else if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 1) { - /* Power up to next state */ - return POWER_S5S3; - } - break; - - case POWER_S5S3: - if (!power_has_signals(IN_S5_PGOOD)) { - /* Required rail went away */ - return POWER_S5G3; - } - - /* Call hooks now that rails are up */ - hook_notify(HOOK_CHIPSET_STARTUP); - - return POWER_S3; - - case POWER_S3: - if (!power_has_signals(IN_S5_PGOOD)) { - /* Required rail went away */ - return POWER_S5G3; - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1) { - /* Power up to next state */ - return POWER_S3S0; - } else if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 0) { - /* Power down to next state */ - return POWER_S3S5; - } - break; - - case POWER_S3S0: - if (!power_has_signals(IN_S5_PGOOD)) { - /* Required rail went away */ - return POWER_S5G3; - } - - /* Enable wireless */ - wireless_set_state(WIRELESS_ON); - - /* Call hooks now that rails are up */ - hook_notify(HOOK_CHIPSET_RESUME); - - /* - * Disable idle task deep sleep. This means that the low - * power idle task will not go into deep sleep while in S0. - */ - disable_sleep(SLEEP_MASK_AP_RUN); - - return POWER_S0; - - case POWER_S0: - if (!power_has_signals(IN_S5_PGOOD)) { - /* Required rail went away */ - return POWER_S5G3; - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 0) { - /* Power down to next state */ - return POWER_S0S3; - } - break; - - case POWER_S0S3: - /* Call hooks before we remove power rails */ - hook_notify(HOOK_CHIPSET_SUSPEND); - - /* Suspend wireless */ - wireless_set_state(WIRELESS_SUSPEND); - - /* - * Enable idle task deep sleep. Allow the low power idle task - * to go into deep sleep in S3 or lower. - */ - enable_sleep(SLEEP_MASK_AP_RUN); - - return POWER_S3; - - case POWER_S3S5: - /* Call hooks before we remove power rails */ - hook_notify(HOOK_CHIPSET_SHUTDOWN); - - /* Disable wireless */ - wireless_set_state(WIRELESS_OFF); - - return POWER_S5; - - case POWER_S5G3: - chipset_force_g3(); - - return POWER_G3; - - default: - break; - } - return state; -} |