summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /power
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14396.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/alderlake_slg4bd44540.c277
-rw-r--r--power/amd_x86.c524
-rw-r--r--power/apollolake.c183
-rw-r--r--power/braswell.c324
-rw-r--r--power/build.mk30
-rw-r--r--power/cannonlake.c139
-rw-r--r--power/cometlake-discrete.c416
-rw-r--r--power/cometlake.c211
-rw-r--r--power/common.c1117
-rw-r--r--power/ec_driven.c55
-rw-r--r--power/host_sleep.c269
-rw-r--r--power/icelake.c325
-rw-r--r--power/intel_x86.c679
-rw-r--r--power/mt817x.c818
-rw-r--r--power/mt8183.c639
-rw-r--r--power/mt8192.c543
-rw-r--r--power/qcom.c1169
-rw-r--r--power/rk3288.c577
-rw-r--r--power/rk3399.c610
-rw-r--r--power/sdm845.c882
-rw-r--r--power/skylake.c194
21 files changed, 0 insertions, 9981 deletions
diff --git a/power/alderlake_slg4bd44540.c b/power/alderlake_slg4bd44540.c
deleted file mode 100644
index e7ae9497a2..0000000000
--- a/power/alderlake_slg4bd44540.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Copyright 2021 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.
- */
-
-/*
- * This was originally copied form power/icelake.c (also used on TGL and
- * ADL) and adapted to support ADL designs using the Silergy SLG4BD44540
- * power sequencer chip.
- */
-
-#include "board_config.h"
-#include "chipset.h"
-#include "console.h"
-#include "gpio.h"
-#include "power.h"
-#include "power/alderlake_slg4bd44540.h"
-#include "power/intel_x86.h"
-#include "timer.h"
-
-/*
- * These delays are used by the brya power sequence reference design and
- * should be suitable for variants.
- */
-
-/* SEQ_EC_ALL_SYS_PG high to VCCST_PWRGD high delay */
-#define VCCST_PWRGD_DELAY_MS 2
-
-/* IMVP9_VRRDY high to PCH_PWROK high delay */
-#define PCH_PWROK_DELAY_MS 2
-
-/* SEQ_EC_ALL_SYS_PG high to EC_PCH_SYS_PWROK high delay */
-#define SYS_PWROK_DELAY_MS 45
-
-/* IMVP9_VRRDY high timeout */
-#define VRRDY_TIMEOUT_MS 50
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-#ifdef CONFIG_BRINGUP
-#define GPIO_SET_LEVEL(signal, value) \
- gpio_set_level_verbose(CC_CHIPSET, signal, value)
-#else
-#define GPIO_SET_LEVEL(signal, value) \
- gpio_set_level(signal, value)
-#endif
-
-/* The wait time is ~150 msec, allow for safety margin. */
-#define IN_PCH_SLP_SUS_WAIT_TIME_USEC (250 * MSEC)
-
-/* Power signals list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
- [X86_SLP_S0_DEASSERTED] = {
- .gpio = GPIO_PCH_SLP_S0_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH |
- POWER_SIGNAL_DISABLE_AT_BOOT,
- .name = "SLP_S0_DEASSERTED",
- },
- [X86_SLP_S3_DEASSERTED] = {
- .gpio = SLP_S3_SIGNAL_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_S3_DEASSERTED",
- },
- [X86_SLP_S4_DEASSERTED] = {
- .gpio = SLP_S4_SIGNAL_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_S4_DEASSERTED",
- },
- [X86_SLP_SUS_DEASSERTED] = {
- .gpio = GPIO_SLP_SUS_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_SUS_DEASSERTED",
- },
- [X86_RSMRST_L_PGOOD] = {
- .gpio = GPIO_PG_EC_RSMRST_ODL,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "RSMRST_L_PGOOD",
- },
- [X86_DSW_DPWROK] = {
- .gpio = GPIO_PG_EC_DSW_PWROK,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "DSW_DPWROK",
- },
- [X86_ALL_SYS_PGOOD] = {
- .gpio = GPIO_PG_EC_ALL_SYS_PWRGD,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "ALL_SYS_PWRGD",
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-__overridable int intel_x86_get_pg_ec_dsw_pwrok(void)
-{
- return gpio_get_level(GPIO_PG_EC_DSW_PWROK);
-}
-
-__overridable int intel_x86_get_pg_ec_all_sys_pwrgd(void)
-{
- return gpio_get_level(GPIO_PG_EC_ALL_SYS_PWRGD);
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- int timeout_ms = 50;
-
- CPRINTS("%s() %d", __func__, reason);
- report_ap_reset(reason);
-
- /* Turn off RMSRST_L to meet tPCH12 */
- board_before_rsmrst(0);
- GPIO_SET_LEVEL(GPIO_PCH_RSMRST_L, 0);
- board_after_rsmrst(0);
-
- /* Turn off S5 rails */
- GPIO_SET_LEVEL(GPIO_EN_S5_RAILS, 0);
-
- /*
- * TODO(b/179519791): Replace this wait with
- * power_wait_signals_timeout()
- */
- /* Now wait for DSW_PWROK and RSMRST_ODL to go away. */
- while (intel_x86_get_pg_ec_dsw_pwrok() &&
- gpio_get_level(GPIO_PG_EC_RSMRST_ODL) && (timeout_ms > 0)) {
- msleep(1);
- timeout_ms--;
- };
-
- if (!timeout_ms)
- CPRINTS("DSW_PWROK or RSMRST_ODL didn't go low! Assuming G3.");
-}
-
-void chipset_handle_espi_reset_assert(void)
-{
- /* No special handling needed. */
-}
-
-enum power_state chipset_force_g3(void)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
-
- return POWER_G3;
-}
-
-static void ap_off(void)
-{
- GPIO_SET_LEVEL(GPIO_VCCST_PWRGD_OD, 0);
- GPIO_SET_LEVEL(GPIO_PCH_PWROK, 0);
- GPIO_SET_LEVEL(GPIO_EC_PCH_SYS_PWROK, 0);
-}
-
-/*
- * We have asserted VCCST_PWRGO_OD, now wait for the IMVP9.1
- * to assert IMVP9_VRRDY_OD.
- *
- * Returns state of VRRDY.
- */
-
-static int wait_for_vrrdy(void)
-{
- int timeout_ms = VRRDY_TIMEOUT_MS;
- int vrrdy;
-
- for (; timeout_ms > 0; --timeout_ms) {
- vrrdy = gpio_get_level(GPIO_IMVP9_VRRDY_OD);
- if (vrrdy != 0)
- return 1;
- msleep(1);
- }
- return 0;
-}
-
-/*
- * The relationship between these signals is described in
- * Intel PDG #627205 rev. 0.81.
- *
- * tCPU16: >= 0
- * VCCST_PWRGD to PCH_PWROK
- * tPLT05: >= 0
- * SYS_ALL_PWRGD to SYS_PWROK
- * PCH_PWROK to SYS_PWROK
- */
-
-static void all_sys_pwrgd_pass_thru(void)
-{
- int sys_pg;
- int vccst_pg;
- int pch_pok;
- int sys_pok;
-
- sys_pg = gpio_get_level(GPIO_SEQ_EC_ALL_SYS_PG);
-
- if (IS_ENABLED(CONFIG_BRINGUP))
- CPRINTS("SEQ_EC_ALL_SYS_PG is %d", sys_pg);
-
- if (sys_pg == 0) {
- ap_off();
- return;
- }
-
- /* SEQ_EC_ALL_SYS_PG is asserted, enable VCCST_PWRGD_OD. */
-
- vccst_pg = gpio_get_level(GPIO_VCCST_PWRGD_OD);
- if (vccst_pg == 0) {
- msleep(VCCST_PWRGD_DELAY_MS);
- GPIO_SET_LEVEL(GPIO_VCCST_PWRGD_OD, 1);
- }
-
- /* Enable PCH_PWROK, gated by VRRDY. */
-
- pch_pok = gpio_get_level(GPIO_PCH_PWROK);
- if (pch_pok == 0) {
- if (wait_for_vrrdy() == 0) {
- CPRINTS("Timed out waiting for VRRDY, "
- "shutting AP off!");
- ap_off();
- return;
- }
- msleep(PCH_PWROK_DELAY_MS);
- GPIO_SET_LEVEL(GPIO_PCH_PWROK, 1);
- }
-
- /* Enable PCH_SYS_PWROK. */
-
- sys_pok = gpio_get_level(GPIO_EC_PCH_SYS_PWROK);
- if (sys_pok == 0) {
- msleep(SYS_PWROK_DELAY_MS);
- /* Check if we lost power while waiting. */
- sys_pg = gpio_get_level(GPIO_SEQ_EC_ALL_SYS_PG);
- if (sys_pg == 0) {
- CPRINTS("SEQ_EC_ALL_SYS_PG deasserted, "
- "shutting AP off!");
- ap_off();
- return;
- }
- GPIO_SET_LEVEL(GPIO_EC_PCH_SYS_PWROK, 1);
- /* PCH will now release PLT_RST */
- }
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- all_sys_pwrgd_pass_thru();
-
- common_intel_x86_handle_rsmrst(state);
-
- switch (state) {
-
- case POWER_G3S5:
- GPIO_SET_LEVEL(GPIO_EN_S5_RAILS, 1);
-
- if (power_wait_signals(IN_PGOOD_ALL_CORE))
- break;
-
- /*
- * Now wait for SLP_SUS_L to go high based on tPCH32. If this
- * signal doesn't go high within 250 msec then go back to G3.
- */
- if (power_wait_signals_timeout(IN_PCH_SLP_SUS_DEASSERTED,
- IN_PCH_SLP_SUS_WAIT_TIME_USEC) != EC_SUCCESS) {
- CPRINTS("SLP_SUS_L didn't go high! Going back to G3.");
- return POWER_S5G3;
- }
- break;
-
- case POWER_S5:
- /* If SLP_SUS_L is asserted, we're no longer in S5. */
- if (!power_has_signals(IN_PCH_SLP_SUS_DEASSERTED))
- return POWER_S5G3;
- break;
-
- default:
- break;
- }
-
- return common_intel_x86_power_handle_state(state);
-}
diff --git a/power/amd_x86.c b/power/amd_x86.c
deleted file mode 100644
index c1b7b2d853..0000000000
--- a/power/amd_x86.c
+++ /dev/null
@@ -1,524 +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.
- */
-
-/* AMD x86 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 "lpc.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_or_transitioning_to_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)
-{
- CPRINTS("%s: power_signal=0x%x", __func__, power_get_signals());
-
- if (!system_jumped_to_this_image())
- return POWER_G3;
- /*
- * We are here as RW. We need to handle the following cases:
- *
- * 1. Late sysjump by software sync. AP is in S0.
- * 2. Shutting down in recovery mode then sysjump by EFS2. AP is in S5
- * and expected to sequence down.
- * 3. Rebooting from recovery mode then sysjump by EFS2. AP is in S5
- * and expected to sequence up.
- * 4. RO jumps to RW from main() by EFS2. (a.k.a. power on reset, cold
- * reset). AP is in G3.
- */
- if (gpio_get_level(GPIO_S0_PGOOD)) {
- /* case #1. Disable idle task deep sleep when in S0. */
- disable_sleep(SLEEP_MASK_AP_RUN);
- CPRINTS("already in S0");
- return POWER_S0;
- }
- if (power_get_signals() & IN_S5_PGOOD) {
- /* case #2 & #3 */
- CPRINTS("already in S5");
- return POWER_S5;
- }
- /* case #4 */
- 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);
-
- if (IS_ENABLED(CONFIG_CHIPSET_X86_RSMRST_DELAY) &&
- (pin_out == GPIO_PCH_RSMRST_L) && in_level)
- msleep(10);
-
- gpio_set_level(pin_out, in_level);
-
- CPRINTS("Pass through %s: %d", gpio_get_name(pin_in), in_level);
-}
-
-#ifdef CONFIG_POWER_S0IX
-/*
- * Backup copies of SCI and SMI mask to preserve across S0ix suspend/resume
- * cycle. If the host uses S0ix, BIOS is not involved during suspend and resume
- * operations and hence SCI/SMI masks are programmed only once during boot-up.
- *
- * These backup variables are set whenever host expresses its interest to
- * enter S0ix and then lpc_host_event_mask for SCI and SMI are cleared. When
- * host resumes from S0ix, masks from backup variables are copied over to
- * lpc_host_event_mask for SCI and SMI.
- */
-static host_event_t backup_sci_mask;
-static host_event_t backup_smi_mask;
-
-/*
- * Clear host event masks for SMI and SCI when host is entering S0ix. This is
- * done to prevent any SCI/SMI interrupts when the host is in suspend. Since
- * BIOS is not involved in the suspend path, EC needs to take care of clearing
- * these masks.
- */
-static void lpc_s0ix_suspend_clear_masks(void)
-{
- backup_sci_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
- backup_smi_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI);
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, 0);
- lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, 0);
-}
-
-/*
- * Restore host event masks for SMI and SCI when host exits S0ix. This is done
- * because BIOS is not involved in the resume path and so EC needs to restore
- * the masks from backup variables.
- */
-static void lpc_s0ix_resume_restore_masks(void)
-{
- /*
- * No need to restore SCI/SMI masks if both backup_sci_mask and
- * backup_smi_mask are zero. This indicates that there was a failure to
- * enter S0ix(SLP_S0# assertion) and hence SCI/SMI masks were never
- * backed up.
- */
- if (!backup_sci_mask && !backup_smi_mask)
- return;
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, backup_sci_mask);
- lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, backup_smi_mask);
-
- backup_sci_mask = backup_smi_mask = 0;
-}
-
-static void lpc_s0ix_hang_detected(void)
-{
- /*
- * Wake up the AP so they don't just chill in a non-suspended state and
- * burn power. Overload a vaguely related event bit since event bits are
- * at a premium. If the system never entered S0ix, then manually set the
- * wake mask to pretend it did, so that the hang detect event wakes the
- * system.
- */
- if (power_get_state() == POWER_S0) {
- host_event_t sleep_wake_mask;
-
- get_lazy_wake_mask(POWER_S0ix, &sleep_wake_mask);
- lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, sleep_wake_mask);
- }
-
- CPRINTS("Warning: Detected sleep hang! Waking host up!");
- host_set_single_event(EC_HOST_EVENT_HANG_DETECT);
-}
-
-static void handle_chipset_suspend(void)
-{
- /* Clear masks before any hooks are run for suspend. */
- lpc_s0ix_suspend_clear_masks();
-}
-DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, handle_chipset_suspend, HOOK_PRIO_FIRST);
-
-static void handle_chipset_reset(void)
-{
- if (chipset_in_state(CHIPSET_STATE_STANDBY)) {
- CPRINTS("chipset reset: exit s0ix");
- power_reset_host_sleep_state();
- task_wake(TASK_ID_CHIPSET);
- }
-}
-DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST);
-
-void power_reset_host_sleep_state(void)
-{
- power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET);
- sleep_reset_tracking();
- power_chipset_handle_host_sleep_event(HOST_SLEEP_EVENT_DEFAULT_RESET,
- NULL);
-}
-
-#endif /* CONFIG_POWER_S0IX */
-
-#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
-
-__overridable void power_board_handle_host_sleep_event(
- enum host_sleep_event state)
-{
- /* Default weak implementation -- no action required. */
-}
-
-__override void power_chipset_handle_host_sleep_event(
- enum host_sleep_event state,
- struct host_sleep_event_context *ctx)
-{
- power_board_handle_host_sleep_event(state);
-
-#ifdef CONFIG_POWER_S0IX
- if (state == HOST_SLEEP_EVENT_S0IX_SUSPEND) {
- /*
- * Indicate to power state machine that a new host event for
- * s0ix/s3 suspend has been received and so chipset suspend
- * notification needs to be sent to listeners.
- */
- sleep_set_notify(SLEEP_NOTIFY_SUSPEND);
-
- sleep_start_suspend(ctx, lpc_s0ix_hang_detected);
- power_signal_enable_interrupt(GPIO_PCH_SLP_S0_L);
- } else if (state == HOST_SLEEP_EVENT_S0IX_RESUME) {
- /*
- * Wake up chipset task and indicate to power state machine that
- * listeners need to be notified of chipset resume.
- */
- sleep_set_notify(SLEEP_NOTIFY_RESUME);
- task_wake(TASK_ID_CHIPSET);
- lpc_s0ix_resume_restore_masks();
- power_signal_disable_interrupt(GPIO_PCH_SLP_S0_L);
- sleep_complete_resume(ctx);
- /*
- * If the sleep signal timed out and never transitioned, then
- * the wake mask was modified to its suspend state (S0ix), so
- * that the event wakes the system. Explicitly restore the wake
- * mask to its S0 state now.
- */
- power_update_wake_mask();
- } else if (state == HOST_SLEEP_EVENT_DEFAULT_RESET) {
- power_signal_disable_interrupt(GPIO_PCH_SLP_S0_L);
- }
-#endif /* CONFIG_POWER_S0IX */
-}
-#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */
-
-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);
-
-#ifdef CONFIG_POWER_S0IX
- /*
- * Clearing the S0ix flag on the path to S0
- * to handle any reset conditions.
- */
- power_reset_host_sleep_state();
-#endif
- 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);
-
- lpc_s3_resume_clear_masks();
-
- /* 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;
- }
-#ifdef CONFIG_POWER_S0IX
- /*
- * SLP_S0 may assert in system idle scenario without a kernel
- * freeze call. This may cause interrupt storm since there is
- * no freeze/unfreeze of threads/process in the idle scenario.
- * Ignore the SLP_S0 assertions in idle scenario by checking
- * the host sleep state.
- */
- else if (power_get_host_sleep_state()
- == HOST_SLEEP_EVENT_S0IX_SUSPEND &&
- gpio_get_level(GPIO_PCH_SLP_S0_L) == 0) {
- return POWER_S0S0ix;
- }
-#endif
- else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 0) {
- /* Power down to next state */
- return POWER_S0S3;
- }
-#ifdef CONFIG_POWER_S0IX
- /*
- * Call hooks only if we haven't notified listeners of S0ix
- * resume.
- */
- sleep_notify_transition(SLEEP_NOTIFY_RESUME,
- HOOK_CHIPSET_RESUME);
-#endif
- 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);
-
-#ifdef CONFIG_POWER_S0IX
- /* re-init S0ix flag */
- power_reset_host_sleep_state();
-#endif
- 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);
-
- /* Call hooks after we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-
- return POWER_S5;
-
- case POWER_S5G3:
- chipset_force_g3();
-
- return POWER_G3;
-
-#ifdef CONFIG_POWER_S0IX
- case POWER_S0ix:
- /* System in S0 only if SLP_S0 and SLP_S3 are de-asserted */
- if ((gpio_get_level(GPIO_PCH_SLP_S0_L) == 1) &&
- (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1)) {
- return POWER_S0ixS0;
- } else if (!power_has_signals(IN_S5_PGOOD)) {
- /* Lost power, start transition to G3 */
- return POWER_S0;
- }
-
- break;
-
- case POWER_S0S0ix:
- /*
- * Call hooks only if we haven't notified listeners of S0ix
- * suspend.
- */
- sleep_notify_transition(SLEEP_NOTIFY_SUSPEND,
- HOOK_CHIPSET_SUSPEND);
- sleep_suspend_transition();
-
- /*
- * Enable idle task deep sleep. Allow the low power idle task
- * to go into deep sleep in S0ix.
- */
- enable_sleep(SLEEP_MASK_AP_RUN);
- return POWER_S0ix;
-
- case POWER_S0ixS0:
- /*
- * 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);
-
- sleep_resume_transition();
- return POWER_S0;
-#endif /* CONFIG_POWER_S0IX */
- default:
- break;
- }
- return state;
-}
diff --git a/power/apollolake.c b/power/apollolake.c
deleted file mode 100644
index 2aaf7fc533..0000000000
--- a/power/apollolake.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Copyright 2016 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.
- */
-
-/* Apollolake chipset power control module for Chrome EC */
-
-#include "chipset.h"
-#include "console.h"
-#include "gpio.h"
-#include "power/intel_x86.h"
-#include "task.h"
-#include "timer.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-/*
- * force_shutdown is used to maintain chipset shutdown request. This request
- * needs to be handled from within the chipset task.
- */
-static int force_shutdown;
-
-/* Power signals list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
-#ifdef CONFIG_POWER_S0IX
- [X86_SLP_S0_N] = {
- GPIO_PCH_SLP_S0_L,
- POWER_SIGNAL_ACTIVE_HIGH | POWER_SIGNAL_DISABLE_AT_BOOT,
- "SLP_S0_DEASSERTED",
- },
-#endif
- [X86_SLP_S3_N] = {
- GPIO_PCH_SLP_S3_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SLP_S3_DEASSERTED",
- },
- [X86_SLP_S4_N] = {
- GPIO_PCH_SLP_S4_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SLP_S4_DEASSERTED",
- },
- [X86_SUSPWRDNACK] = {
- GPIO_SUSPWRDNACK,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SUSPWRDNACK_DEASSERTED",
- },
- [X86_ALL_SYS_PG] = {
- GPIO_ALL_SYS_PGOOD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "ALL_SYS_PGOOD",
- },
- [X86_RSMRST_N] = {
- GPIO_RSMRST_L_PGOOD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "RSMRST_L",
- },
- [X86_PGOOD_PP3300] = {
- GPIO_PP3300_PG,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP3300_PG",
- },
- [X86_PGOOD_PP5000] = {
- GPIO_PP5000_PG,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP5000_PG",
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-__attribute__((weak)) void chipset_do_shutdown(void)
-{
- /* Need to implement board specific shutdown */
-}
-
-static void internal_chipset_shutdown(void)
-{
- /*
- * UART buffer gets overwritten by other tasks if it is not explicitly
- * flushed before printing it on the console by same task. Hence, clean
- * up the UART buffer so that all the debug messages are printed on the
- * UART console before doing shutdown.
- */
- cflush();
-
- CPRINTS("%s()", __func__);
-
- force_shutdown = 0;
- chipset_do_shutdown();
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s: %d", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * This function is called from multiple tasks and hence it is racy! But
- * since things are going down hard, it does not matter if some task
- * misses out.
- */
- force_shutdown = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-
-enum power_state chipset_force_g3(void)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
-
- return POWER_G3;
-}
-
-void chipset_handle_espi_reset_assert(void)
-{
-}
-
-static void handle_all_sys_pgood(enum power_state state)
-{
- /*
- * Pass through asynchronously, as SOC may not react
- * immediately to power changes.
- */
- int in_level = gpio_get_level(GPIO_ALL_SYS_PGOOD);
- int out_level = gpio_get_level(GPIO_PCH_SYS_PWROK);
-
- /* Nothing to do. */
- if (in_level == out_level)
- return;
-
- gpio_set_level(GPIO_PCH_SYS_PWROK, in_level);
-
- CPRINTS("Pass through GPIO_ALL_SYS_PGOOD: %d", in_level);
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- enum power_state new_state;
-
- /* Process ALL_SYS_PGOOD state changes. */
- handle_all_sys_pgood(state);
-
- if (state == POWER_S5 && !power_has_signals(IN_PGOOD_ALL_CORE)) {
- /* Required rail went away */
- internal_chipset_shutdown();
-
- new_state = POWER_S5G3;
- goto rsmrst_handle;
-
- }
-
- /* If force shutdown is requested, perform that. */
- if (force_shutdown)
- internal_chipset_shutdown();
-
- new_state = common_intel_x86_power_handle_state(state);
-
-rsmrst_handle:
-
- /*
- * Process RSMRST_L state changes:
- * RSMRST_L de-assertion is passed to SoC only on G3S5 to S5 transition.
- * RSMRST_L is also checked in some states and, if asserted, will
- * force shutdown.
- */
- common_intel_x86_handle_rsmrst(new_state);
-
- return new_state;
-}
-
-/**
- * chipset check if PLTRST# is valid.
- *
- * @return non-zero if PLTRST# is valid, 0 if invalid.
- */
-int chipset_pltrst_is_valid(void)
-{
- /*
- * Invalid PLTRST# from SOC unless RSMRST#
- * from PMIC through EC to soc is deasserted.
- */
- return (gpio_get_level(GPIO_RSMRST_L_PGOOD) &&
- gpio_get_level(GPIO_PCH_RSMRST_L));
-}
diff --git a/power/braswell.c b/power/braswell.c
deleted file mode 100644
index 288092c795..0000000000
--- a/power/braswell.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/* Copyright 2014 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.
- */
-
-/* X86 braswell chipset power control 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 "lpc.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)
-
-/* Input state flags */
-#define IN_RSMRST_L_PWRGD POWER_SIGNAL_MASK(X86_RSMRST_L_PWRGD)
-#define IN_ALL_SYS_PWRGD POWER_SIGNAL_MASK(X86_ALL_SYS_PWRGD)
-#define IN_SLP_S3_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S3_DEASSERTED)
-#define IN_SLP_S4_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S4_DEASSERTED)
-
-/* All always-on supplies */
-#define IN_PGOOD_ALWAYS_ON (IN_RSMRST_L_PWRGD)
-/* All non-core power rails */
-#define IN_PGOOD_ALL_NONCORE (IN_ALL_SYS_PWRGD)
-/* All core power rails */
-#define IN_PGOOD_ALL_CORE (IN_ALL_SYS_PWRGD)
-/* Rails required for S5 */
-#define IN_PGOOD_S5 (IN_PGOOD_ALWAYS_ON)
-/* Rails required for S3 */
-#define IN_PGOOD_S3 (IN_PGOOD_ALWAYS_ON)
-/* Rails required for S0 */
-#define IN_PGOOD_S0 (IN_PGOOD_ALWAYS_ON | IN_PGOOD_ALL_NONCORE)
-
-/* All PM_SLP signals from PCH deasserted */
-#define IN_ALL_PM_SLP_DEASSERTED (IN_SLP_S3_DEASSERTED | IN_SLP_S4_DEASSERTED)
-/* All inputs in the right state for S0 */
-#define IN_ALL_S0 (IN_PGOOD_S0 | IN_ALL_PM_SLP_DEASSERTED)
-
-static int throttle_cpu; /* Throttle CPU? */
-static int forcing_shutdown; /* Forced shutdown in progress? */
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * Force power off. This condition will reset once the state machine
- * transitions to G3.
- */
-#ifndef CONFIG_PMIC
- gpio_set_level(GPIO_PCH_SYS_PWROK, 0);
-#endif
- gpio_set_level(GPIO_PCH_RSMRST_L, 0);
- forcing_shutdown = 1;
-}
-
-void chipset_reset(enum chipset_reset_reason reason)
-{
- CPRINTS("%s: %d", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * Send a reset pulse to the PCH. This just causes it to
- * assert INIT# to the CPU without dropping power or asserting
- * PLTRST# to reset the rest of the system. The PCH uses a 16
- * ms debounce time, so assert the signal for twice that.
- */
- gpio_set_level(GPIO_PCH_RCIN_L, 0);
- usleep(32 * MSEC);
- gpio_set_level(GPIO_PCH_RCIN_L, 1);
-}
-
-void chipset_throttle_cpu(int throttle)
-{
-#ifdef CONFIG_CPU_PROCHOT_ACTIVE_LOW
- throttle = !throttle;
-#endif /* CONFIG_CPU_PROCHOT_ACTIVE_LOW */
- if (chipset_in_state(CHIPSET_STATE_ON))
- gpio_set_level(GPIO_CPU_PROCHOT, throttle);
-}
-
-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 ((power_get_signals() & IN_PGOOD_S0) == IN_PGOOD_S0) {
- /* Disable idle task deep sleep when in S0. */
- disable_sleep(SLEEP_MASK_AP_RUN);
-
- CPRINTS("already in S0");
- return POWER_S0;
- } else {
- /* Force all signals to their G3 states */
- CPRINTS("forcing G3");
- gpio_set_level(GPIO_PCH_SYS_PWROK, 0);
- gpio_set_level(GPIO_PCH_RSMRST_L, 0);
-
- /*wireless_set_state(WIRELESS_OFF);*/
- }
- }
-
- return POWER_G3;
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- switch (state) {
- case POWER_G3:
- break;
-
- case POWER_G3S5:
- /* Exit SOC G3 */
-#ifdef CONFIG_PMIC
- gpio_set_level(GPIO_PCH_SYS_PWROK, 1);
-#else
- gpio_set_level(GPIO_SUSPWRDNACK_SOC_EC, 0);
-#endif
- CPRINTS("Exit SOC G3");
-
- if (power_wait_signals(IN_PGOOD_S5)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
- return POWER_G3;
- }
-
- /* Deassert RSMRST# */
- gpio_set_level(GPIO_PCH_RSMRST_L, 1);
- return POWER_S5;
-
- case POWER_S5:
- /* Check for SLP S4 */
- if (gpio_get_level(GPIO_PCH_SLP_S4_L) == 1)
- return POWER_S5S3; /* Power up to next state */
- break;
-
- case POWER_S5S3:
-
- /* Call hooks now that rails are up */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
- return POWER_S3;
-
-
- case POWER_S3:
-
- /* Check for state transitions */
- if (!power_has_signals(IN_PGOOD_S3)) {
- /* Required rail went away */
- chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
- return POWER_S3S5;
- } 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_S4_L) == 0) {
- /* Power down to next state */
- return POWER_S3S5;
- }
- break;
-
- case POWER_S3S0:
- /* Enable wireless */
-
- /*wireless_set_state(WIRELESS_ON);*/
-
- if (!power_has_signals(IN_PGOOD_S3)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
-
- /*wireless_set_state(WIRELESS_OFF);*/
- return POWER_S3S5;
- }
-
- /* 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);
-
- /*
- * Wait 15 ms after all voltages good. 100 ms is only needed
- * for PCIe devices; mini-PCIe devices should need only 10 ms.
- */
- msleep(15);
-
- /*
- * Throttle CPU if necessary. This should only be asserted
- * when +VCCP is powered (it is by now).
- */
-#ifdef CONFIG_CPU_PROCHOT_ACTIVE_LOW
- gpio_set_level(GPIO_CPU_PROCHOT, !throttle_cpu);
-#else
- gpio_set_level(GPIO_CPU_PROCHOT, throttle_cpu);
-#endif /* CONFIG_CPU_PROCHOT_ACTIVE_LOW */
-
- /* Set SYS and CORE PWROK */
- gpio_set_level(GPIO_PCH_SYS_PWROK, 1);
-
- return POWER_S0;
-
-
- case POWER_S0:
-
- if (!power_has_signals(IN_PGOOD_ALWAYS_ON)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
- return POWER_S0S3;
- }
-
- if (!power_has_signals(IN_ALL_S0)) {
- return POWER_S0S3;
- }
-
- break;
- case POWER_S0S3:
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SUSPEND);
-
-#ifndef CONFIG_PMIC
- /* Clear SYS and CORE PWROK */
- gpio_set_level(GPIO_PCH_SYS_PWROK, 0);
-#endif
- /* Wait 40ns */
- udelay(1);
-
- /* 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);
-
- /*
- * Deassert prochot since CPU is off and we're about to drop
- * +VCCP.
- */
- gpio_set_level(GPIO_CPU_PROCHOT, 0);
-
- return POWER_S3;
-
- case POWER_S3S5:
-
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
-
- /*wireless_set_state(WIRELESS_OFF);*/
-
- /* Call hooks after we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-
- /* Start shutting down */
- return power_get_pause_in_s5() ? POWER_S5 : POWER_S5G3;
-
- case POWER_S5G3:
- /*
- * in case shutdown is already done by apshutdown
- * (or chipset_force_shutdown()), SOC already lost
- * power and can't assert PMC_SUSPWRDNACK any more.
- */
- if (forcing_shutdown) {
- /* Config pins for SOC G3 */
- gpio_config_module(MODULE_GPIO, 1);
-#ifndef CONFIG_PMIC
- gpio_set_level(GPIO_SUSPWRDNACK_SOC_EC, 1);
-#else
- gpio_set_level(GPIO_PCH_SYS_PWROK, 0);
-#endif
-
- forcing_shutdown = 0;
-
- CPRINTS("Enter SOC G3");
-
- return POWER_G3;
- }
-
- if (gpio_get_level(GPIO_PCH_SUSPWRDNACK) == 1) {
- /* Assert RSMRST# */
- gpio_set_level(GPIO_PCH_RSMRST_L, 0);
-
- /* Config pins for SOC G3 */
- gpio_config_module(MODULE_GPIO, 1);
-
- /* Enter SOC G3 */
-#ifdef CONFIG_PMIC
- gpio_set_level(GPIO_PCH_SYS_PWROK, 0);
- udelay(1);
- gpio_set_level(GPIO_PCH_RSMRST_L, 0);
-#else
- gpio_set_level(GPIO_SUSPWRDNACK_SOC_EC, 1);
-#endif
- CPRINTS("Enter SOC G3");
-
- return POWER_G3;
- } else {
- CPRINTS("waiting for PMC_SUSPWRDNACK to assert!");
- return POWER_S5;
- }
- }
- return state;
-}
diff --git a/power/build.mk b/power/build.mk
deleted file mode 100644
index e2b86a055e..0000000000
--- a/power/build.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- makefile -*-
-# Copyright 2013 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.
-#
-# Power management for application processor and peripherals
-#
-
-power-$(CONFIG_CHIPSET_ALDERLAKE_SLG4BD44540)+=alderlake_slg4bd44540.o
-power-$(CONFIG_CHIPSET_ALDERLAKE_SLG4BD44540)+=intel_x86.o
-power-$(CONFIG_CHIPSET_APL_GLK)+=apollolake.o intel_x86.o
-power-$(CONFIG_CHIPSET_BRASWELL)+=braswell.o
-power-$(CONFIG_CHIPSET_CANNONLAKE)+=cannonlake.o intel_x86.o
-power-$(CONFIG_CHIPSET_COMETLAKE)+=cometlake.o intel_x86.o
-power-$(CONFIG_CHIPSET_COMETLAKE_DISCRETE)+=cometlake-discrete.o intel_x86.o
-power-$(CONFIG_CHIPSET_ECDRIVEN)+=ec_driven.o
-power-$(CONFIG_CHIPSET_ICELAKE)+=icelake.o intel_x86.o
-power-$(CONFIG_CHIPSET_MT817X)+=mt817x.o
-power-$(CONFIG_CHIPSET_MT8183)+=mt8183.o
-power-$(CONFIG_CHIPSET_MT8192)+=mt8192.o
-power-$(CONFIG_CHIPSET_CEZANNE)+=amd_x86.o
-power-$(CONFIG_CHIPSET_RK3288)+=rk3288.o
-power-$(CONFIG_CHIPSET_RK3399)+=rk3399.o
-power-$(CONFIG_CHIPSET_SC7180)+=qcom.o
-power-$(CONFIG_CHIPSET_SC7280)+=qcom.o
-power-$(CONFIG_CHIPSET_SDM845)+=sdm845.o
-power-$(CONFIG_CHIPSET_SKYLAKE)+=skylake.o intel_x86.o
-power-$(CONFIG_CHIPSET_STONEY)+=amd_x86.o
-power-$(CONFIG_POWER_COMMON)+=common.o
-power-$(CONFIG_POWER_TRACK_HOST_SLEEP_STATE)+=host_sleep.o
diff --git a/power/cannonlake.c b/power/cannonlake.c
deleted file mode 100644
index 392db669df..0000000000
--- a/power/cannonlake.c
+++ /dev/null
@@ -1,139 +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.
- */
-
-/* Cannonlake chipset power control module for Chrome EC */
-
-#include "chipset.h"
-#include "console.h"
-#include "gpio.h"
-#include "power.h"
-#include "power/cannonlake.h"
-#include "power/intel_x86.h"
-#include "power_button.h"
-#include "task.h"
-#include "timer.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-static int forcing_shutdown; /* Forced shutdown in progress? */
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
-
- /*
- * Force off. Sending a reset command to the PMIC will power off
- * the EC, so simulate a long power button press instead. This
- * condition will reset once the state machine transitions to G3.
- * Consider reducing the latency here by changing the power off
- * hold time on the PMIC.
- */
- if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
- report_ap_reset(reason);
- forcing_shutdown = 1;
- power_button_pch_press();
- }
-}
-
-void chipset_handle_espi_reset_assert(void)
-{
- /*
- * If eSPI_Reset# pin is asserted without SLP_SUS# being asserted, then
- * it means that there is an unexpected power loss (global reset
- * event). In this case, check if shutdown was being forced by pressing
- * power button. If yes, release power button.
- */
- if ((power_get_signals() & IN_PCH_SLP_SUS_DEASSERTED) &&
- forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
-}
-
-enum power_state chipset_force_g3(void)
-{
- int timeout = 50;
- chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
-
- /* Turn off DSW load switch. */
- gpio_set_level(GPIO_EN_PP3300_DSW, 0);
-
- /* Now wait for DSW_PWROK to go away. */
- while (gpio_get_level(GPIO_PMIC_DPWROK) && (timeout > 0)) {
- msleep(1);
- timeout--;
- };
-
- if (!timeout)
- CPRINTS("DSW_PWROK didn't go low! Assuming G3.");
-
- return POWER_G3;
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- enum power_state new_state;
- int dswpwrok_in = gpio_get_level(GPIO_PMIC_DPWROK);
- static int dswpwrok_out = -1;
-
- /* Pass-through DSW_PWROK to CNL. */
- if (dswpwrok_in != dswpwrok_out) {
- CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in);
- gpio_set_level(GPIO_PCH_DSW_PWROK, dswpwrok_in);
- dswpwrok_out = dswpwrok_in;
- }
-
- common_intel_x86_handle_rsmrst(state);
-
- if (state == POWER_S5 && forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
-
- switch (state) {
- case POWER_G3:
- /* If SLP_SUS_L is deasserted, we're no longer in G3. */
- if (power_has_signals(IN_PCH_SLP_SUS_DEASSERTED))
- return POWER_S5;
- break;
-
- case POWER_G3S5:
- /* Turn on the PP3300_DSW rail. */
- gpio_set_level(GPIO_EN_PP3300_DSW, 1);
- if (power_wait_signals(IN_PGOOD_ALL_CORE))
- break;
-
- /* Pass thru DSWPWROK again since we changed it. */
- dswpwrok_in = gpio_get_level(GPIO_PMIC_DPWROK);
- gpio_set_level(GPIO_PCH_DSW_PWROK, dswpwrok_in);
- CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in);
- dswpwrok_out = dswpwrok_in;
-
- /* Enable the 5V rail. */
-#ifdef CONFIG_POWER_PP5000_CONTROL
- power_5v_enable(task_get_current(), 1);
-#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
- gpio_set_level(GPIO_EN_PP5000, 1);
-#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
- break;
-
- case POWER_S5G3:
- /* Turn off the 5V rail. */
-#ifdef CONFIG_POWER_PP5000_CONTROL
- power_5v_enable(task_get_current(), 0);
-#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
- gpio_set_level(GPIO_EN_PP5000, 0);
-#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
- break;
-
- default:
- break;
- };
-
- new_state = common_intel_x86_power_handle_state(state);
-
- return new_state;
-}
diff --git a/power/cometlake-discrete.c b/power/cometlake-discrete.c
deleted file mode 100644
index a22e32a69f..0000000000
--- a/power/cometlake-discrete.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* Copyright 2019 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.
- */
-
-/*
- * Chrome EC chipset power control for Cometlake with platform-controlled
- * discrete sequencing.
- */
-
-#include "adc.h"
-#include "chipset.h"
-#include "console.h"
-#include "gpio.h"
-#include "power.h"
-#include "power/intel_x86.h"
-#include "power_button.h"
-#include "task.h"
-#include "timer.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ##args)
-
-/* Power signals list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
- [PP5000_A_PGOOD] = {
- GPIO_PG_PP5000_A_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP5000_A_PGOOD",
- },
- [PP1800_A_PGOOD] = {
- GPIO_PG_PP1800_A_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP1800_A_PGOOD",
- },
- [VPRIM_CORE_A_PGOOD] = {
- GPIO_PG_VPRIM_CORE_A_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "VPRIM_CORE_A_PGOOD",
- },
- [PP1050_A_PGOOD] = {
- GPIO_PG_PP1050_A_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP1050_A_PGOOD",
- },
- [OUT_PCH_RSMRST_DEASSERTED] = {
- GPIO_PCH_RSMRST_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "OUT_PCH_RSMRST_DEASSERTED",
- },
- [X86_SLP_S4_DEASSERTED] = {
- SLP_S4_SIGNAL_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SLP_S4_DEASSERTED",
- },
- [PP2500_DRAM_PGOOD] = {
- GPIO_PG_PP2500_DRAM_U_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP2500_DRAM_PGOOD",
- },
- [PP1200_DRAM_PGOOD] = {
- GPIO_PG_PP1200_U_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP1200_DRAM_PGOOD",
- },
- [X86_SLP_S3_DEASSERTED] = {
- SLP_S3_SIGNAL_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SLP_S3_DEASSERTED",
- },
- [PP950_VCCIO_PGOOD] = {
- GPIO_PG_PP950_VCCIO_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PP950_VCCIO_PGOOD",
- },
- [X86_SLP_S0_DEASSERTED] = {
- GPIO_PCH_SLP_S0_L,
- POWER_SIGNAL_ACTIVE_HIGH | POWER_SIGNAL_DISABLE_AT_BOOT,
- "SLP_S0_DEASSERTED",
- },
- [CPU_C10_GATE_DEASSERTED] = {
- GPIO_CPU_C10_GATE_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "CPU_C10_GATE_DEASSERTED",
- },
- [IMVP8_READY] = {
- GPIO_IMVP8_VRRDY_OD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "IMVP8_READY",
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-/*
- * The EC is responsible for most of the power-on sequence with this driver,
- * enabling rails and waiting for power-good signals from regulators before
- * continuing. The power sequencing works as follows.
- *
- * 1. From G3 (all-off), power is applied and EC power supplies come up.
- * The power button task kicks off platform power-up as desired.
- * 2. Power up the platform to reach S5
- * a. Enable PP5000_A and wait for PP5000_A_PGOOD.
- * b. Enable PP3300_A (EN_ROA_RAILS).
- * c. Wait for PP3300_A power good. This regulator doesn't provide a power
- * good output, so the EC monitors ADC_SNS_PP3300.
- * d. Enable PP1800_A and wait for PP1800_A_PGOOD.
- * e. PP1800_A_PGOOD automatically enables PPVAR_VPRIM_CORE_A, which receives
- * power from PP3300_A (hence PP3300_A must precede PP1800_A, even though
- * PP1800_A draws power from PP3300_G which is guaranteed to already be on)
- * f. PPVAR_VPRIM_CORE_A_PGOOD automatically enables PP1050_A
- * g. Wait for PP1050_A_PGOOD, indicating that both PPVAR_VPRIM_CORE_A and
- * PP1050_A are good.
- * h. Wait 10ms to satisfy tPCH03, then bring the PCH out of reset by
- * deasserting RSMRST.
- * 3. The PCH controls transition from S5 up to S3 and higher-power states.
- * a. PCH deasserts SLP_S4, automatically turning on PP2500_DRAM_U and
- * PP1200_DRAM_U.
- * b. Wait for PP2500_DRAM_PGOOD and PP1200_DRAM_PGOOD.
- * 4. PCH deasserts SLP_S3 to switch to S0
- * a. SLP_S3 transition automatically enables PP1050_ST_S.
- * b. Wait for PP1050_ST_S good. The power good output from this regulator is
- * not connected, so the EC monitors ADC_SNS_PP1050_ST_S.
- * c. Turn on EN_S0_RAILS (enabling PP1200_PLLOC and PP1050_STG).
- * VCCIO must not ramp up before VCCST, VCCSTG and memory rails are good
- * (PDG figure 424, note 14).
- * d. Wait 2ms (for EN_S0_RAILS load switches to turn on).
- * e. Enable PP950_VCCIO.
- * f. Wait for PG_PP950_VCCIO. Although the PCH may be asserting CPU_C10_GATED
- * which holds the VCCIO regulator in a low-power mode, the regulator will
- * turn on normally and assert power good then drop into low power mode
- * and continue asserting power good.
- * 5. Transition fully to S0 following SLP_S0
- * a. Assert VCCST_PWRGD. This notionally tracks PP1050_ST_S but must be
- * deasserted in S3 and lower.
- * b. Enable IMVP8_VR.
- * c. Wait 2ms.
- * d. Assert SYS_PWROK.
- * e. Wait for IMVP8_VRRDY.
- * f. Wait 2ms.
- * g. Assert PCH_PWROK.
- *
- * When CPU_C10_GATED is asserted, we are free to disable PP1200_PLLOC and
- * PP1050_STG by deasserting EN_S0_RAILS to save some power. VCCIO is
- * automatically placed in low-power mode by CPU_C10_GATED, and no further
- * action is required- power-good signals will not change, just the relevant
- * load switches (which are specified to meet the platform's minimum turn-on
- * time when CPU_C10_GATED is deasserted again) are turned off. This gating is
- * done asynchronously directly in the interrupt handler because its timing is
- * very tight.
- *
- * For further reference, Figure 421 and Table 370 in the Comet Lake U PDG
- * summarizes platform power rail requirements in a reasonably easy-to-digest
- * manner, while section 12.11 (containing those diagrams) details the required
- * operation.
- */
-
-/*
- * Reverse of S0->S3 transition.
- *
- * This is a separate function so it can be reused when forcing shutdown due to
- * power failure or other reasons.
- *
- * This function may be called from an ISR (slp_s3_interrupt) so must not
- * assume that it's running in a regular task.
- */
-static void shutdown_s0_rails(void)
-{
- board_enable_s0_rails(0);
- /*
- * Deassert VCCST_PG as early as possible to satisfy tCPU22; VDDQ is
- * derived directly from SLP_S3.
- */
- gpio_set_level(GPIO_VCCST_PG_OD, 0);
- gpio_set_level(GPIO_EC_PCH_PWROK, 0);
- gpio_set_level(GPIO_EC_PCH_SYS_PWROK, 0);
- gpio_set_level(GPIO_EN_IMVP8_VR, 0);
- gpio_set_level(GPIO_EN_S0_RAILS, 0);
- /*
- * * tPCH10: PCH_PWROK to VCCIO off >400ns (but only on unexpected
- * power-down)
- * * tPLT18: SLP_S3_L to VCCIO disable <200us
- *
- * tPCH10 is only 7 CPU cycles at 16 MHz so we should satisfy that
- * minimum time with no extra code, and sleeping is likely to cause
- * a delay that exceeds tPLT18.
- */
- gpio_set_level(GPIO_EN_PP950_VCCIO, 0);
-}
-
-/*
- * Reverse of G3->S5 transition.
- *
- * This is a separate function so it can be reused when forcing shutdown due to
- * power failure or other reasons.
- */
-static void shutdown_s5_rails(void)
-{
- gpio_set_level(GPIO_PCH_RSMRST_L, 0);
- /* tPCH12: RSMRST to VCCPRIM (PPVAR_VPRIM_CORE_A) off >400ns */
- usleep(1);
- gpio_set_level(GPIO_EN_PP1800_A, 0);
- gpio_set_level(GPIO_EN_ROA_RAILS, 0);
-#ifdef CONFIG_POWER_PP5000_CONTROL
- power_5v_enable(task_get_current(), 0);
-#else
- gpio_set_level(GPIO_EN_PP5000_A, 0);
-#endif
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- shutdown_s0_rails();
- /* S3->S5 is automatic based on SLP_S3 driving memory rails. */
- shutdown_s5_rails();
-}
-
-void chipset_handle_espi_reset_assert(void) {}
-
-enum power_state chipset_force_g3(void)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
-
- return POWER_G3;
-}
-
-/*
- * Wait for a power rail on an analog channel to become good.
- *
- * @param channel ADC channel to read
- * @param min_voltage Minimum required voltage for rail (in mV)
- *
- * @return EC_SUCCESS, or non-zero if error.
- */
-static int power_wait_analog(enum adc_channel channel, int min_voltage)
-{
- timestamp_t deadline;
- int reading;
-
- /* One second timeout */
- deadline = get_time();
- deadline.val += SECOND;
-
- do {
- reading = adc_read_channel(channel);
- if (reading == ADC_READ_ERROR)
- return EC_ERROR_HW_INTERNAL;
- if (timestamp_expired(deadline, NULL))
- return EC_ERROR_TIMEOUT;
- } while (reading < min_voltage);
-
- return EC_SUCCESS;
-}
-
-/*
- * Force system power state if we time out waiting for a power rail to become
- * good.
- *
- * In general the new state is to transition down to the next lower-power state,
- * so if we time out in G3->S5 we return POWER_G3 to turn things off again and
- * if S3->S0 times out we return POWER_S3S5 for the same reason.
- *
- * Correct sequencing of rails that might already be enabled is handled by
- * chipset_force_shutdown(), so the caller of this function doesn't need to
- * clean up after itself.
- */
-static enum power_state pgood_timeout(enum power_state new_state)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
- return new_state;
-}
-
-/*
- * Called in the chipset task when power signal inputs change state.
- * If this doesn't request a different state, power_common_state handles it.
- *
- * @param state Current power state
- * @return New power state
- */
-enum power_state power_handle_state(enum power_state state)
-{
- switch (state) {
- case POWER_G3S5:
- if (intel_x86_wait_power_up_ok() != EC_SUCCESS) {
- chipset_force_shutdown(
- CHIPSET_SHUTDOWN_BATTERY_INHIBIT);
- return POWER_G3;
- }
- /* Power-up steps 2a-2h. */
-#ifdef CONFIG_POWER_PP5000_CONTROL
- power_5v_enable(task_get_current(), 1);
-#else
- gpio_set_level(GPIO_EN_PP5000_A, 1);
-#endif
- if (power_wait_signals(POWER_SIGNAL_MASK(PP5000_A_PGOOD)))
- return pgood_timeout(POWER_S5G3);
- gpio_set_level(GPIO_EN_ROA_RAILS, 1);
- if (power_wait_analog(ADC_SNS_PP3300, 3000) != EC_SUCCESS)
- return pgood_timeout(POWER_S5G3);
- gpio_set_level(GPIO_EN_PP1800_A, 1);
- if (power_wait_signals(POWER_SIGNAL_MASK(PP1800_A_PGOOD) |
- POWER_SIGNAL_MASK(PP1050_A_PGOOD)))
- return pgood_timeout(POWER_S5G3);
- msleep(10); /* tPCH03: VCCPRIM good -> RSMRST >10ms */
- gpio_set_level(GPIO_PCH_RSMRST_L, 1);
- break;
-
- case POWER_S5G3:
- shutdown_s5_rails();
- break;
-
- case POWER_S5S3:
- /* Power-up steps 3a-3b. */
- if (power_wait_signals(POWER_SIGNAL_MASK(PP2500_DRAM_PGOOD) |
- POWER_SIGNAL_MASK(PP1200_DRAM_PGOOD)))
- return pgood_timeout(POWER_S3S5);
- break;
-
- case POWER_S3S0:
- /* Power-up steps 4a-4f. */
- if (power_wait_analog(ADC_SNS_PP1050, 1000) != EC_SUCCESS)
- return pgood_timeout(POWER_S3S5);
- gpio_set_level(GPIO_EN_S0_RAILS, 1);
- msleep(2);
- gpio_set_level(GPIO_EN_PP950_VCCIO, 1);
- if (power_wait_signals(POWER_SIGNAL_MASK(PP950_VCCIO_PGOOD)))
- return pgood_timeout(POWER_S3S5);
-
- /* Power-up steps 5a-5h */
- gpio_set_level(GPIO_VCCST_PG_OD, 1);
- gpio_set_level(GPIO_EN_IMVP8_VR, 1);
- msleep(2);
- gpio_set_level(GPIO_EC_PCH_SYS_PWROK, 1);
- if (power_wait_signals(POWER_SIGNAL_MASK(IMVP8_READY)))
- return pgood_timeout(POWER_S3S5);
- msleep(2);
- gpio_set_level(GPIO_EC_PCH_PWROK, 1);
-
- board_enable_s0_rails(1);
- break;
-
- case POWER_S0S3:
- /*
- * Handled in the slp_s3_interrupt fast path, but also run
- * here in case we miss the interrupt somehow.
- */
- shutdown_s0_rails();
- break;
-
- case POWER_S5:
- /*
- * Return to G3 if S5 rails are not on, probably because of
- * a forced power-off.
- */
- if ((power_get_signals() & CHIPSET_G3S5_POWERUP_SIGNAL) !=
- CHIPSET_G3S5_POWERUP_SIGNAL)
- return POWER_S5G3;
- break;
-
- default:
- break;
- }
-
- /*
- * Power-up steps 3a-3b (S5->S3 via IN_PGOOD_ALL_CORE) plus general
- * bookkeeping.
- */
- return common_intel_x86_power_handle_state(state);
-}
-
-#ifdef CONFIG_VBOOT_EFS
-/*
- * Called in main() to ensure chipset power is in a good state.
- *
- * This may be useful because EC reset could happen under unexpected
- * conditions and we want to ensure that if the AP is wedged for some
- * reason (for instance) we unwedge it before continuing.
- *
- * Because power sequencing here is all EC-controlled and this is called
- * as part of the init sequence, we don't need to do anything- EC reset
- * implies power sequencing is all-off and we don't have any external
- * PMIC to synchronize state with.
- */
-void chipset_handle_reboot(void) {}
-#endif /* CONFIG_VBOOT_EFS */
-
-void c10_gate_interrupt(enum gpio_signal signal)
-{
- /*
- * Per PDG, gate VccSTG and VCCIO on (SLP_S3_L && CPU_C10_GATE_L).
- *
- * When in S3 we let the state machine do it since timing is less
- * critical; when in S0/S0ix we do it here because timing is very
- * tight.
- */
- if (board_is_c10_gate_enabled() && gpio_get_level(GPIO_SLP_S3_L)) {
- int enable_core = gpio_get_level(GPIO_CPU_C10_GATE_L);
-
- gpio_set_level(GPIO_EN_S0_RAILS, enable_core);
- }
-
- return power_signal_interrupt(signal);
-}
-
-void slp_s3_interrupt(enum gpio_signal signal)
-{
- if (!gpio_get_level(GPIO_SLP_S3_L)
- && chipset_in_state(CHIPSET_STATE_ON)) {
- /* Falling edge on SLP_S3_L means dropping to S3 from S0 */
- shutdown_s0_rails();
- }
-
- return power_signal_interrupt(signal);
-}
diff --git a/power/cometlake.c b/power/cometlake.c
deleted file mode 100644
index 1b73bcc296..0000000000
--- a/power/cometlake.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Copyright 2019 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.
- */
-
-/* Cometlake chipset power control module for Chrome EC */
-
-#include "chipset.h"
-#include "console.h"
-#include "gpio.h"
-#include "power.h"
-#include "power/intel_x86.h"
-#include "power_button.h"
-#include "task.h"
-#include "timer.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-/* Power signals list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
- [X86_SLP_S0_DEASSERTED] = {
- .gpio = GPIO_PCH_SLP_S0_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH |
- POWER_SIGNAL_DISABLE_AT_BOOT,
- .name = "SLP_S0_DEASSERTED",
- },
- [X86_SLP_S3_DEASSERTED] = {
- .gpio = SLP_S3_SIGNAL_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_S3_DEASSERTED",
- },
- [X86_SLP_S4_DEASSERTED] = {
- .gpio = SLP_S4_SIGNAL_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_S4_DEASSERTED",
- },
- [X86_RSMRST_L_PGOOD] = {
- .gpio = GPIO_RSMRST_L_PGOOD,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "RSMRST_L_PGOOD",
- },
- [X86_PP5000_A_PGOOD] = {
- .gpio = GPIO_PP5000_A_PG_OD,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "PP5000_A_PGOOD",
- },
- [X86_ALL_SYS_PGOOD] = {
- .gpio = GPIO_PG_EC_ALL_SYS_PWRGD,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "ALL_SYS_PWRGD",
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-static int forcing_shutdown; /* Forced shutdown in progress? */
-
-/* Default no action, overwrite it in board.c if necessary*/
-__overridable void board_chipset_forced_shutdown(void)
-{
- return;
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- int timeout_ms = 50;
-
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /* Turn off RSMRST_L to meet tPCH12 */
- gpio_set_level(GPIO_PCH_RSMRST_L, 0);
-
- /* Turn off A (except PP5000_A) rails*/
- gpio_set_level(GPIO_EN_A_RAILS, 0);
-
-#ifdef CONFIG_POWER_PP5000_CONTROL
- /* Issue a request to turn off the rail. */
- power_5v_enable(task_get_current(), 0);
-#else
- /* Turn off PP5000_A rail */
- gpio_set_level(GPIO_EN_PP5000_A, 0);
-#endif
-
- /* For b:143440730, stop checking GPIO_ALL_SYS_PGOOD if system is
- * already force to G3.
- */
- board_chipset_forced_shutdown();
-
- /* Need to wait a min of 10 msec before check for power good */
- msleep(10);
-
- /* Now wait for PP5000_A and RSMRST_L to go low */
- while ((gpio_get_level(GPIO_PP5000_A_PG_OD) ||
- power_has_signals(IN_PGOOD_ALL_CORE)) && (timeout_ms > 0)) {
- msleep(1);
- timeout_ms--;
- };
-
- if (!timeout_ms)
- CPRINTS("PP5000_A rail still up! Assuming G3.");
-}
-
-void chipset_handle_espi_reset_assert(void)
-{
- /*
- * If eSPI_Reset# pin is asserted without SLP_SUS# being asserted, then
- * it means that there is an unexpected power loss (global reset
- * event). In this case, check if shutdown was being forced by pressing
- * power button. If yes, release power button.
- */
- if ((power_get_signals() & IN_PGOOD_ALL_CORE) && forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
-}
-
-enum power_state chipset_force_g3(void)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
-
- return POWER_G3;
-}
-
-/* Default no action, overwrite it in board.c if necessary*/
-__attribute__((weak)) void all_sys_pgood_check_reboot(void)
-{
- return;
-}
-
-/* Called by APL power state machine when transitioning from G3 to S5 */
-void chipset_pre_init_callback(void)
-{
- /* Enable 5.0V and 3.3V rails, and wait for Power Good */
-#ifdef CONFIG_POWER_PP5000_CONTROL
- power_5v_enable(task_get_current(), 1);
-#else
- /* Turn on PP5000_A rail */
- gpio_set_level(GPIO_EN_PP5000_A, 1);
-#endif
- /* Turn on A (except PP5000_A) rails*/
- gpio_set_level(GPIO_EN_A_RAILS, 1);
-
- /*
- * The status of the 5000_A rail is verifed in the calling function via
- * power_wait_signals() as PP5000_A_PGOOD is included in the
- * CHIPSET_G3S5_POWERUP_SIGNAL macro.
- */
-
- /* For b:143440730, system might hang-up before enter S0/S3. Check
- * GPIO_ALL_SYS_PGOOD here to make sure it will trigger every time.
- */
- all_sys_pgood_check_reboot();
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
-
- int all_sys_pwrgd_in;
- int all_sys_pwrgd_out;
-
- /*
- * Check if RSMRST_L signal state has changed and if so, pass the new
- * value along to the PCH. However, if the new transition of RSMRST_L
- * from the Sielgo is from low to high, then gate this transition to the
- * AP by the PP5000_A rail. If the new transition is from high to low,
- * then pass that through regardless of the PP5000_A value.
- *
- * The PP5000_A power good signal will float high if the
- * regulator is not powered, so checking both that the EN and the PG
- * signals are high.
- */
- if ((gpio_get_level(GPIO_PP5000_A_PG_OD) &&
- gpio_get_level(GPIO_EN_PP5000_A)) ||
- gpio_get_level(GPIO_PCH_RSMRST_L))
- common_intel_x86_handle_rsmrst(state);
-
- switch (state) {
-
- case POWER_S5:
- if (forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
- /* If RSMRST_L is asserted, we're no longer in S5. */
- if (!power_has_signals(IN_PGOOD_ALL_CORE))
- return POWER_S5G3;
- break;
-
- case POWER_S0:
- /*
- * Check value of PG_EC_ALL_SYS_PWRGD to see if PCH_SYS_PWROK
- * needs to be changed. If it's low->high transition, requires a
- * 2msec delay.
- */
- all_sys_pwrgd_in = gpio_get_level(GPIO_PG_EC_ALL_SYS_PWRGD);
- all_sys_pwrgd_out = gpio_get_level(GPIO_PCH_SYS_PWROK);
-
- if (all_sys_pwrgd_in != all_sys_pwrgd_out) {
- if (all_sys_pwrgd_in)
- msleep(2);
- gpio_set_level(GPIO_PCH_SYS_PWROK, all_sys_pwrgd_in);
- }
- break;
-
- default:
- break;
- }
-
- return common_intel_x86_power_handle_state(state);
-}
diff --git a/power/common.c b/power/common.c
deleted file mode 100644
index 0f83a2ce61..0000000000
--- a/power/common.c
+++ /dev/null
@@ -1,1117 +0,0 @@
-/* Copyright 2013 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.
- */
-
-/* Common functionality across all chipsets */
-
-#include "battery.h"
-#include "charge_state.h"
-#include "chipset.h"
-#include "common.h"
-#include "console.h"
-#include "display_7seg.h"
-#include "espi.h"
-#include "extpower.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "lpc.h"
-#include "power.h"
-#include "power/intel_x86.h"
-#include "power/qcom.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
-
-/*
- * Default timeout in us; if we've been waiting this long for an input
- * transition, just jump to the next state.
- */
-#define DEFAULT_TIMEOUT SECOND
-
-/* Timeout for dropping back from S5 to G3 in seconds */
-#ifdef CONFIG_CMD_S5_TIMEOUT
-static int s5_inactivity_timeout = 10;
-#else
-static const int s5_inactivity_timeout = 10;
-#endif
-
-static const char * const state_names[] = {
- "G3",
- "S5",
- "S3",
- "S0",
-#ifdef CONFIG_POWER_S0IX
- "S0ix",
-#endif
- "G3->S5",
- "S5->S3",
- "S3->S0",
- "S0->S3",
- "S3->S5",
- "S5->G3",
-#ifdef CONFIG_POWER_S0IX
- "S0ix->S0",
- "S0->S0ix",
-#endif
-};
-
-static uint32_t in_signals; /* Current input signal states (IN_PGOOD_*) */
-static uint32_t in_want; /* Input signal state we're waiting for */
-static uint32_t in_debug; /* Signal values which print debug output */
-
-static enum power_state state = POWER_G3; /* Current state */
-static int want_g3_exit; /* Should we exit the G3 state? */
-static uint64_t last_shutdown_time; /* When did we enter G3? */
-
-#ifdef CONFIG_HIBERNATE
-/* Delay before hibernating, in seconds */
-static uint32_t hibernate_delay = CONFIG_HIBERNATE_DELAY_SEC;
-#endif
-
-#ifdef CONFIG_POWER_SHUTDOWN_PAUSE_IN_S5
-/* Pause in S5 on shutdown? */
-static int pause_in_s5;
-#endif
-
-static bool want_reboot_ap_at_g3;/* Want to reboot AP from G3? */
-/* Want to reboot AP from G3 with delay? */
-static uint64_t reboot_ap_at_g3_delay;
-
-static enum ec_status
-host_command_reboot_ap_on_g3(struct host_cmd_handler_args *args)
-{
- const struct ec_params_reboot_ap_on_g3_v1 *cmd = args->params;
-
- /* Store request for processing at g3 */
- want_reboot_ap_at_g3 = true;
-
- switch (args->version) {
- case 0:
- break;
- case 1:
- /* Store user specified delay to wait in G3 state */
- reboot_ap_at_g3_delay = cmd->reboot_ap_at_g3_delay;
- break;
- default:
- return EC_RES_INVALID_PARAM;
- }
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_REBOOT_AP_ON_G3,
- host_command_reboot_ap_on_g3,
- EC_VER_MASK(0) | EC_VER_MASK(1));
-
-__overridable int power_signal_get_level(enum gpio_signal signal)
-{
- if (IS_ENABLED(CONFIG_HOST_ESPI_VW_POWER_SIGNAL)) {
- /* Check signal is from GPIOs or VWs */
- if (espi_signal_is_vw(signal))
- return espi_vw_get_wire(signal);
- }
- return gpio_get_level(signal);
-}
-
-int power_signal_disable_interrupt(enum gpio_signal signal)
-{
- if (IS_ENABLED(CONFIG_HOST_ESPI_VW_POWER_SIGNAL)) {
- /* Check signal is from GPIOs or VWs */
- if (espi_signal_is_vw(signal))
- return espi_vw_disable_wire_int(signal);
- }
- return gpio_disable_interrupt(signal);
-}
-
-int power_signal_enable_interrupt(enum gpio_signal signal)
-{
- if (IS_ENABLED(CONFIG_HOST_ESPI_VW_POWER_SIGNAL)) {
- /* Check signal is from GPIOs or VWs */
- if (espi_signal_is_vw(signal))
- return espi_vw_enable_wire_int(signal);
- }
- return gpio_enable_interrupt(signal);
-}
-
-int power_signal_is_asserted(const struct power_signal_info *s)
-{
- return power_signal_get_level(s->gpio) ==
- !!(s->flags & POWER_SIGNAL_ACTIVE_STATE);
-}
-
-#ifdef CONFIG_BRINGUP
-static const char *power_signal_get_name(enum gpio_signal signal)
-{
- if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) {
- /* Check signal is from GPIOs or VWs */
- if (espi_signal_is_vw(signal))
- return espi_vw_get_wire_name(signal);
- }
- return gpio_get_name(signal);
-}
-#endif
-
-/**
- * Update input signals mask
- */
-static void power_update_signals(void)
-{
- uint32_t inew = 0;
- const struct power_signal_info *s = power_signal_list;
- int i;
-
- for (i = 0; i < POWER_SIGNAL_COUNT; i++, s++) {
- if (power_signal_is_asserted(s))
- inew |= 1 << i;
- }
-
- if ((in_signals & in_debug) != (inew & in_debug))
- CPRINTS("power in 0x%04x", inew);
-
- in_signals = inew;
-}
-
-uint32_t power_get_signals(void)
-{
- return in_signals;
-}
-
-int power_has_signals(uint32_t want)
-{
- if ((in_signals & want) == want)
- return 1;
-
- CPRINTS("power lost input; wanted 0x%04x, got 0x%04x",
- want, in_signals & want);
-
- return 0;
-}
-
-int power_wait_signals(uint32_t want)
-{
- int ret = power_wait_signals_timeout(want, DEFAULT_TIMEOUT);
-
- if (ret == EC_ERROR_TIMEOUT)
- CPRINTS("power timeout on input; wanted 0x%04x, got 0x%04x",
- want, in_signals & want);
- return ret;
-}
-
-int power_wait_signals_timeout(uint32_t want, int timeout)
-{
- return power_wait_mask_signals_timeout(want, want, timeout);
-}
-
-int power_wait_mask_signals_timeout(uint32_t want, uint32_t mask, int timeout)
-{
- in_want = want;
- if (!mask)
- return EC_SUCCESS;
-
- while ((in_signals & mask) != in_want) {
- if (task_wait_event(timeout) == TASK_EVENT_TIMER) {
- power_update_signals();
- return EC_ERROR_TIMEOUT;
- }
- /*
- * TODO(crosbug.com/p/23772): should really shrink the
- * remaining timeout if we woke up but didn't have all the
- * signals we wanted. Also need to handle aborts if we're no
- * longer in the same state we were when we started waiting.
- */
- }
- return EC_SUCCESS;
-}
-
-void power_set_state(enum power_state new_state)
-{
- /* Record the time we go into G3 */
- if (new_state == POWER_G3)
- last_shutdown_time = get_time().val;
-
- /* Print out the RTC value to help correlate EC and kernel logs. */
- print_system_rtc(CC_CHIPSET);
-
- state = new_state;
-
- /*
- * Reset want_g3_exit flag here to prevent the situation that if the
- * error handler in POWER_S5S3 decides to force shutdown the system and
- * the flag is set, the system will go to G3 and then immediately exit
- * G3 again.
- */
- if (state == POWER_S5S3)
- want_g3_exit = 0;
-}
-
-enum power_state power_get_state(void)
-{
- return state;
-}
-
-#ifdef CONFIG_HOSTCMD_X86
-
-/* If host doesn't program s0ix lazy wake mask, use default s0ix mask */
-#define DEFAULT_WAKE_MASK_S0IX (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) | \
- EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE))
-
- /*
- * Set the wake mask according to the current power state:
- * 1. On transition to S0, wake mask is reset.
- * 2. In non-S0 states, active mask set by host gets a higher preference.
- * 3. If host has not set any active mask, then check if a lazy mask exists
- * for the current power state.
- * 4. If state is S0ix and no lazy or active wake mask is set, then use default
- * S0ix mask to be compatible with older BIOS versions.
- */
-
-void power_update_wake_mask(void)
-{
- host_event_t wake_mask;
- enum power_state state;
-
- state = power_get_state();
-
- if (state == POWER_S0)
- wake_mask = 0;
- else if (lpc_is_active_wm_set_by_host())
- return;
- else if (get_lazy_wake_mask(state, &wake_mask))
- return;
-#ifdef CONFIG_POWER_S0IX
- if ((state == POWER_S0ix) && (wake_mask == 0))
- wake_mask = DEFAULT_WAKE_MASK_S0IX;
-#endif
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, wake_mask);
-}
- /*
- * Set wake mask after power state has stabilized, 5ms after power state
- * change. The reason for making this a deferred call is to avoid race
- * conditions occurring from S0ix periodic wakes on the SoC.
- */
-
-static void power_update_wake_mask_deferred(void);
-DECLARE_DEFERRED(power_update_wake_mask_deferred);
-
-static void power_update_wake_mask_deferred(void)
-{
- hook_call_deferred(&power_update_wake_mask_deferred_data, -1);
- power_update_wake_mask();
-}
-
-static void power_set_active_wake_mask(void)
-{
- /*
- * Allow state machine to stabilize and update wake mask after 5msec. It
- * was observed that on platforms where host wakes up periodically from
- * S0ix for hardware book-keeping activities, there is a small window
- * where host is not really up and running software, but still SLP_S0#
- * is de-asserted and hence setting wake mask right away can cause user
- * wake events to be missed.
- *
- * Time for deferred callback was chosen to be 5msec based on the fact
- * that it takes ~2msec for the periodic wake cycle to complete on the
- * host for KBL.
- */
- hook_call_deferred(&power_update_wake_mask_deferred_data,
- 5 * MSEC);
-}
-
-#else
-static void power_set_active_wake_mask(void) { }
-#endif
-
-#ifdef CONFIG_HIBERNATE
-#ifdef CONFIG_BATTERY
-/*
- * Smart discharge system
- *
- * EC controls how the system discharges differently depending on the remaining
- * capacity and the expected hours to zero.
- *
- * 0 X1 X2 full
- * |----------|-------------------|------------------------------------|
- * cutoff stay-up safe
- *
- * EC cuts off the battery at X1 mAh and hibernates the system at X2 mAh. X1 and
- * X2 are derived from the cutoff and hibernation discharge rate, respectively.
- *
- * TODO: Learn discharge rates dynamically.
- *
- * TODO: Save sdzone in non-volatile memory and restore it when waking up from
- * cutoff or hibernation.
- */
-static struct smart_discharge_zone sdzone;
-
-static enum ec_status hc_smart_discharge(struct host_cmd_handler_args *args)
-{
- static uint16_t hours_to_zero;
- static struct discharge_rate drate;
- const struct ec_params_smart_discharge *p = args->params;
- struct ec_response_smart_discharge *r = args->response;
-
- if (p->flags & EC_SMART_DISCHARGE_FLAGS_SET) {
- int cap;
-
- if (battery_full_charge_capacity(&cap))
- return EC_RES_UNAVAILABLE;
-
- if (p->drate.hibern < p->drate.cutoff)
- /* Hibernation discharge rate should be always higher */
- return EC_RES_INVALID_PARAM;
- else if (p->drate.cutoff > 0 && p->drate.hibern > 0)
- drate = p->drate;
- else if (p->drate.cutoff == 0 && p->drate.hibern == 0)
- ; /* no-op. use the current drate. */
- else
- return EC_RES_INVALID_PARAM;
-
- /* Commit */
- hours_to_zero = p->hours_to_zero;
- sdzone.stayup = MIN(hours_to_zero * drate.hibern / 1000, cap);
- sdzone.cutoff = MIN(hours_to_zero * drate.cutoff / 1000,
- sdzone.stayup);
- }
-
- /* Return the effective values. */
- r->hours_to_zero = hours_to_zero;
- r->dzone = sdzone;
- r->drate = drate;
- args->response_size = sizeof(*r);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_SMART_DISCHARGE,
- hc_smart_discharge,
- EC_VER_MASK(0));
-
-__overridable enum critical_shutdown board_system_is_idle(
- uint64_t last_shutdown_time, uint64_t *target, uint64_t now)
-{
- int remain;
-
- if (now < *target)
- return CRITICAL_SHUTDOWN_IGNORE;
-
- if (battery_remaining_capacity(&remain)) {
- CPRINTS("SDC Failed to get remaining capacity");
- return CRITICAL_SHUTDOWN_HIBERNATE;
- }
-
- if (remain < sdzone.cutoff) {
- CPRINTS("SDC Cutoff");
- return CRITICAL_SHUTDOWN_CUTOFF;
- } else if (remain < sdzone.stayup) {
- CPRINTS("SDC Stay-up");
- return CRITICAL_SHUTDOWN_IGNORE;
- }
-
- CPRINTS("SDC Safe");
- return CRITICAL_SHUTDOWN_HIBERNATE;
-}
-#else
-/* Default implementation for battery-less systems */
-__overridable enum critical_shutdown board_system_is_idle(
- uint64_t last_shutdown_time, uint64_t *target, uint64_t now)
-{
- return now > *target ?
- CRITICAL_SHUTDOWN_HIBERNATE : CRITICAL_SHUTDOWN_IGNORE;
-}
-#endif /* CONFIG_BATTERY */
-#endif /* CONFIG_HIBERNATE */
-
-/**
- * Common handler for steady states
- *
- * @param state Current power state
- * @return Updated power state
- */
-static enum power_state power_common_state(enum power_state state)
-{
- switch (state) {
- case POWER_G3:
- if (want_g3_exit || want_reboot_ap_at_g3) {
- uint64_t i;
-
- want_g3_exit = 0;
- want_reboot_ap_at_g3 = false;
- reboot_ap_at_g3_delay = reboot_ap_at_g3_delay * MSEC;
- /*
- * G3->S0 transition should happen only after the
- * user specified delay. Hence, wait until the
- * user specified delay times out.
- */
- for (i = 0; i < reboot_ap_at_g3_delay; i += 100)
- msleep(100);
- reboot_ap_at_g3_delay = 0;
-
- return POWER_G3S5;
- }
-
- in_want = 0;
-#ifdef CONFIG_HIBERNATE
- {
- uint64_t target, now, wait;
- if (extpower_is_present()) {
- task_wait_event(-1);
- break;
- }
-
- now = get_time().val;
- target = last_shutdown_time +
- (uint64_t)hibernate_delay * SECOND;
- switch (board_system_is_idle(last_shutdown_time,
- &target, now)) {
- case CRITICAL_SHUTDOWN_HIBERNATE:
- CPRINTS("Hibernate due to G3 idle");
- system_hibernate(0, 0);
- break;
-#ifdef CONFIG_BATTERY_CUT_OFF
- case CRITICAL_SHUTDOWN_CUTOFF:
- CPRINTS("Cutoff due to G3 idle");
- /* Ensure logs are flushed. */
- cflush();
- board_cut_off_battery();
- break;
-#endif
- case CRITICAL_SHUTDOWN_IGNORE:
- default:
- break;
- }
-
- wait = MIN(target - now, TASK_MAX_WAIT_US);
- task_wait_event(wait);
- }
-#else /* !CONFIG_HIBERNATE */
- task_wait_event(-1);
-#endif
- break;
-
- case POWER_S5:
- /*
- * If the power button is pressed before S5 inactivity timer
- * expires, the timer will be cancelled and the task of the
- * power state machine will be back here again. Since we are
- * here, which means the system has been waiting for CPU
- * starting up, we don't need want_g3_exit flag to be set
- * anymore. Therefore, we can reset the flag here to prevent
- * the situation that the flag is still set after S5 inactivity
- * timer expires, which can cause the system to exit G3 again.
- */
- want_g3_exit = 0;
-
- power_wait_signals(0);
-
- /* Wait for inactivity timeout, if desired */
- if (s5_inactivity_timeout == 0) {
- return POWER_S5G3;
- } else if (s5_inactivity_timeout < 0) {
- task_wait_event(-1);
- } else if (task_wait_event(s5_inactivity_timeout * SECOND) ==
- TASK_EVENT_TIMER) {
- /* Prepare to drop to G3; wake not requested yet */
- return POWER_S5G3;
- }
- break;
-
- case POWER_S3:
- /* Wait for a message */
- power_wait_signals(0);
- task_wait_event(-1);
- break;
-
- case POWER_S0:
- /* Wait for a message */
- power_wait_signals(0);
- task_wait_event(-1);
- break;
-#ifdef CONFIG_POWER_S0IX
- case POWER_S0ix:
- /* Wait for a message */
- power_wait_signals(0);
- task_wait_event(-1);
- break;
-#endif
- default:
- /* No common functionality for transition states */
- break;
- }
-
- return state;
-}
-
-/*****************************************************************************/
-/* Chipset interface */
-
-int chipset_in_state(int state_mask)
-{
- int need_mask = 0;
-
- /*
- * TODO(crosbug.com/p/23773): what to do about state transitions? If
- * the caller wants HARD_OFF|SOFT_OFF and we're in G3S5, we could still
- * return non-zero.
- */
- switch (state) {
- case POWER_G3:
- need_mask = CHIPSET_STATE_HARD_OFF;
- break;
- case POWER_G3S5:
- case POWER_S5G3:
- /*
- * In between hard and soft off states. Match only if caller
- * will accept both.
- */
- need_mask = CHIPSET_STATE_HARD_OFF | CHIPSET_STATE_SOFT_OFF;
- break;
- case POWER_S5:
- need_mask = CHIPSET_STATE_SOFT_OFF;
- break;
- case POWER_S5S3:
- case POWER_S3S5:
- need_mask = CHIPSET_STATE_SOFT_OFF | CHIPSET_STATE_SUSPEND;
- break;
- case POWER_S3:
- need_mask = CHIPSET_STATE_SUSPEND;
- break;
- case POWER_S3S0:
- case POWER_S0S3:
- need_mask = CHIPSET_STATE_SUSPEND | CHIPSET_STATE_ON;
- break;
- case POWER_S0:
- need_mask = CHIPSET_STATE_ON;
- break;
-#ifdef CONFIG_POWER_S0IX
- case POWER_S0ixS0:
- case POWER_S0S0ix:
- need_mask = CHIPSET_STATE_ON | CHIPSET_STATE_STANDBY;
- break;
- case POWER_S0ix:
- need_mask = CHIPSET_STATE_STANDBY;
- break;
-#endif
- }
-
- /* Return non-zero if all needed bits are present */
- return (state_mask & need_mask) == need_mask;
-}
-
-int chipset_in_or_transitioning_to_state(int state_mask)
-{
- switch (state) {
- case POWER_G3:
- case POWER_S5G3:
- return state_mask & CHIPSET_STATE_HARD_OFF;
- case POWER_S5:
- case POWER_G3S5:
- case POWER_S3S5:
- return state_mask & CHIPSET_STATE_SOFT_OFF;
- case POWER_S3:
- case POWER_S5S3:
- case POWER_S0S3:
- return state_mask & CHIPSET_STATE_SUSPEND;
-#ifdef CONFIG_POWER_S0IX
- case POWER_S0ix:
- case POWER_S0S0ix:
- return state_mask & CHIPSET_STATE_STANDBY;
-#endif
- case POWER_S0:
- case POWER_S3S0:
-#ifdef CONFIG_POWER_S0IX
- case POWER_S0ixS0:
-#endif
- return state_mask & CHIPSET_STATE_ON;
- }
-
- /* Unknown power state; return false. */
- return 0;
-}
-
-void chipset_exit_hard_off(void)
-{
- /*
- * If not in the soft-off state, hard-off state, or headed there,
- * nothing to do.
- */
- if (state != POWER_G3 && state != POWER_S5G3 && state != POWER_S5)
- return;
-
- /*
- * Set a flag to leave G3, then wake the task. If the power state is
- * POWER_S5G3, or is POWER_S5 but the S5 inactivity timer has
- * expired, set this flag can let system go to G3 and then exit G3
- * immediately for powering on.
- */
- want_g3_exit = 1;
-
- /*
- * If the power state is in POWER_S5 and S5 inactivity timer is
- * running, to wake the chipset task can cancel S5 inactivity timer and
- * then restart the timer. This will give cpu a chance to start up if
- * S5 inactivity timer is about to expire while power button is
- * pressed. For other states here, to wake the chipset task to trigger
- * the event for leaving G3 is necessary.
- */
- task_wake(TASK_ID_CHIPSET);
-}
-
-/*****************************************************************************/
-/* Task function */
-
-void chipset_task(void *u)
-{
- enum power_state new_state;
- static enum power_state last_state;
- uint32_t this_in_signals;
- static uint32_t last_in_signals;
-
- while (1) {
- /*
- * In order to prevent repeated console spam, only print the
- * current power state if something has actually changed. It's
- * possible that one of the power signals goes away briefly and
- * comes back by the time we update our in_signals.
- */
- this_in_signals = in_signals;
- if (this_in_signals != last_in_signals || state != last_state) {
- CPRINTS("power state %d = %s, in 0x%04x",
- state, state_names[state], this_in_signals);
- if (IS_ENABLED(CONFIG_SEVEN_SEG_DISPLAY))
- display_7seg_write(SEVEN_SEG_EC_DISPLAY, state);
- last_in_signals = this_in_signals;
- last_state = state;
- }
-
- /* Always let the specific chipset handle the state first */
- new_state = power_handle_state(state);
-
- /*
- * If the state hasn't changed, run common steady-state
- * handler.
- */
- if (new_state == state)
- new_state = power_common_state(state);
-
- /* Handle state changes */
- if (new_state != state) {
- power_set_state(new_state);
- power_set_active_wake_mask();
-
- /* Call hooks before we enter G3 */
- if (new_state == POWER_G3)
- hook_notify(HOOK_CHIPSET_HARD_OFF);
- }
- }
-}
-
-/*****************************************************************************/
-/* Hooks */
-
-static void power_common_init(void)
-{
- const struct power_signal_info *s = power_signal_list;
- int i;
-
- /* Update input state */
- power_update_signals();
-
- /* Enable interrupts for input signals */
- for (i = 0; i < POWER_SIGNAL_COUNT; i++, s++)
- if (s->flags & POWER_SIGNAL_DISABLE_AT_BOOT)
- power_signal_disable_interrupt(s->gpio);
- else
- power_signal_enable_interrupt(s->gpio);
-
- /* Call chipset-specific init to set initial state */
- power_set_state(power_chipset_init());
-
- /*
- * Update input state again since there is a small window
- * before GPIO is enabled.
- */
- power_update_signals();
-}
-DECLARE_HOOK(HOOK_INIT, power_common_init, HOOK_PRIO_INIT_CHIPSET);
-
-static void power_lid_change(void)
-{
- /* Wake up the task to update power state */
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, power_lid_change, HOOK_PRIO_DEFAULT);
-
-#ifdef CONFIG_EXTPOWER
-static void power_ac_change(void)
-{
- if (extpower_is_present()) {
- CPRINTS("AC on");
- } else {
- CPRINTS("AC off");
-
- if (state == POWER_G3) {
- last_shutdown_time = get_time().val;
- task_wake(TASK_ID_CHIPSET);
- }
- }
-}
-DECLARE_HOOK(HOOK_AC_CHANGE, power_ac_change, HOOK_PRIO_DEFAULT);
-#endif
-
-/*****************************************************************************/
-/* Interrupts */
-
-#ifdef CONFIG_BRINGUP
-#define MAX_SIGLOG_ENTRIES 24
-
-static unsigned int siglog_entries;
-static unsigned int siglog_truncated;
-
-static struct {
- timestamp_t time;
- enum gpio_signal signal;
- int level;
-} siglog[MAX_SIGLOG_ENTRIES];
-
-static void siglog_deferred(void)
-{
- unsigned int i;
- timestamp_t tdiff = {.val = 0};
-
- /* Disable interrupts for input signals while we print stuff.*/
- for (i = 0; i < POWER_SIGNAL_COUNT; i++)
- power_signal_disable_interrupt(power_signal_list[i].gpio);
-
- CPRINTF("%d signal changes:\n", siglog_entries);
- for (i = 0; i < siglog_entries; i++) {
- if (i)
- tdiff.val = siglog[i].time.val - siglog[i-1].time.val;
- CPRINTF(" %.6lld +%.6lld %s => %d\n",
- siglog[i].time.val, tdiff.val,
- power_signal_get_name(siglog[i].signal),
- siglog[i].level);
- }
- if (siglog_truncated)
- CPRINTF(" SIGNAL LOG TRUNCATED...\n");
- siglog_entries = siglog_truncated = 0;
-
- /* Okay, turn 'em on again. */
- for (i = 0; i < POWER_SIGNAL_COUNT; i++)
- power_signal_enable_interrupt(power_signal_list[i].gpio);
-}
-DECLARE_DEFERRED(siglog_deferred);
-
-static void siglog_add(enum gpio_signal signal)
-{
- if (siglog_entries >= MAX_SIGLOG_ENTRIES) {
- siglog_truncated = 1;
- return;
- }
-
- siglog[siglog_entries].time = get_time();
- siglog[siglog_entries].signal = signal;
- siglog[siglog_entries].level = power_signal_get_level(signal);
- siglog_entries++;
-
- hook_call_deferred(&siglog_deferred_data, SECOND);
-}
-
-#define SIGLOG(S) siglog_add(S)
-
-#else
-#define SIGLOG(S)
-#endif /* CONFIG_BRINGUP */
-
-#ifdef CONFIG_POWER_SIGNAL_INTERRUPT_STORM_DETECT_THRESHOLD
-/*
- * Print an interrupt storm warning when we receive more than
- * CONFIG_POWER_SIGNAL_INTERRUPT_STORM_DETECT_THRESHOLD interrupts of a
- * single source within 1 second.
- */
-static int power_signal_interrupt_count[POWER_SIGNAL_COUNT];
-
-static void reset_power_signal_interrupt_count(void)
-{
- int i;
-
- for (i = 0; i < POWER_SIGNAL_COUNT; ++i)
- power_signal_interrupt_count[i] = 0;
-}
-DECLARE_HOOK(HOOK_SECOND,
- reset_power_signal_interrupt_count,
- HOOK_PRIO_DEFAULT);
-#endif
-
-void power_signal_interrupt(enum gpio_signal signal)
-{
-#ifdef CONFIG_POWER_SIGNAL_INTERRUPT_STORM_DETECT_THRESHOLD
- int i;
-
- /* Tally our interrupts and print a warning if necessary. */
- for (i = 0; i < POWER_SIGNAL_COUNT; ++i) {
- if (power_signal_list[i].gpio == signal) {
- if (power_signal_interrupt_count[i]++ ==
- CONFIG_POWER_SIGNAL_INTERRUPT_STORM_DETECT_THRESHOLD)
- CPRINTS("Interrupt storm! Signal %d", i);
- break;
- }
- }
-#endif
-
- SIGLOG(signal);
-
- /* Shadow signals and compare with our desired signal state. */
- power_update_signals();
-
- /* Wake up the task */
- task_wake(TASK_ID_CHIPSET);
-}
-
-#ifdef CONFIG_POWER_SHUTDOWN_PAUSE_IN_S5
-inline int power_get_pause_in_s5(void)
-{
- return pause_in_s5;
-}
-
-inline void power_set_pause_in_s5(int pause)
-{
- pause_in_s5 = pause;
-}
-#endif
-
-/*****************************************************************************/
-/* Console commands */
-
-static int command_powerinfo(int argc, char **argv)
-{
- /*
- * Print power state in same format as state machine. This is
- * used by FAFT tests, so must match exactly.
- */
- ccprintf("power state %d = %s, in 0x%04x\n",
- state, state_names[state], in_signals);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(powerinfo, command_powerinfo,
- NULL,
- "Show current power state");
-
-#ifdef CONFIG_CMD_POWERINDEBUG
-static int command_powerindebug(int argc, char **argv)
-{
- const struct power_signal_info *s = power_signal_list;
- int i;
- char *e;
-
- /* If one arg, set the mask */
- if (argc == 2) {
- int m = strtoi(argv[1], &e, 0);
- if (*e)
- return EC_ERROR_PARAM1;
-
- in_debug = m;
- }
-
- /* Print the mask */
- ccprintf("power in: 0x%04x\n", in_signals);
- ccprintf("debug mask: 0x%04x\n", in_debug);
-
- /* Print the decode */
-
- ccprintf("bit meanings:\n");
- for (i = 0; i < POWER_SIGNAL_COUNT; i++, s++) {
- int mask = 1 << i;
- ccprintf(" 0x%04x %d %s\n",
- mask, in_signals & mask ? 1 : 0, s->name);
- }
-
- return EC_SUCCESS;
-};
-DECLARE_CONSOLE_COMMAND(powerindebug, command_powerindebug,
- "[mask]",
- "Get/set power input debug mask");
-#endif
-
-#ifdef CONFIG_CMD_S5_TIMEOUT
-/* Allow command-line access to configure our S5 delay for power testing */
-static int command_s5_timeout(int argc, char **argv)
-{
- char *e;
-
- if (argc >= 2) {
- uint32_t s = strtoi(argv[1], &e, 0);
-
- if (*e)
- return EC_ERROR_PARAM1;
-
- s5_inactivity_timeout = s;
- }
-
- /* Print the current setting */
- ccprintf("S5 inactivity timeout: %d s\n", s5_inactivity_timeout);
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(s5_timeout, command_s5_timeout,
- "[sec]",
- "Set the timeout from S5 to G3 transition, "
- "-1 to indicate no transition");
-#endif
-
-#ifdef CONFIG_HIBERNATE
-static int command_hibernation_delay(int argc, char **argv)
-{
- char *e;
- uint32_t time_g3 = ((uint32_t)(get_time().val - last_shutdown_time))
- / SECOND;
-
- if (argc >= 2) {
- uint32_t s = strtoi(argv[1], &e, 0);
- if (*e)
- return EC_ERROR_PARAM1;
-
- hibernate_delay = s;
- }
-
- /* Print the current setting */
- ccprintf("Hibernation delay: %d s\n", hibernate_delay);
- if (state == POWER_G3 && !extpower_is_present()) {
- ccprintf("Time G3: %d s\n", time_g3);
- ccprintf("Time left: %d s\n", hibernate_delay - time_g3);
- }
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(hibdelay, command_hibernation_delay,
- "[sec]",
- "Set the delay before going into hibernation");
-
-static enum ec_status
-host_command_hibernation_delay(struct host_cmd_handler_args *args)
-{
- const struct ec_params_hibernation_delay *p = args->params;
- struct ec_response_hibernation_delay *r = args->response;
-
- uint32_t time_g3;
- uint64_t t = get_time().val - last_shutdown_time;
-
- uint64divmod(&t, SECOND);
- time_g3 = (uint32_t)t;
-
- /* Only change the hibernation delay if seconds is non-zero. */
- if (p->seconds)
- hibernate_delay = p->seconds;
-
- if (state == POWER_G3 && !extpower_is_present())
- r->time_g3 = time_g3;
- else
- r->time_g3 = 0;
-
- if ((time_g3 != 0) && (time_g3 > hibernate_delay))
- r->time_remaining = 0;
- else
- r->time_remaining = hibernate_delay - time_g3;
- r->hibernate_delay = hibernate_delay;
-
- args->response_size = sizeof(struct ec_response_hibernation_delay);
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_HIBERNATION_DELAY,
- host_command_hibernation_delay,
- EC_VER_MASK(0));
-#endif /* CONFIG_HIBERNATE */
-
-#ifdef CONFIG_POWER_SHUTDOWN_PAUSE_IN_S5
-static enum ec_status
-host_command_pause_in_s5(struct host_cmd_handler_args *args)
-{
- const struct ec_params_get_set_value *p = args->params;
- struct ec_response_get_set_value *r = args->response;
-
- if (p->flags & EC_GSV_SET)
- pause_in_s5 = p->value;
-
- r->value = pause_in_s5;
-
- args->response_size = sizeof(*r);
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_GSV_PAUSE_IN_S5,
- host_command_pause_in_s5,
- EC_VER_MASK(0));
-
-static int command_pause_in_s5(int argc, char **argv)
-{
- if (argc > 1 && !parse_bool(argv[1], &pause_in_s5))
- return EC_ERROR_INVAL;
-
- ccprintf("pause_in_s5 = %s\n", pause_in_s5 ? "on" : "off");
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(pause_in_s5, command_pause_in_s5,
- "[on|off]",
- "Should the AP pause in S5 during shutdown?");
-#endif /* CONFIG_POWER_SHUTDOWN_PAUSE_IN_S5 */
-
-#ifdef CONFIG_POWER_PP5000_CONTROL
-__overridable void board_power_5v_enable(int enable)
-{
- if (enable)
- gpio_set_level(GPIO_EN_PP5000, 1);
- else
- gpio_set_level(GPIO_EN_PP5000, 0);
-}
-
-/* 5V enable request bitmask from various tasks. */
-static uint32_t pwr_5v_en_req;
-K_MUTEX_DEFINE(pwr_5v_ctl_mtx);
-
-void power_5v_enable(task_id_t tid, int enable)
-{
- mutex_lock(&pwr_5v_ctl_mtx);
-
- if (enable) /* Set the bit indicating the request. */
- pwr_5v_en_req |= 1 << tid;
- else /* Clear the task's request bit. */
- pwr_5v_en_req &= ~(1 << tid);
-
- /*
- * If there are any outstanding requests for the rail to be enabled,
- * turn on the rail. Otherwise, turn it off.
- */
- board_power_5v_enable(pwr_5v_en_req);
- mutex_unlock(&pwr_5v_ctl_mtx);
-}
-
-#define P5_SYSJUMP_TAG 0x5005 /* "P5" */
-static void restore_enable_5v_state(void)
-{
- const uint32_t *state;
- int size;
-
- state = (const uint32_t *) system_get_jump_tag(P5_SYSJUMP_TAG, 0,
- &size);
- if (state && size == sizeof(pwr_5v_en_req)) {
- mutex_lock(&pwr_5v_ctl_mtx);
- pwr_5v_en_req |= *state;
- mutex_unlock(&pwr_5v_ctl_mtx);
- }
-}
-DECLARE_HOOK(HOOK_INIT, restore_enable_5v_state, HOOK_PRIO_FIRST);
-
-static void preserve_enable_5v_state(void)
-{
- mutex_lock(&pwr_5v_ctl_mtx);
- system_add_jump_tag(P5_SYSJUMP_TAG, 0, sizeof(pwr_5v_en_req),
- &pwr_5v_en_req);
- mutex_unlock(&pwr_5v_ctl_mtx);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, preserve_enable_5v_state, HOOK_PRIO_DEFAULT);
-#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
diff --git a/power/ec_driven.c b/power/ec_driven.c
deleted file mode 100644
index 282941b941..0000000000
--- a/power/ec_driven.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright 2013 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.
- */
-
-/*
- * Mock power module for Sensor HUB.
- *
- * This implements the following features:
- * when AP_IN_SUSPEND is low, in S0, otherwise S3.
- *
- */
-
-#include "chipset.h" /* This module implements chipset functions too */
-#include "common.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "power.h"
-#include "task.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-#define IN_SUSPEND POWER_SIGNAL_MASK(ECDRIVEN_SUSPEND_ASSERTED)
-
-enum power_state power_chipset_init(void)
-{
- return POWER_S3;
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- switch (state) {
- case POWER_S3:
- if (!(power_get_signals() & IN_SUSPEND)) {
- hook_notify(HOOK_CHIPSET_RESUME);
- return POWER_S0;
- }
- return state;
-
- case POWER_S0:
- if (power_get_signals() & IN_SUSPEND) {
- hook_notify(HOOK_CHIPSET_SUSPEND);
- return POWER_S3;
- }
- return state;
- default:
- CPRINTS("Unexpected state: $d", state);
- }
-
- return state;
-}
diff --git a/power/host_sleep.c b/power/host_sleep.c
deleted file mode 100644
index bfa5cbd90a..0000000000
--- a/power/host_sleep.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/* Copyright 2019 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.
- */
-
-#include "config.h"
-#include "console.h"
-#include "ec_commands.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "power.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
-
-/* Track last reported sleep event */
-static enum host_sleep_event host_sleep_state;
-
-__overridable void power_chipset_handle_host_sleep_event(
- enum host_sleep_event state,
- struct host_sleep_event_context *ctx)
-{
- /* Default weak implementation -- no action required. */
-}
-
-static enum ec_status
-host_command_host_sleep_event(struct host_cmd_handler_args *args)
-{
- const struct ec_params_host_sleep_event_v1 *p = args->params;
- struct ec_response_host_sleep_event_v1 *r = args->response;
- struct host_sleep_event_context ctx;
- enum host_sleep_event state = p->sleep_event;
-
- host_sleep_state = state;
- ctx.sleep_transitions = 0;
- switch (state) {
- case HOST_SLEEP_EVENT_S0IX_SUSPEND:
- case HOST_SLEEP_EVENT_S3_SUSPEND:
- case HOST_SLEEP_EVENT_S3_WAKEABLE_SUSPEND:
- ctx.sleep_timeout_ms = EC_HOST_SLEEP_TIMEOUT_DEFAULT;
-
- /* The original version contained only state. */
- if (args->version >= 1)
- ctx.sleep_timeout_ms =
- p->suspend_params.sleep_timeout_ms;
-
- break;
-
- default:
- break;
- }
-
- power_chipset_handle_host_sleep_event(host_sleep_state, &ctx);
- switch (state) {
- case HOST_SLEEP_EVENT_S0IX_RESUME:
- case HOST_SLEEP_EVENT_S3_RESUME:
- if (args->version >= 1) {
- r->resume_response.sleep_transitions =
- ctx.sleep_transitions;
-
- args->response_size = sizeof(*r);
- }
-
- break;
-
- default:
- break;
- }
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_HOST_SLEEP_EVENT,
- host_command_host_sleep_event,
- EC_VER_MASK(0) | EC_VER_MASK(1));
-
-enum host_sleep_event power_get_host_sleep_state(void)
-{
- return host_sleep_state;
-}
-
-void power_set_host_sleep_state(enum host_sleep_event state)
-{
- host_sleep_state = state;
-}
-
-/* Flag to notify listeners about suspend/resume events. */
-enum sleep_notify_type sleep_notify = SLEEP_NOTIFY_NONE;
-
-/*
- * Note: the following sleep_ functions do not get called in the S3 path on
- * Intel devices. On Intel devices, they are called in the S0ix path.
- */
-void sleep_set_notify(enum sleep_notify_type notify)
-{
- sleep_notify = notify;
-}
-
-void sleep_notify_transition(int check_state, int hook_id)
-{
- if (sleep_notify != check_state)
- return;
-
- hook_notify(hook_id);
- sleep_set_notify(SLEEP_NOTIFY_NONE);
-}
-
-#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION
-
-static uint16_t sleep_signal_timeout;
-static uint16_t host_sleep_timeout_default = CONFIG_SLEEP_TIMEOUT_MS;
-static uint32_t sleep_signal_transitions;
-static void (*sleep_timeout_callback)(void);
-
-static void sleep_transition_timeout(void);
-DECLARE_DEFERRED(sleep_transition_timeout);
-
-static void sleep_increment_transition(void)
-{
- if ((sleep_signal_transitions & EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK) <
- EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK)
- sleep_signal_transitions += 1;
-}
-
-void sleep_suspend_transition(void)
-{
- sleep_increment_transition();
- hook_call_deferred(&sleep_transition_timeout_data, -1);
-}
-
-void sleep_resume_transition(void)
-{
- sleep_increment_transition();
-
- /*
- * Start the timer again to ensure the AP doesn't get itself stuck in
- * a state where it's no longer in a sleep state (S0ix/S3), but from
- * the Linux perspective is still suspended. Perhaps a bug in the SoC-
- * internal periodic housekeeping code might result in a situation
- * like this.
- */
- if (sleep_signal_timeout)
- hook_call_deferred(&sleep_transition_timeout_data,
- (uint32_t)sleep_signal_timeout * 1000);
-}
-
-static void sleep_transition_timeout(void)
-{
- /* Mark the timeout. */
- sleep_signal_transitions |= EC_HOST_RESUME_SLEEP_TIMEOUT;
- hook_call_deferred(&sleep_transition_timeout_data, -1);
-
- /* Call the custom callback */
- if (sleep_timeout_callback)
- sleep_timeout_callback();
-}
-
-void sleep_start_suspend(struct host_sleep_event_context *ctx,
- void (*callback)(void))
-{
- uint16_t timeout = ctx->sleep_timeout_ms;
-
- sleep_timeout_callback = callback;
- sleep_signal_transitions = 0;
-
- /* Use zero internally to indicate no timeout. */
- if (timeout == EC_HOST_SLEEP_TIMEOUT_DEFAULT) {
- timeout = host_sleep_timeout_default;
- }
-
- /* Use 0xFFFF to disable the timeout */
- if (timeout == EC_HOST_SLEEP_TIMEOUT_INFINITE) {
- sleep_signal_timeout = 0;
- return;
- }
-
- sleep_signal_timeout = timeout;
- hook_call_deferred(&sleep_transition_timeout_data,
- (uint32_t)timeout * 1000);
-}
-
-void sleep_complete_resume(struct host_sleep_event_context *ctx)
-{
- /*
- * Ensure we don't schedule another sleep_transition_timeout
- * if the the HOST_SLEEP_EVENT_S0IX_RESUME message arrives before
- * the CHIPSET task transitions to the POWER_S0ixS0 state.
- */
- sleep_signal_timeout = 0;
- hook_call_deferred(&sleep_transition_timeout_data, -1);
- ctx->sleep_transitions = sleep_signal_transitions;
-}
-
-void sleep_reset_tracking(void)
-{
- sleep_signal_transitions = 0;
- sleep_signal_timeout = 0;
- sleep_timeout_callback = NULL;
-}
-
-static int command_sleep_fail_timeout(int argc, char **argv)
-{
- if (argc < 2) {
- /* no arguments - just print the current timeout */
- } else if (!strcasecmp(argv[1], "default")) {
- host_sleep_timeout_default = CONFIG_SLEEP_TIMEOUT_MS;
- } else if (!strcasecmp(argv[1], "infinite")) {
- host_sleep_timeout_default = EC_HOST_SLEEP_TIMEOUT_INFINITE;
- } else {
- char *e;
- int val;
-
- val = strtoi(argv[1], &e, 10);
- if (*e)
- return EC_ERROR_PARAM1;
-
- if (val <= 0 || val >= EC_HOST_SLEEP_TIMEOUT_INFINITE) {
- ccprintf("Error: timeout range is 1..%d [msec]\n",
- EC_HOST_SLEEP_TIMEOUT_INFINITE - 1);
- return EC_ERROR_PARAM1;
- }
-
- host_sleep_timeout_default = val;
- }
-
- if (host_sleep_timeout_default == EC_HOST_SLEEP_TIMEOUT_INFINITE)
- ccprintf("Sleep failure detection timeout is disabled\n");
- else
- ccprintf("Sleep failure detection timeout is %d [msec]\n",
- host_sleep_timeout_default);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(sleeptimeout, command_sleep_fail_timeout,
- "[default | infinite | <msec>]",
- "Display or set host sleep failure detection timeout.\n"
- "Valid arguments are:\n"
- " default\n"
- " infinite - disables the timeout\n"
- " <msec> - custom length in milliseconds\n"
- " <none> - prints the current setting");
-
-
-#else /* !CONFIG_POWER_SLEEP_FAILURE_DETECTION */
-
-/* No action */
-void sleep_suspend_transition(void)
-{
-}
-
-void sleep_resume_transition(void)
-{
-}
-
-void sleep_start_suspend(struct host_sleep_event_context *ctx,
- void (*callback)(void))
-{
-}
-
-void sleep_complete_resume(struct host_sleep_event_context *ctx)
-{
-}
-
-void sleep_reset_tracking(void)
-{
-}
-
-#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */
diff --git a/power/icelake.c b/power/icelake.c
deleted file mode 100644
index c47f44c146..0000000000
--- a/power/icelake.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/* Copyright 2018 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.
- */
-
-/* Icelake chipset power control module for Chrome EC */
-
-#include "board_config.h"
-#include "chipset.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "power.h"
-#include "power/intel_x86.h"
-#include "power_button.h"
-#include "task.h"
-#include "timer.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-#ifdef CONFIG_BRINGUP
-#define GPIO_SET_LEVEL(signal, value) \
- gpio_set_level_verbose(CC_CHIPSET, signal, value)
-#else
-#define GPIO_SET_LEVEL(signal, value) \
- gpio_set_level(signal, value)
-#endif
-
-/* The wait time is ~150 msec, allow for safety margin. */
-#define IN_PCH_SLP_SUS_WAIT_TIME_USEC (250 * MSEC)
-
-static int forcing_shutdown; /* Forced shutdown in progress? */
-
-/* Power signals list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
- [X86_SLP_S0_DEASSERTED] = {
- .gpio = GPIO_PCH_SLP_S0_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH |
- POWER_SIGNAL_DISABLE_AT_BOOT,
- .name = "SLP_S0_DEASSERTED",
- },
- [X86_SLP_S3_DEASSERTED] = {
- .gpio = SLP_S3_SIGNAL_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_S3_DEASSERTED",
- },
- [X86_SLP_S4_DEASSERTED] = {
- .gpio = SLP_S4_SIGNAL_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_S4_DEASSERTED",
- },
- [X86_SLP_SUS_DEASSERTED] = {
- .gpio = GPIO_SLP_SUS_L,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "SLP_SUS_DEASSERTED",
- },
- [X86_RSMRST_L_PGOOD] = {
- .gpio = GPIO_PG_EC_RSMRST_ODL,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "RSMRST_L_PGOOD",
- },
- [X86_DSW_DPWROK] = {
- .gpio = GPIO_PG_EC_DSW_PWROK,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "DSW_DPWROK",
- },
- [X86_ALL_SYS_PGOOD] = {
- .gpio = GPIO_PG_EC_ALL_SYS_PWRGD,
- .flags = POWER_SIGNAL_ACTIVE_HIGH,
- .name = "ALL_SYS_PWRGD",
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-__overridable int intel_x86_get_pg_ec_dsw_pwrok(void)
-{
- return gpio_get_level(GPIO_PG_EC_DSW_PWROK);
-}
-
-__overridable int intel_x86_get_pg_ec_all_sys_pwrgd(void)
-{
- return gpio_get_level(GPIO_PG_EC_ALL_SYS_PWRGD);
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- int timeout_ms = 50;
-
- CPRINTS("%s() %d", __func__, reason);
- report_ap_reset(reason);
-
- /* Turn off RMSRST_L to meet tPCH12 */
- board_before_rsmrst(0);
- GPIO_SET_LEVEL(GPIO_PCH_RSMRST_L, 0);
- board_after_rsmrst(0);
-
- /* Turn off DSW_PWROK to meet tPCH14 */
- GPIO_SET_LEVEL(GPIO_PCH_DSW_PWROK, 0);
-
- /* Turn off DSW load switch. */
- GPIO_SET_LEVEL(GPIO_EN_PP3300_A, 0);
-
- /*
- * For JSL, we need to wait 60ms before turning off PP5000_U to allow
- * VCCIN_AUX time to discharge.
- */
- if (IS_ENABLED(CONFIG_CHIPSET_JASPERLAKE))
- msleep(60);
-
- /* Turn off PP5000 rail */
- if (IS_ENABLED(CONFIG_POWER_PP5000_CONTROL))
- power_5v_enable(task_get_current(), 0);
- else
- GPIO_SET_LEVEL(GPIO_EN_PP5000, 0);
-
- /*
- * TODO(b/111810925): Replace this wait with
- * power_wait_signals_timeout()
- */
- /* Now wait for DSW_PWROK and RSMRST_ODL to go away. */
- while (intel_x86_get_pg_ec_dsw_pwrok() &&
- gpio_get_level(GPIO_PG_EC_RSMRST_ODL) && (timeout_ms > 0)) {
- msleep(1);
- timeout_ms--;
- };
-
- if (!timeout_ms)
- CPRINTS("DSW_PWROK or RSMRST_ODL didn't go low! Assuming G3.");
-}
-
-void chipset_handle_espi_reset_assert(void)
-{
- /*
- * If eSPI_Reset# pin is asserted without SLP_SUS# being asserted, then
- * it means that there is an unexpected power loss (global reset
- * event). In this case, check if shutdown was being forced by pressing
- * power button. If yes, release power button.
- */
- if ((power_get_signals() & IN_PCH_SLP_SUS_DEASSERTED) &&
- forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
-}
-
-enum power_state chipset_force_g3(void)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
-
- return POWER_G3;
-}
-
-static void enable_pp5000_rail(void)
-{
- if (IS_ENABLED(CONFIG_POWER_PP5000_CONTROL))
- power_5v_enable(task_get_current(), 1);
- else
- GPIO_SET_LEVEL(GPIO_EN_PP5000, 1);
-
-}
-
-static void dsw_pwrok_pass_thru(void)
-{
- int dswpwrok_in = intel_x86_get_pg_ec_dsw_pwrok();
-
- /* Pass-through DSW_PWROK to ICL. */
- if (dswpwrok_in != gpio_get_level(GPIO_PCH_DSW_PWROK)) {
- if (IS_ENABLED(CONFIG_CHIPSET_SLP_S3_L_OVERRIDE)
- && dswpwrok_in) {
- /*
- * Once DSW_PWROK is high, reconfigure SLP_S3_L back to
- * an input after a short delay.
- */
- msleep(1);
- CPRINTS("Release SLP_S3_L");
- gpio_reset(SLP_S3_SIGNAL_L);
- power_signal_enable_interrupt(SLP_S3_SIGNAL_L);
- }
-
- CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in);
- /*
- * A minimum 10 msec delay is required between PP3300_A being
- * stable and the DSW_PWROK signal being passed to the PCH.
- */
- msleep(10);
- GPIO_SET_LEVEL(GPIO_PCH_DSW_PWROK, dswpwrok_in);
- }
-}
-
-/*
- * Set the PWROK signal state
- *
- * &param level 0 deasserts the signal, other values assert the signal
- */
-static void pwrok_signal_set(const struct intel_x86_pwrok_signal *signal,
- int level)
-{
- GPIO_SET_LEVEL(signal->gpio, signal->active_low ? !level : level);
-}
-
-/*
- * Pass through the state of the ALL_SYS_PWRGD input to all the PWROK outputs
- * defined by the board.
- */
-static void all_sys_pwrgd_pass_thru(void)
-{
- int all_sys_pwrgd_in = intel_x86_get_pg_ec_all_sys_pwrgd();
- const struct intel_x86_pwrok_signal *pwrok_signal;
- int signal_count;
- int i;
-
- if (all_sys_pwrgd_in) {
- pwrok_signal = pwrok_signal_assert_list;
- signal_count = pwrok_signal_assert_count;
- } else {
- pwrok_signal = pwrok_signal_deassert_list;
- signal_count = pwrok_signal_deassert_count;
- }
-
- /*
- * Loop through all PWROK signals defined by the board and set
- * to match the current ALL_SYS_PWRGD input.
- */
- for (i = 0; i < signal_count; i++, pwrok_signal++) {
- if (pwrok_signal->delay_ms > 0)
- msleep(pwrok_signal->delay_ms);
-
- pwrok_signal_set(pwrok_signal, all_sys_pwrgd_in);
- }
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
-#ifdef CONFIG_CHIPSET_JASPERLAKE
- int timeout_ms = 10;
-#endif /* CONFIG_CHIPSET_JASPERLAKE */
-
- dsw_pwrok_pass_thru();
-
- all_sys_pwrgd_pass_thru();
-
- common_intel_x86_handle_rsmrst(state);
-
- switch (state) {
-
- case POWER_G3S5:
- if (IS_ENABLED(CONFIG_CHIPSET_SLP_S3_L_OVERRIDE)) {
- /*
- * Prevent glitches on the SLP_S3_L and PCH_PWROK
- * signals while when the PP3300_A rail is turned on.
- * Drive SLP_S3_L from the EC until DSW_PWROK is high.
- */
- CPRINTS("Drive SLP_S3_L low during PP3300_A rampup");
- power_signal_disable_interrupt(SLP_S3_SIGNAL_L);
- gpio_set_flags(SLP_S3_SIGNAL_L, GPIO_ODR_LOW);
- }
-
- /* Default behavior - turn on PP5000 rail first */
- if (!IS_ENABLED(CONFIG_CHIPSET_PP3300_RAIL_FIRST))
- enable_pp5000_rail();
-
- /*
- * TODO(b/111121615): Should modify this to wait until the
- * common power state machine indicates that it's ok to try an
- * boot the AP prior to turning on the 3300_A rail. This could
- * be done using chipset_pre_init_callback()
- */
- /* Turn on the PP3300_DSW rail. */
- GPIO_SET_LEVEL(GPIO_EN_PP3300_A, 1);
- if (power_wait_signals(IN_PGOOD_ALL_CORE))
- break;
-
- /* Pass thru DSWPWROK again since we changed it. */
- dsw_pwrok_pass_thru();
-
- /* Turn on PP5000 after PP3300 and DSW PWROK when enabled */
- if (IS_ENABLED(CONFIG_CHIPSET_PP3300_RAIL_FIRST))
- enable_pp5000_rail();
-
- /*
- * Now wait for SLP_SUS_L to go high based on tPCH32. If this
- * signal doesn't go high within 250 msec then go back to G3.
- */
- if (power_wait_signals_timeout(IN_PCH_SLP_SUS_DEASSERTED,
- IN_PCH_SLP_SUS_WAIT_TIME_USEC) != EC_SUCCESS) {
- CPRINTS("SLP_SUS_L didn't go high! Going back to G3.");
- return POWER_S5G3;
- }
- break;
-
- case POWER_S5:
- if (forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
- /* If SLP_SUS_L is asserted, we're no longer in S5. */
- if (!power_has_signals(IN_PCH_SLP_SUS_DEASSERTED))
- return POWER_S5G3;
- break;
-
-#ifdef CONFIG_CHIPSET_JASPERLAKE
- case POWER_S3S0:
- GPIO_SET_LEVEL(GPIO_EN_VCCIO_EXT, 1);
- /* Now wait for ALL_SYS_PWRGD. */
- while (!intel_x86_get_pg_ec_all_sys_pwrgd() &&
- (timeout_ms > 0)) {
- msleep(1);
- timeout_ms--;
- };
- if (!timeout_ms)
- CPRINTS("ALL_SYS_PWRGD not received.");
- break;
-
- case POWER_S0S3:
- GPIO_SET_LEVEL(GPIO_EN_VCCIO_EXT, 0);
- break;
-#endif /* CONFIG_CHIPSET_JASPERLAKE */
-
- default:
- break;
- }
-
- return common_intel_x86_power_handle_state(state);
-}
diff --git a/power/intel_x86.c b/power/intel_x86.c
deleted file mode 100644
index c4aae9db81..0000000000
--- a/power/intel_x86.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/* Copyright 2016 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.
- */
-
-/* Intel X86 chipset power control module for Chrome EC */
-
-#include "board_config.h"
-#include "charge_state.h"
-#include "chipset.h"
-#include "console.h"
-#include "ec_commands.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "lpc.h"
-#include "power.h"
-#include "power/intel_x86.h"
-#include "power_button.h"
-#include "system.h"
-#include "task.h"
-#include "util.h"
-#include "vboot.h"
-#include "wireless.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
-
-enum sys_sleep_state {
- SYS_SLEEP_S3,
- SYS_SLEEP_S4,
-#ifdef CONFIG_POWER_S0IX
- SYS_SLEEP_S0IX,
-#endif
-};
-
-static const int sleep_sig[] = {
- [SYS_SLEEP_S3] = SLP_S3_SIGNAL_L,
- [SYS_SLEEP_S4] = SLP_S4_SIGNAL_L,
-#ifdef CONFIG_POWER_S0IX
- [SYS_SLEEP_S0IX] = GPIO_PCH_SLP_S0_L,
-#endif
-};
-
-static int power_s5_up; /* Chipset is sequencing up or down */
-
-#ifdef CONFIG_CHARGER
-/* Flag to indicate if power up was inhibited due to low battery SOC level. */
-static int power_up_inhibited;
-
-/*
- * Check if AP power up should be inhibited.
- * 0 = Ok to boot up AP
- * 1 = AP power up is inhibited.
- */
-static int is_power_up_inhibited(void)
-{
- /* Defaulting to power button not pressed. */
- const int power_button_pressed = 0;
-
- return charge_prevent_power_on(power_button_pressed) ||
- charge_want_shutdown();
-}
-
-static void power_up_inhibited_cb(void)
-{
- if (!power_up_inhibited)
- return;
-
- if (is_power_up_inhibited()) {
- CPRINTS("power-up still inhibited");
- return;
- }
-
- CPRINTS("Battery SOC ok to boot AP!");
- power_up_inhibited = 0;
-
- chipset_exit_hard_off();
-}
-DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, power_up_inhibited_cb, HOOK_PRIO_DEFAULT);
-#endif
-
-/* Get system sleep state through GPIOs or VWs */
-static inline int chipset_get_sleep_signal(enum sys_sleep_state state)
-{
- return power_signal_get_level(sleep_sig[state]);
-}
-
-#ifdef CONFIG_BOARD_HAS_RTC_RESET
-static void intel_x86_rtc_reset(void)
-{
- CPRINTS("Asserting RTCRST# to PCH");
- gpio_set_level(GPIO_PCH_RTCRST, 1);
- udelay(100);
- gpio_set_level(GPIO_PCH_RTCRST, 0);
-}
-
-static enum power_state power_wait_s5_rtc_reset(void)
-{
- static int s5_exit_tries;
-
- /* Wait for S5 exit and then attempt RTC reset */
- while ((power_get_signals() & IN_PCH_SLP_S4_DEASSERTED) == 0) {
- /* Handle RSMRST passthru event while waiting */
- common_intel_x86_handle_rsmrst(POWER_S5);
- if (task_wait_event(SECOND*4) == TASK_EVENT_TIMER) {
- CPRINTS("timeout waiting for S5 exit");
- chipset_force_g3();
-
- /* Assert RTCRST# and retry 5 times */
- intel_x86_rtc_reset();
-
- if (++s5_exit_tries > 4) {
- s5_exit_tries = 0;
- return POWER_G3; /* Stay off */
- }
-
- udelay(10 * MSEC);
- return POWER_G3S5; /* Power up again */
- }
- }
-
- s5_exit_tries = 0;
- return POWER_S5S3; /* Power up to next state */
-}
-#endif
-
-#ifdef CONFIG_POWER_S0IX
-/*
- * Backup copies of SCI and SMI mask to preserve across S0ix suspend/resume
- * cycle. If the host uses S0ix, BIOS is not involved during suspend and resume
- * operations and hence SCI/SMI masks are programmed only once during boot-up.
- *
- * These backup variables are set whenever host expresses its interest to
- * enter S0ix and then lpc_host_event_mask for SCI and SMI are cleared. When
- * host resumes from S0ix, masks from backup variables are copied over to
- * lpc_host_event_mask for SCI and SMI.
- */
-static host_event_t backup_sci_mask;
-static host_event_t backup_smi_mask;
-
-/*
- * Clear host event masks for SMI and SCI when host is entering S0ix. This is
- * done to prevent any SCI/SMI interrupts when the host is in suspend. Since
- * BIOS is not involved in the suspend path, EC needs to take care of clearing
- * these masks.
- */
-static void lpc_s0ix_suspend_clear_masks(void)
-{
- backup_sci_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
- backup_smi_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI);
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, 0);
- lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, 0);
-}
-
-/*
- * Restore host event masks for SMI and SCI when host exits S0ix. This is done
- * because BIOS is not involved in the resume path and so EC needs to restore
- * the masks from backup variables.
- */
-static void lpc_s0ix_resume_restore_masks(void)
-{
- /*
- * No need to restore SCI/SMI masks if both backup_sci_mask and
- * backup_smi_mask are zero. This indicates that there was a failure to
- * enter S0ix(SLP_S0# assertion) and hence SCI/SMI masks were never
- * backed up.
- */
- if (!backup_sci_mask && !backup_smi_mask)
- return;
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, backup_sci_mask);
- lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, backup_smi_mask);
-
- backup_sci_mask = backup_smi_mask = 0;
-}
-
-static void lpc_s0ix_hang_detected(void)
-{
- /*
- * Wake up the AP so they don't just chill in a non-suspended state and
- * burn power. Overload a vaguely related event bit since event bits are
- * at a premium. If the system never entered S0ix, then manually set the
- * wake mask to pretend it did, so that the hang detect event wakes the
- * system.
- */
- if (power_get_state() == POWER_S0) {
- host_event_t sleep_wake_mask;
-
- get_lazy_wake_mask(POWER_S0ix, &sleep_wake_mask);
- lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, sleep_wake_mask);
- }
-
- CPRINTS("Warning: Detected sleep hang! Waking host up!");
- host_set_single_event(EC_HOST_EVENT_HANG_DETECT);
-}
-
-static void handle_chipset_suspend(void)
-{
- /* Clear masks before any hooks are run for suspend. */
- lpc_s0ix_suspend_clear_masks();
-}
-DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, handle_chipset_suspend, HOOK_PRIO_FIRST);
-
-static void handle_chipset_reset(void)
-{
- if (chipset_in_state(CHIPSET_STATE_STANDBY)) {
- CPRINTS("chipset reset: exit s0ix");
- power_reset_host_sleep_state();
- task_wake(TASK_ID_CHIPSET);
- }
-}
-DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST);
-
-void power_reset_host_sleep_state(void)
-{
- power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET);
- sleep_reset_tracking();
- power_chipset_handle_host_sleep_event(HOST_SLEEP_EVENT_DEFAULT_RESET,
- NULL);
-}
-
-#endif /* CONFIG_POWER_S0IX */
-
-void chipset_throttle_cpu(int throttle)
-{
-#ifdef CONFIG_CPU_PROCHOT_ACTIVE_LOW
- throttle = !throttle;
-#endif /* CONFIG_CPU_PROCHOT_ACTIVE_LOW */
- if (chipset_in_state(CHIPSET_STATE_ON))
- gpio_set_level(GPIO_CPU_PROCHOT, throttle);
-}
-
-enum power_state power_chipset_init(void)
-{
- CPRINTS("%s: power_signal=0x%x", __func__, power_get_signals());
-
- if (!system_jumped_to_this_image())
- return POWER_G3;
- /*
- * We are here as RW. We need to handle the following cases:
- *
- * 1. Late sysjump by software sync. AP is in S0.
- * 2. Shutting down in recovery mode then sysjump by EFS2. AP is in S5
- * and expected to sequence down.
- * 3. Rebooting from recovery mode then sysjump by EFS2. AP is in S5
- * and expected to sequence up.
- * 4. RO jumps to RW from main() by EFS2. (a.k.a. power on reset, cold
- * reset). AP is in G3.
- */
- if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) {
- /* case #1. Disable idle task deep sleep when in S0. */
- disable_sleep(SLEEP_MASK_AP_RUN);
- CPRINTS("already in S0");
- return POWER_S0;
- }
- if ((power_get_signals() & CHIPSET_G3S5_POWERUP_SIGNAL)
- == CHIPSET_G3S5_POWERUP_SIGNAL) {
- /* case #2 & #3 */
- CPRINTS("already in S5");
- return POWER_S5;
- }
- /* case #4 */
- chipset_force_g3();
- return POWER_G3;
-}
-
-enum power_state common_intel_x86_power_handle_state(enum power_state state)
-{
- switch (state) {
- case POWER_G3:
- break;
-
- case POWER_S5:
-#ifdef CONFIG_BOARD_HAS_RTC_RESET
- /* Wait for S5 exit and attempt RTC reset if supported */
- if (power_s5_up)
- return power_wait_s5_rtc_reset();
-#endif
-
- if (chipset_get_sleep_signal(SYS_SLEEP_S4) == 1)
- return POWER_S5S3; /* Power up to next state */
- break;
-
- case POWER_S3:
- if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
- /* Required rail went away */
- chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
- return POWER_S3S5;
- } else if (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1) {
- /* Power up to next state */
- return POWER_S3S0;
- } else if (chipset_get_sleep_signal(SYS_SLEEP_S4) == 0) {
- /* Power down to next state */
- return POWER_S3S5;
- }
- break;
-
- case POWER_S0:
- if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
- return POWER_S0S3;
- } else if (chipset_get_sleep_signal(SYS_SLEEP_S3) == 0) {
- /* Power down to next state */
- return POWER_S0S3;
-#ifdef CONFIG_POWER_S0IX
- /*
- * SLP_S0 may assert in system idle scenario without a kernel
- * freeze call. This may cause interrupt storm since there is
- * no freeze/unfreeze of threads/process in the idle scenario.
- * Ignore the SLP_S0 assertions in idle scenario by checking
- * the host sleep state.
- */
- } else if (power_get_host_sleep_state()
- == HOST_SLEEP_EVENT_S0IX_SUSPEND &&
- chipset_get_sleep_signal(SYS_SLEEP_S0IX) == 0) {
- return POWER_S0S0ix;
- } else {
- sleep_notify_transition(SLEEP_NOTIFY_RESUME,
- HOOK_CHIPSET_RESUME);
-#endif
- }
-
- break;
-
-#ifdef CONFIG_POWER_S0IX
- case POWER_S0ix:
- /* System in S0 only if SLP_S0 and SLP_S3 are de-asserted */
- if ((chipset_get_sleep_signal(SYS_SLEEP_S0IX) == 1) &&
- (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1)) {
- return POWER_S0ixS0;
- } else if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
- return POWER_S0;
- }
-
- break;
-#endif
-
- case POWER_G3S5:
- if (intel_x86_wait_power_up_ok() != EC_SUCCESS) {
- chipset_force_shutdown(
- CHIPSET_SHUTDOWN_BATTERY_INHIBIT);
- return POWER_G3;
- }
-#ifdef CONFIG_CHIPSET_HAS_PRE_INIT_CALLBACK
- /*
- * Callback to do pre-initialization within the context of
- * chipset task.
- */
- chipset_pre_init_callback();
-#endif
-
- if (power_wait_signals(CHIPSET_G3S5_POWERUP_SIGNAL)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
- return POWER_G3;
- }
-
- power_s5_up = 1;
- return POWER_S5;
-
- case POWER_S5S3:
- if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
- /* Required rail went away */
- chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
- return POWER_S5G3;
- }
-
- /* Call hooks now that rails are up */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
-#ifdef CONFIG_POWER_S0IX
- /*
- * Clearing the S0ix flag on the path to S0
- * to handle any reset conditions.
- */
- power_reset_host_sleep_state();
-#endif
- return POWER_S3;
-
- case POWER_S3S0:
- if (!power_has_signals(IN_PGOOD_ALL_CORE)) {
- /* Required rail went away */
- chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL);
- return POWER_S3S5;
- }
-
- /* Enable wireless */
- wireless_set_state(WIRELESS_ON);
-
- lpc_s3_resume_clear_masks();
-
- /* 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);
-
- /*
- * Throttle CPU if necessary. This should only be asserted
- * when +VCCP is powered (it is by now).
- */
-#ifdef CONFIG_CPU_PROCHOT_ACTIVE_LOW
- gpio_set_level(GPIO_CPU_PROCHOT, 1);
-#else
- gpio_set_level(GPIO_CPU_PROCHOT, 0);
-#endif /* CONFIG_CPU_PROCHOT_ACTIVE_LOW */
-
- return POWER_S0;
-
- 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);
-
-#ifdef CONFIG_POWER_S0IX
- /* re-init S0ix flag */
- power_reset_host_sleep_state();
-#endif
- return POWER_S3;
-
-#ifdef CONFIG_POWER_S0IX
- case POWER_S0S0ix:
- /*
- * Call hooks only if we haven't notified listeners of S0ix
- * suspend.
- */
- sleep_notify_transition(SLEEP_NOTIFY_SUSPEND,
- HOOK_CHIPSET_SUSPEND);
- sleep_suspend_transition();
-
- /*
- * Enable idle task deep sleep. Allow the low power idle task
- * to go into deep sleep in S0ix.
- */
- enable_sleep(SLEEP_MASK_AP_RUN);
- return POWER_S0ix;
-
- case POWER_S0ixS0:
- /*
- * 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);
-
- sleep_resume_transition();
- return POWER_S0;
-#endif
-
- case POWER_S3S5:
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
-
- /* Disable wireless */
- wireless_set_state(WIRELESS_OFF);
-
- /* Call hooks after we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-
- /* Always enter into S5 state. The S5 state is required to
- * correctly handle global resets which have a bit of delay
- * while the SLP_Sx_L signals are asserted then deasserted.
- */
- power_s5_up = 0;
- return POWER_S5;
-
- case POWER_S5G3:
- return chipset_force_g3();
-
- default:
- break;
- }
-
- return state;
-}
-
-void intel_x86_rsmrst_signal_interrupt(enum gpio_signal signal)
-{
- int rsmrst_in = gpio_get_level(GPIO_RSMRST_L_PGOOD);
- int rsmrst_out = gpio_get_level(GPIO_PCH_RSMRST_L);
-
- /*
- * This function is called when rsmrst changes state. If rsmrst
- * has been asserted (high -> low) then pass this new state to PCH.
- */
- if (!rsmrst_in && (rsmrst_in != rsmrst_out))
- gpio_set_level(GPIO_PCH_RSMRST_L, rsmrst_in);
-
- /*
- * Call the main power signal interrupt handler to wake up the chipset
- * task which handles low->high rsmrst pass through.
- */
- power_signal_interrupt(signal);
-}
-
-__overridable void board_before_rsmrst(int rsmrst)
-{
-}
-
-__overridable void board_after_rsmrst(int rsmrst)
-{
-}
-
-void common_intel_x86_handle_rsmrst(enum power_state state)
-{
- /*
- * Pass through RSMRST asynchronously, as PCH may not react
- * immediately to power changes.
- */
- int rsmrst_in = gpio_get_level(GPIO_RSMRST_L_PGOOD);
- int rsmrst_out = gpio_get_level(GPIO_PCH_RSMRST_L);
-
- /* Nothing to do. */
- if (rsmrst_in == rsmrst_out)
- return;
-
- board_before_rsmrst(rsmrst_in);
-
-#ifdef CONFIG_CHIPSET_APL_GLK
- /* Only passthrough RSMRST_L de-assertion on power up */
- if (rsmrst_in && !power_s5_up)
- return;
-#elif defined(CONFIG_CHIPSET_X86_RSMRST_DELAY)
- /*
- * Wait at least 10ms between power signals going high
- * and deasserting RSMRST to PCH.
- */
- if (rsmrst_in)
- msleep(10);
-#endif
-
- gpio_set_level(GPIO_PCH_RSMRST_L, rsmrst_in);
-
- CPRINTS("Pass through GPIO_RSMRST_L_PGOOD: %d", rsmrst_in);
-
- board_after_rsmrst(rsmrst_in);
-}
-
-#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
-
-__overridable void power_board_handle_host_sleep_event(
- enum host_sleep_event state)
-{
- /* Default weak implementation -- no action required. */
-}
-
-__override void power_chipset_handle_host_sleep_event(
- enum host_sleep_event state,
- struct host_sleep_event_context *ctx)
-{
- power_board_handle_host_sleep_event(state);
-
-#ifdef CONFIG_POWER_S0IX
- if (state == HOST_SLEEP_EVENT_S0IX_SUSPEND) {
- /*
- * Indicate to power state machine that a new host event for
- * s0ix/s3 suspend has been received and so chipset suspend
- * notification needs to be sent to listeners.
- */
- sleep_set_notify(SLEEP_NOTIFY_SUSPEND);
-
- sleep_start_suspend(ctx, lpc_s0ix_hang_detected);
- power_signal_enable_interrupt(sleep_sig[SYS_SLEEP_S0IX]);
- } else if (state == HOST_SLEEP_EVENT_S0IX_RESUME) {
- /*
- * Wake up chipset task and indicate to power state machine that
- * listeners need to be notified of chipset resume.
- */
- sleep_set_notify(SLEEP_NOTIFY_RESUME);
- task_wake(TASK_ID_CHIPSET);
- lpc_s0ix_resume_restore_masks();
- power_signal_disable_interrupt(sleep_sig[SYS_SLEEP_S0IX]);
- sleep_complete_resume(ctx);
- /*
- * If the sleep signal timed out and never transitioned, then
- * the wake mask was modified to its suspend state (S0ix), so
- * that the event wakes the system. Explicitly restore the wake
- * mask to its S0 state now.
- */
- power_update_wake_mask();
- } else if (state == HOST_SLEEP_EVENT_DEFAULT_RESET) {
- power_signal_disable_interrupt(sleep_sig[SYS_SLEEP_S0IX]);
- }
-#endif
-
-}
-
-#endif
-
-__overridable void intel_x86_sys_reset_delay(void)
-{
- /*
- * Debounce time for SYS_RESET_L is 16 ms. Wait twice that period
- * to be safe.
- */
- udelay(32 * MSEC);
-}
-
-void chipset_reset(enum chipset_reset_reason reason)
-{
- /*
- * Irrespective of cold_reset value, always toggle SYS_RESET_L to
- * perform a chipset reset. RCIN# which was used earlier to trigger
- * a warm reset is known to not work in certain cases where the CPU
- * is in a bad state (crbug.com/721853).
- *
- * The EC cannot control warm vs cold reset of the chipset using
- * SYS_RESET_L; it's more of a request.
- */
- CPRINTS("%s: %d", __func__, reason);
-
- /*
- * Toggling SYS_RESET_L will not have any impact when it's already
- * low (i,e. Chipset is in reset state).
- */
- if (gpio_get_level(GPIO_SYS_RESET_L) == 0) {
- CPRINTS("Chipset is in reset state");
- return;
- }
-
- report_ap_reset(reason);
-
- gpio_set_level(GPIO_SYS_RESET_L, 0);
- intel_x86_sys_reset_delay();
- gpio_set_level(GPIO_SYS_RESET_L, 1);
-}
-
-enum ec_error_list intel_x86_wait_power_up_ok(void)
-{
-#ifdef CONFIG_CHARGER
- int tries = 0;
-
- /*
- * Allow charger to be initialized for up to defined tries,
- * in case we're trying to boot the AP with no battery.
- */
- while ((tries < CHARGER_INITIALIZED_TRIES) &&
- is_power_up_inhibited()) {
- msleep(CHARGER_INITIALIZED_DELAY_MS);
- tries++;
- }
-
- /*
- * Return to G3 if battery level is too low. Set
- * power_up_inhibited in order to check the eligibility to boot
- * AP up after battery SOC changes.
- */
- if (tries == CHARGER_INITIALIZED_TRIES) {
- CPRINTS("power-up inhibited");
- power_up_inhibited = 1;
- return EC_ERROR_TIMEOUT;
- }
-
- power_up_inhibited = 0;
-#endif
-
-#if defined(CONFIG_VBOOT_EFS) || defined(CONFIG_VBOOT_EFS2)
- /*
- * We have to test power readiness here (instead of S5->S3)
- * because when entering S5, EC enables EC_ROP_SLP_SUS pin
- * which causes (short-powered) system to brown out.
- */
- while (!system_can_boot_ap())
- msleep(200);
-#endif
-
- return EC_SUCCESS;
-}
diff --git a/power/mt817x.c b/power/mt817x.c
deleted file mode 100644
index e7e23605f2..0000000000
--- a/power/mt817x.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/* Copyright 2015 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.
- */
-
-/*
- * MT817x SoC power sequencing module for Chrome EC
- *
- * This implements the following features:
- *
- * - Cold reset powers on the AP
- *
- * When powered off:
- * - Press pwron turns on the AP
- * - Hold pwron turns on the AP, and then 8s later turns it off and leaves
- * it off until pwron is released and pressed again
- *
- * When powered on:
- * - The PMIC PWRON signal is released <= 1 second after the power button is
- * released
- * - Holding pwron for 8s powers off the AP
- * - Pressing and releasing pwron within that 8s is ignored
- * - If POWER_GOOD is dropped by the AP, then we power the AP off
- * - If SUSPEND_L goes low, enter suspend mode.
- *
- */
-
-#include "battery.h"
-#include "chipset.h" /* ./common/chipset.c implements chipset functions too */
-#include "common.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "keyboard_scan.h"
-#include "lid_switch.h"
-#include "power.h"
-#include "power_button.h"
-#include "power_led.h"
-#include "system.h"
-#include "task.h"
-#include "test_util.h"
-#include "util.h"
-
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-#define INT_BOTH_PULL_UP (GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH)
-
-/* masks for power signals */
-#define IN_POWER_GOOD POWER_SIGNAL_MASK(MTK_POWER_GOOD)
-#define IN_SUSPEND POWER_SIGNAL_MASK(MTK_SUSPEND_ASSERTED)
-
-/* Long power key press to force shutdown */
-#define DELAY_FORCE_SHUTDOWN (8000 * MSEC) /* 8 seconds */
-
-/*
- * The power signal from SoC should be kept at least 50ms.
- */
-#define POWER_DEBOUNCE_TIME (50 * MSEC)
-
-/*
- * The suspend signal from SoC should be kept at least 50ms.
- */
-#define SUSPEND_DEBOUNCE_TIME (50 * MSEC)
-
-/*
- * The time to bootup the PMIC from power-off to power-on.
- */
-#define PMIC_PWRON_PRESS_TIME (5000 * MSEC)
-
-/*
- * The minimum time to assert the PMIC THERM pin is 32us. However,
- * it needs to be extended to about 50ms to let the 5V rail
- * dissipate fully.
- */
-#define PMIC_THERM_HOLD_TIME (50 * MSEC)
-
-/*
- * If the power key is pressed to turn on, then held for this long, we
- * power off.
- *
- * Normal case: User releases power button and chipset_task() goes
- * into the inner loop, waiting for next event to occur (power button
- * press or POWER_GOOD == 0).
- */
-#define DELAY_SHUTDOWN_ON_POWER_HOLD (8000 * MSEC) /* 8 seconds */
-
-/*
- * The hold time for pulling down the PMIC_WARM_RESET_H pin so that
- * the AP can entery the recovery mode (flash SPI flash from USB).
- */
-#define PMIC_WARM_RESET_H_HOLD_TIME (4 * MSEC)
-
-/*
- * The hold time for pulling down the SYSTEM_POWER_H pin.
- */
-#define PMIC_COLD_RESET_L_HOLD_TIME \
- (SUSPEND_DEBOUNCE_TIME + POWER_DEBOUNCE_TIME + (20 * MSEC))
-
-/*
- * The first time the PMIC sees power (AC or battery) it needs 200ms (+/-12%
- * oscillator tolerance) for the RTC startup. In addition there is a startup
- * time of approx. 0.5msec until V2_5 regulator starts up. */
-#define PMIC_RTC_STARTUP (225 * MSEC)
-
-/* Wait for 5V power source stable */
-#define PMIC_WAIT_FOR_5V_POWER_GOOD (1 * MSEC)
-
-/*
- * If POWER_GOOD is lost, wait for PMIC to turn off its power completely
- * before we turn off VBAT by set_system_power(0)
- */
-#define PMIC_POWER_OFF_DELAY (50 * MSEC)
-
-/* TODO(crosbug.com/p/25047): move to HOOK_POWER_BUTTON_CHANGE */
-/* 1 if the power button was pressed last time we checked */
-static char power_button_was_pressed;
-
-/* 1 if lid-open event has been detected */
-static char lid_opened;
-
-/* time where we will power off, if power button still held down */
-static timestamp_t power_off_deadline;
-
-/* force AP power on (used for recovery keypress) */
-static int auto_power_on;
-
-enum power_request_t {
- POWER_REQ_NONE,
- POWER_REQ_OFF,
- POWER_REQ_ON,
-
- POWER_REQ_COUNT,
-};
-
-static enum power_request_t power_request;
-
-/**
- * Return values for check_for_power_off_event().
- */
-enum power_off_event_t {
- POWER_OFF_CANCEL,
- POWER_OFF_BY_POWER_BUTTON_PRESSED,
- POWER_OFF_BY_LONG_PRESS,
- POWER_OFF_BY_POWER_GOOD_LOST,
- POWER_OFF_BY_POWER_REQ,
-
- POWER_OFF_EVENT_COUNT,
-};
-
-/**
- * Return values for check_for_power_on_event().
- */
-enum power_on_event_t {
- POWER_ON_CANCEL,
- POWER_ON_BY_IN_POWER_GOOD,
- POWER_ON_BY_AUTO_POWER_ON,
- POWER_ON_BY_LID_OPEN,
- POWER_ON_BY_POWER_BUTTON_PRESSED,
- POWER_ON_BY_POWER_REQ_NONE,
-
- POWER_ON_EVENT_COUNT,
-};
-
-/**
- * Parameters of mtk_backlight_override().
- */
-enum blacklight_override_t {
- MTK_BACKLIGHT_FORCE_OFF,
- MTK_BACKLIGHT_CONTROL_BY_SOC,
-
- MTK_BACKLIGHT_OVERRIDE_COUNT,
-};
-
-/* Forward declaration */
-static void chipset_turn_off_power_rails(void);
-
-/**
- * Check the suspend signal is on after SUSPEND_DEBOUNCE_TIME to avoid transient
- * state.
- *
- * @return non-zero if SUSPEND is asserted.
- */
-static int is_suspend_asserted(void)
-{
-#ifdef BOARD_OAK
- if ((power_get_signals() & IN_SUSPEND) &&
- (system_get_board_version() < 4))
- usleep(SUSPEND_DEBOUNCE_TIME);
-#endif
-
- return power_get_signals() & IN_SUSPEND;
-}
-
-/**
- * Check the suspend signal is off after SUSPEND_DEBOUNCE_TIME to avoid
- * transient state.
- *
- * @return non-zero if SUSPEND is deasserted.
- */
-static int is_suspend_deasserted(void)
-{
-#ifdef BOARD_OAK
- if (!(power_get_signals() & IN_SUSPEND) &&
- (system_get_board_version() < 4))
- usleep(SUSPEND_DEBOUNCE_TIME);
-#endif
-
- return !(power_get_signals() & IN_SUSPEND);
-}
-
-/**
- * Check power good signal is on after POWER_DEBOUNCE_TIME to avoid transient
- * state.
- *
- * @return non-zero if POWER_GOOD is asserted.
- */
-static int is_power_good_asserted(void)
-{
- if (!gpio_get_level(GPIO_SYSTEM_POWER_H))
- return 0;
-#ifdef BOARD_OAK
- else if ((power_get_signals() & IN_POWER_GOOD) &&
- (system_get_board_version() < 4))
- usleep(POWER_DEBOUNCE_TIME);
-#endif
-
- return power_get_signals() & IN_POWER_GOOD;
-}
-
-/**
- * Check power good signal is off after POWER_DEBOUNCE_TIME to avoid transient
- * state.
- *
- * @return non-zero if POWER_GOOD is deasserted.
- */
-static int is_power_good_deasserted(void)
-{
-#ifdef BOARD_OAK
- /*
- * Warm reset key from servo board lets the POWER_GOOD signal
- * deasserted temporarily (about 1~2 seconds) on rev4.
- * In order to detect this case, check the AP_RESET_L status,
- * ignore the transient state if reset key is pressing.
- */
- if (system_get_board_version() >= 4) {
- if (0 == gpio_get_level(GPIO_AP_RESET_L))
- return 0;
- } else {
- if (!(power_get_signals() & IN_POWER_GOOD))
- usleep(POWER_DEBOUNCE_TIME);
- }
-#endif
- if (0 == gpio_get_level(GPIO_AP_RESET_L))
- return 0;
-
- return !(power_get_signals() & IN_POWER_GOOD);
-}
-
-/**
- * Set the system power signal.
- *
- * @param asserted off (=0) or on (=1)
- */
-static void set_system_power(int asserted)
-{
- CPRINTS("set_system_power(%d)", asserted);
- gpio_set_level(GPIO_SYSTEM_POWER_H, asserted);
-}
-
-/**
- * Set the PMIC PWRON signal.
- *
- * Note that asserting requires holding for PMIC_PWRON_PRESS_TIME.
- *
- * @param asserted Assert (=1) or deassert (=0) the signal. This is the
- * logical level of the pin, not the physical level.
- */
-static void set_pmic_pwron(int asserted)
-{
- timestamp_t poll_deadline;
- /* Signal is active-high */
- CPRINTS("set_pmic_pwron(%d)", asserted);
- /* Oak rev1 power-on sequence:
- * raise GPIO_SYSTEM_POWER_H
- * wait for 5V power good, timeout 1 second
- */
- if (asserted) {
- set_system_power(asserted);
- poll_deadline = get_time();
- poll_deadline.val += SECOND;
- while (asserted && !gpio_get_level(GPIO_5V_POWER_GOOD) &&
- get_time().val < poll_deadline.val)
- usleep(PMIC_WAIT_FOR_5V_POWER_GOOD);
- if (!gpio_get_level(GPIO_5V_POWER_GOOD))
- CPRINTS("5V power not ready");
- }
-
- gpio_set_level(GPIO_PMIC_PWRON_H, asserted);
-}
-
-/**
- * Set the WARM RESET signal.
- *
- * @param asserted off (=0) or on (=1)
- */
-static void set_warm_reset(int asserted)
-{
- board_set_ap_reset(asserted);
-}
-
-/**
- * Check for some event triggering the shutdown.
- *
- * It can be either a long power button press or a shutdown triggered from the
- * AP and detected by reading POWER_GOOD.
- *
- * @return non-zero if a shutdown should happen, 0 if not
- */
-static int check_for_power_off_event(void)
-{
- timestamp_t now;
- int pressed = 0;
-
- /*
- * Check for power button press.
- */
- if (power_button_is_pressed()) {
- pressed = POWER_OFF_BY_POWER_BUTTON_PRESSED;
- } else if (power_request == POWER_REQ_OFF) {
- power_request = POWER_REQ_NONE;
- /* return non-zero for shudown down */
- return POWER_OFF_BY_POWER_REQ;
- }
-
- now = get_time();
- if (pressed) {
- if (!power_button_was_pressed) {
- power_off_deadline.val = now.val + DELAY_FORCE_SHUTDOWN;
- CPRINTS("power waiting for long press %u",
- power_off_deadline.le.lo);
- /* Ensure we will wake up to check the power key */
- timer_arm(power_off_deadline, TASK_ID_CHIPSET);
- } else if (timestamp_expired(power_off_deadline, &now)) {
- power_off_deadline.val = 0;
- CPRINTS("power off after long press now=%u, %u",
- now.le.lo, power_off_deadline.le.lo);
- return POWER_OFF_BY_LONG_PRESS;
- }
- } else if (power_button_was_pressed) {
- CPRINTS("power off cancel");
- timer_cancel(TASK_ID_CHIPSET);
- }
-
- power_button_was_pressed = pressed;
-
- /* POWER_GOOD released by AP : shutdown immediate */
- if (is_power_good_deasserted()) {
- /*
- * Cancel long press timer if power is lost and the power button
- * still press, otherwise EC will crash.
- */
- if (power_button_was_pressed)
- timer_cancel(TASK_ID_CHIPSET);
-
- CPRINTS("POWER_GOOD is lost");
- return POWER_OFF_BY_POWER_GOOD_LOST;
- }
-
- return POWER_OFF_CANCEL;
-}
-
-/**
- * Set the LCD backlight enable pin and override the signal from SoC.
- *
- * @param asserted MTK_BACKLIGHT_FORCE_OFF, force off the panel backlight
- * MTK_BACKLIGHT_CONTROL_BY_SOC, leave the control to SOC
- */
-static void mtk_backlight_override(enum blacklight_override_t asserted)
-{
- /* Signal is active-low */
- gpio_set_level(GPIO_EC_BL_OVERRIDE, !asserted);
-}
-
-static void mtk_lid_event(void)
-{
- enum blacklight_override_t bl_override;
-
- /* Override the panel backlight enable signal from SoC,
- * force the backlight off on lid close.
- */
- bl_override = lid_is_open() ?
- MTK_BACKLIGHT_CONTROL_BY_SOC :
- MTK_BACKLIGHT_FORCE_OFF;
- mtk_backlight_override(bl_override);
-
- /* Power task only cares about lid-open events */
- if (!lid_is_open())
- return;
-
- lid_opened = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, mtk_lid_event, HOOK_PRIO_DEFAULT);
-
-enum power_state power_chipset_init(void)
-{
- int init_power_state;
- uint32_t reset_flags = system_get_reset_flags();
-
- /*
- * Force the AP shutdown unless we are doing SYSJUMP. Otherwise,
- * the AP could stay in strange state.
- */
- if (!(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("not sysjump; forcing AP shutdown");
- chipset_turn_off_power_rails();
-
- /*
- * The warm reset triggers AP into the recovery mode (
- * flash SPI from USB).
- */
- chipset_reset(CHIPSET_RESET_UNKNOWN);
-
- init_power_state = POWER_G3;
- } else {
- /* In the SYSJUMP case, we check if the AP is on */
- if (is_power_good_asserted()) {
- CPRINTS("SOC ON");
- /*
- * Check and release PMIC power button signal,
- * if it's deferred callback function is not triggered
- * in RO before SYSJUMP.
- */
- if (gpio_get_level(GPIO_PMIC_PWRON_H))
- set_pmic_pwron(0);
-
- init_power_state = POWER_S0;
- if (is_suspend_asserted())
- enable_sleep(SLEEP_MASK_AP_RUN);
- else
- disable_sleep(SLEEP_MASK_AP_RUN);
- } else {
- CPRINTS("SOC OFF");
- init_power_state = POWER_G3;
- enable_sleep(SLEEP_MASK_AP_RUN);
- }
- }
-
- /* Leave power off only if requested by reset flags */
- if (!(reset_flags & EC_RESET_FLAG_AP_OFF) &&
- !(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("reset_flag 0x%x", reset_flags);
- auto_power_on = 1;
- }
-
- /*
- * Some batteries use clock stretching feature, which requires
- * more time to be stable. See http://crosbug.com/p/28289
- */
- battery_wait_for_stable();
-
- return init_power_state;
-}
-
-/*****************************************************************************/
-/* Chipset interface */
-
-static void chipset_turn_off_power_rails(void)
-{
- /* Release the power on pin, if it was asserted */
- set_pmic_pwron(0);
-
- /* system power off */
- usleep(PMIC_POWER_OFF_DELAY);
- set_system_power(0);
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s: %d", __func__, reason);
- report_ap_reset(reason);
-
- chipset_turn_off_power_rails();
-
- /* clean-up internal variable */
- power_request = POWER_REQ_NONE;
-}
-
-/*****************************************************************************/
-
-/**
- * Power off the AP
- */
-static void power_off(void)
-{
- /* Check the power off status */
- if (!gpio_get_level(GPIO_SYSTEM_POWER_H))
- return;
-
- /* Call hooks before we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
- /* switch off all rails */
- chipset_turn_off_power_rails();
-
- /* Change SUSPEND_L pin to high-Z to reduce power draw. */
- gpio_set_flags(power_signal_list[MTK_SUSPEND_ASSERTED].gpio,
- GPIO_INPUT);
-
- /* Change EC_INT to low */
- gpio_set_level(GPIO_EC_INT_L, 0);
-
- lid_opened = 0;
- enable_sleep(SLEEP_MASK_AP_RUN);
-#ifdef HAS_TASK_POWERLED
- powerled_set_state(POWERLED_STATE_OFF);
-#endif
- CPRINTS("power shutdown complete");
-
- /* Call hooks after we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-}
-
-/**
- * Check if there has been a power-on event
- *
- * This checks all power-on event signals and returns non-zero if any have been
- * triggered (with debounce taken into account).
- *
- * @return non-zero if there has been a power-on event, 0 if not.
- */
-static int check_for_power_on_event(void)
-{
- int ap_off_flag;
-
- ap_off_flag = system_get_reset_flags() & EC_RESET_FLAG_AP_OFF;
- system_clear_reset_flags(EC_RESET_FLAG_AP_OFF);
- /* check if system is already ON */
- if (is_power_good_asserted()) {
- if (ap_off_flag) {
- CPRINTS("system is on, but EC_RESET_FLAG_AP_OFF is on");
- return POWER_ON_CANCEL;
- } else {
- CPRINTS("system is on, thus clear " "auto_power_on");
- /* no need to arrange another power on */
- auto_power_on = 0;
- return POWER_ON_BY_IN_POWER_GOOD;
- }
- } else {
- if (ap_off_flag) {
- CPRINTS("EC_RESET_FLAG_AP_OFF is on");
- power_off();
- return POWER_ON_CANCEL;
- }
-
- CPRINTS("POWER_GOOD is not asserted");
- }
-
- /* power on requested at EC startup for recovery */
- if (auto_power_on) {
- auto_power_on = 0;
- return POWER_ON_BY_AUTO_POWER_ON;
- }
-
- /* Check lid open */
- if (lid_opened) {
- lid_opened = 0;
- return POWER_ON_BY_LID_OPEN;
- }
-
- /* check for power button press */
- if (power_button_is_pressed())
- return POWER_ON_BY_POWER_BUTTON_PRESSED;
-
- if (power_request == POWER_REQ_ON) {
- power_request = POWER_REQ_NONE;
- return POWER_ON_BY_POWER_REQ_NONE;
- }
-
- return POWER_OFF_CANCEL;
-}
-
-void release_pmic_pwron_deferred(void)
-{
- /* Release PMIC power button */
- set_pmic_pwron(0);
-}
-DECLARE_DEFERRED(release_pmic_pwron_deferred);
-
-/**
- * Power on the AP
- */
-static void power_on(void)
-{
- uint64_t t;
-
- /* Set pull-up and enable interrupt */
- gpio_set_flags(power_signal_list[MTK_SUSPEND_ASSERTED].gpio,
- GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH);
-
- /* Make sure we de-assert and GPIO_PMIC_WARM_RESET_H pin. */
- set_warm_reset(0);
-
- /*
- * Before we push PMIC power button, wait for the PMI RTC ready, which
- * takes PMIC_RTC_STARTUP from the AC/battery is plugged in.
- */
- t = get_time().val;
- if (t < PMIC_RTC_STARTUP) {
- uint32_t wait = PMIC_RTC_STARTUP - t;
-
- CPRINTS("wait for %dms for PMIC RTC start-up", wait / MSEC);
- usleep(wait);
- }
-
- /*
- * When power_on() is called, we are at S5S3. Initialize components
- * to ready state before AP is up.
- */
- hook_notify(HOOK_CHIPSET_PRE_INIT);
-
- /* Push the power button */
- set_pmic_pwron(1);
- hook_call_deferred(&release_pmic_pwron_deferred_data,
- PMIC_PWRON_PRESS_TIME);
-
- /* enable interrupt */
- gpio_set_flags(GPIO_SUSPEND_L, INT_BOTH_PULL_UP);
-
-#ifdef BOARD_OAK
- if (system_get_board_version() <= 3)
- gpio_set_flags(GPIO_EC_INT_L, GPIO_OUTPUT | GPIO_OUT_HIGH);
- else
- gpio_set_flags(GPIO_EC_INT_L, GPIO_ODR_HIGH);
-#else
- gpio_set_flags(GPIO_EC_INT_L, GPIO_ODR_HIGH);
-#endif
-
- disable_sleep(SLEEP_MASK_AP_RUN);
-#ifdef HAS_TASK_POWERLED
- powerled_set_state(POWERLED_STATE_ON);
-#endif
- /* Call hooks now that AP is running */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
- CPRINTS("AP running ...");
-}
-
-void chipset_reset(enum chipset_reset_reason reason)
-{
- CPRINTS("%s: %d", __func__, reason);
- report_ap_reset(reason);
-
- set_warm_reset(1);
- usleep(PMIC_WARM_RESET_H_HOLD_TIME);
- /* deassert the reset signals */
- set_warm_reset(0);
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- int value;
- static int boot_from_g3;
-
- switch (state) {
- case POWER_G3:
- boot_from_g3 = check_for_power_on_event();
- if (boot_from_g3)
- return POWER_G3S5;
- break;
-
- case POWER_G3S5:
- return POWER_S5;
-
- case POWER_S5:
- if (boot_from_g3) {
- value = boot_from_g3;
- boot_from_g3 = 0;
- } else {
- value = check_for_power_on_event();
- }
-
- if (value) {
- CPRINTS("power on %d", value);
- return POWER_S5S3;
- }
- return state;
-
- case POWER_S5S3:
- power_on();
- if (power_wait_signals(IN_POWER_GOOD) == EC_SUCCESS) {
- CPRINTS("POWER_GOOD seen");
- power_button_was_pressed = 0;
- return POWER_S3;
- } else {
- CPRINTS("POWER_GOOD not seen in time");
- }
- set_pmic_pwron(0);
- return POWER_S5;
-
- case POWER_S3:
- if (is_power_good_deasserted()) {
- power_off();
- return POWER_S3S5;
- } else if (is_suspend_deasserted())
- return POWER_S3S0;
- return state;
-
- case POWER_S3S0:
- disable_sleep(SLEEP_MASK_AP_RUN);
-#ifdef HAS_TASK_POWERLED
- powerled_set_state(POWERLED_STATE_ON);
-#endif
- hook_notify(HOOK_CHIPSET_RESUME);
- return POWER_S0;
-
- case POWER_S0:
- value = check_for_power_off_event();
- if (value) {
- CPRINTS("power off %d", value);
- power_off();
- return POWER_S0S3;
- } else if (is_suspend_asserted())
- return POWER_S0S3;
- return state;
-
- case POWER_S0S3:
-#ifdef HAS_TASK_POWERLED
- if (lid_is_open())
- powerled_set_state(POWERLED_STATE_SUSPEND);
- else
- powerled_set_state(POWERLED_STATE_OFF);
-#endif
- /*
- * if the power button is pressing, we need cancel the long
- * press timer, otherwise EC will crash.
- */
- if (power_button_was_pressed)
- timer_cancel(TASK_ID_CHIPSET);
-
- /* Call hooks here since we don't know it prior to AP suspend */
- hook_notify(HOOK_CHIPSET_SUSPEND);
- enable_sleep(SLEEP_MASK_AP_RUN);
- return POWER_S3;
-
- case POWER_S3S5:
- power_button_wait_for_release(-1);
- power_button_was_pressed = 0;
- return POWER_S5;
-
- case POWER_S5G3:
- return POWER_G3;
- }
-
- return state;
-}
-
-static void powerbtn_mtk_changed(void)
-{
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, powerbtn_mtk_changed, HOOK_PRIO_DEFAULT);
-
-/*****************************************************************************/
-/* Console debug command */
-
-static const char *power_req_name[POWER_REQ_COUNT] = {
- "none",
- "off",
- "on",
-};
-
-/* Power states that we can report */
-enum power_state_t {
- PSTATE_UNKNOWN,
- PSTATE_OFF,
- PSTATE_SUSPEND,
- PSTATE_ON,
-
- PSTATE_COUNT,
-};
-
-static const char * const state_name[] = {
- "unknown",
- "off",
- "suspend",
- "on",
-};
-
-static int command_power(int argc, char **argv)
-{
- int v;
-
- if (argc < 2) {
- enum power_state_t state;
-
- state = PSTATE_UNKNOWN;
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- state = PSTATE_OFF;
- if (chipset_in_state(CHIPSET_STATE_SUSPEND))
- state = PSTATE_SUSPEND;
- if (chipset_in_state(CHIPSET_STATE_ON))
- state = PSTATE_ON;
- ccprintf("%s\n", state_name[state]);
-
- return EC_SUCCESS;
- }
-
- if (!parse_bool(argv[1], &v))
- return EC_ERROR_PARAM1;
-
- power_request = v ? POWER_REQ_ON : POWER_REQ_OFF;
- ccprintf("Requesting power %s\n", power_req_name[power_request]);
- task_wake(TASK_ID_CHIPSET);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(power, command_power,
- "on/off",
- "Turn AP power on/off");
diff --git a/power/mt8183.c b/power/mt8183.c
deleted file mode 100644
index bdbd319601..0000000000
--- a/power/mt8183.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/* Copyright 2018 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.
- */
-
-/* mt8183 chipset power control module for Chrome EC */
-
-#include "charge_state.h"
-#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 "task.h"
-#include "timer.h"
-#include "util.h"
-
-/*
- * mt8183 has two different power sequence versions
- * 0: for normal tablet and detachable form factor
- * 1: for boards have GPIO_EN_PP1800_S5_L
- * CONFIG_CHIPSET_POWER_SEQ_VERSION defaults to 0, re-define the power seq
- * version if needed.
- */
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-/* Input state flags */
-#define IN_PGOOD_PMIC POWER_SIGNAL_MASK(PMIC_PWR_GOOD)
-#define IN_SUSPEND_ASSERTED POWER_SIGNAL_MASK(AP_IN_S3_L)
-
-/* Rails required for S3 and S0 */
-#define IN_PGOOD_S0 (IN_PGOOD_PMIC)
-#define IN_PGOOD_S3 (IN_PGOOD_PMIC)
-
-/* All inputs in the right state for S0 */
-#define IN_ALL_S0 (IN_PGOOD_S0 & ~IN_SUSPEND_ASSERTED)
-
-/* Long power key press to force shutdown in S0. go/crosdebug */
-#ifdef VARIANT_KUKUI_JACUZZI
-#define FORCED_SHUTDOWN_DELAY (8 * SECOND)
-#else
-#define FORCED_SHUTDOWN_DELAY (10 * SECOND)
-#endif
-
-/* Long power key press to boot from S5/G3 state. */
-#ifndef POWERBTN_BOOT_DELAY
-#define POWERBTN_BOOT_DELAY (1 * SECOND)
-#endif
-
-#define CHARGER_INITIALIZED_DELAY_MS 100
-#define CHARGER_INITIALIZED_TRIES 40
-
-#define PMIC_EN_PULSE_MS 50
-
-/* Maximum time it should for PMIC to turn on after toggling PMIC_EN_ODL. */
-#define PMIC_EN_TIMEOUT (300 * MSEC)
-
-/*
- * Amount of time we need to hold PMIC_FORCE_RESET_ODL to ensure PMIC is really
- * off and will not restart on its own.
- */
-#define PMIC_FORCE_RESET_TIME (10 * SECOND)
-
-/* Time delay in G3 to deassert EN_PP1800_S5_L */
-#define EN_PP1800_S5_L_DEASSERT_TIME (20 * MSEC)
-
-/* Data structure for a GPIO operation for power sequencing */
-struct power_seq_op {
- /* enum gpio_signal in 8 bits */
- uint8_t signal;
- uint8_t level;
- /* Number of milliseconds to delay after setting signal to level */
- uint8_t delay;
-};
-BUILD_ASSERT(GPIO_COUNT < 256);
-
-/*
- * This is the power sequence for POWER_S5S3.
- * The entries in the table are handled sequentially from the top
- * to the bottom.
- */
-
-static const struct power_seq_op s5s3_power_seq[] = {
- /* Release PMIC watchdog. */
- { GPIO_PMIC_WATCHDOG_L, 1, 0 },
- /* Turn on AP. */
- { GPIO_AP_SYS_RST_L, 1, 2 },
-};
-
-/* The power sequence for POWER_S3S0 */
-static const struct power_seq_op s3s0_power_seq[] = {
-};
-
-/* The power sequence for POWER_S0S3 */
-static const struct power_seq_op s0s3_power_seq[] = {
-};
-
-/* The power sequence for POWER_S3S5 */
-static const struct power_seq_op s3s5_power_seq[] = {
- /* Turn off AP. */
- { GPIO_AP_SYS_RST_L, 0, 0 },
- /* Assert watchdog to PMIC (there may be a 1.6ms debounce) */
- { GPIO_PMIC_WATCHDOG_L, 0, 3 },
-};
-
-static int forcing_shutdown;
-static int boot_from_cutoff;
-
-void chipset_reset_request_interrupt(enum gpio_signal signal)
-{
- chipset_reset(CHIPSET_RESET_AP_REQ);
-}
-
-/*
- * Triggers on falling edge of AP watchdog line only. The falling edge can
- * happen in these 3 cases:
- * - AP asserts watchdog while the AP is on: this is a real AP-initiated reset.
- * - EC asserted GPIO_AP_SYS_RST_L, so the AP is in reset and AP watchdog falls
- * as well. This is _not_ a watchdog reset. We mask these cases by disabling
- * the interrupt just before shutting down the AP, and re-enabling it just
- * after starting the AP.
- * - PMIC has shut down (e.g. the AP powered off by itself), this is not a
- * watchdog reset either. This should be covered by the case above if the
- * EC reacts quickly enough, but we mask those cases as well by testing if
- * the PMIC is still on when the watchdog line falls.
- */
-void chipset_watchdog_interrupt(enum gpio_signal signal)
-{
- if (power_get_signals() & IN_PGOOD_PMIC)
- chipset_reset(CHIPSET_RESET_AP_WATCHDOG);
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * Force power off. This condition will reset once the state machine
- * transitions to G3.
- */
- forcing_shutdown = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-
-void chipset_force_shutdown_button(void)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_BUTTON);
-}
-DECLARE_DEFERRED(chipset_force_shutdown_button);
-
-void chipset_exit_hard_off_button(void)
-{
- /* Power up from off */
- forcing_shutdown = 0;
- chipset_exit_hard_off();
-}
-DECLARE_DEFERRED(chipset_exit_hard_off_button);
-
-#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
-static void power_reset_host_sleep_state(void)
-{
- power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET);
- sleep_reset_tracking();
- power_chipset_handle_host_sleep_event(HOST_SLEEP_EVENT_DEFAULT_RESET,
- NULL);
-}
-
-static void handle_chipset_reset(void)
-{
- if (chipset_in_state(CHIPSET_STATE_SUSPEND)) {
- CPRINTS("Chipset reset: exit s3");
- power_reset_host_sleep_state();
- task_wake(TASK_ID_CHIPSET);
- }
-}
-DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST);
-#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */
-
-/* If chipset needs to be reset, EC also reboots to RO. */
-void chipset_reset(enum chipset_reset_reason reason)
-{
- int flags = SYSTEM_RESET_HARD;
-
- CPRINTS("%s: %d", __func__, reason);
- report_ap_reset(reason);
-
- cflush();
- if (reason == CHIPSET_RESET_AP_WATCHDOG)
- flags |= SYSTEM_RESET_AP_WATCHDOG;
-
- system_reset(flags);
-
- /* This should not be reachable. */
- while (1)
- ;
-}
-
-enum power_state power_chipset_init(void)
-{
- /* Enable reboot / sleep control inputs from AP */
- gpio_enable_interrupt(GPIO_WARM_RESET_REQ);
- gpio_enable_interrupt(GPIO_AP_IN_SLEEP_L);
-
- if (system_jumped_to_this_image()) {
- if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) {
- disable_sleep(SLEEP_MASK_AP_RUN);
- gpio_enable_interrupt(GPIO_AP_EC_WATCHDOG_L);
- CPRINTS("already in S0");
- return POWER_S0;
- }
- } else if (system_get_reset_flags() & EC_RESET_FLAG_AP_OFF) {
- /* Force shutdown from S5 if the PMIC is already up. */
- if (power_get_signals() & IN_PGOOD_PMIC) {
- forcing_shutdown = 1;
- return POWER_S5;
- }
- } else {
- /* Auto-power on */
- chipset_exit_hard_off();
-
- if (system_get_reset_flags() == EC_RESET_FLAG_RESET_PIN)
- boot_from_cutoff = 1;
- }
-
- /* Start from S5 if the PMIC is already up. */
- if (power_get_signals() & IN_PGOOD_PMIC)
- return POWER_S5;
-
- return POWER_G3;
-}
-
-/*
- * If we have to force reset the PMIC, we only need to do so for a few seconds,
- * then we need to release the GPIO to prevent leakage in G3.
- */
-static void release_pmic_force_reset(void)
-{
- CPRINTS("Releasing PMIC force reset");
- gpio_set_level(GPIO_PMIC_FORCE_RESET_ODL, 1);
-}
-DECLARE_DEFERRED(release_pmic_force_reset);
-
-/**
- * Step through the power sequence table and do corresponding GPIO operations.
- *
- * @param power_seq_ops The pointer to the power sequence table.
- * @param op_count The number of entries of power_seq_ops.
- */
-static void power_seq_run(const struct power_seq_op *power_seq_ops,
- int op_count)
-{
- int i;
-
- for (i = 0; i < op_count; i++) {
- gpio_set_level(power_seq_ops[i].signal,
- power_seq_ops[i].level);
- if (!power_seq_ops[i].delay)
- continue;
- msleep(power_seq_ops[i].delay);
- }
-}
-
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
-static void deassert_en_pp1800_s5_l(void)
-{
- gpio_set_level(GPIO_EN_PP1800_S5_L, 1);
-}
-DECLARE_DEFERRED(deassert_en_pp1800_s5_l);
-#endif
-
-enum power_state power_handle_state(enum power_state state)
-{
- /*
- * Set if we already had a rising edge on AP_SYS_RST_L. If so, any
- * subsequent boot attempt will require an EC reset.
- */
- static int booted;
-
- /* Retry S5->S3 transition, if not zero. */
- static int s5s3_retry;
-
- /*
- * PMIC power went away (AP most likely decided to shut down):
- * transition to S5, G3.
- */
- static int ap_shutdown;
- uint16_t tries = 0;
-
- switch (state) {
- case POWER_G3:
-
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
- hook_call_deferred(&deassert_en_pp1800_s5_l_data,
- EN_PP1800_S5_L_DEASSERT_TIME);
-#endif
-
- /* Go back to S5->G3 if the PMIC unexpectedly starts again. */
- if (power_get_signals() & IN_PGOOD_PMIC)
- return POWER_S5G3;
- break;
-
- case POWER_S5:
- boot_from_cutoff = 0;
-
- /*
- * If AP initiated shutdown, PMIC is off, and we can transition
- * to G3 immediately.
- */
- if (ap_shutdown) {
- ap_shutdown = 0;
- return POWER_S5G3;
- } else if (!forcing_shutdown) {
- /* Powering up. */
- s5s3_retry = 1;
- return POWER_S5S3;
- }
-
- /* Forcing shutdown */
-
- /* Long press has worked, transition to G3. */
- if (!(power_get_signals() & IN_PGOOD_PMIC))
- return POWER_S5G3;
-
- /*
- * Try to force PMIC shutdown with a long press. This takes 8s,
- * shorter than the common code S5->G3 timeout (10s).
- */
- CPRINTS("Forcing shutdown with long press.");
- gpio_set_level(GPIO_PMIC_EN_ODL, 0);
-
- /*
- * Stay in S5, common code will drop to G3 after timeout
- * if the long press does not work.
- */
- return POWER_S5;
-
- case POWER_S3:
- if (!power_has_signals(IN_PGOOD_S3) || forcing_shutdown)
- return POWER_S3S5;
- else if (!(power_get_signals() & IN_SUSPEND_ASSERTED))
- return POWER_S3S0;
- break;
-
- case POWER_S0:
- if (!power_has_signals(IN_PGOOD_S0) ||
- forcing_shutdown ||
- power_get_signals() & IN_SUSPEND_ASSERTED)
- return POWER_S0S3;
-
- break;
-
- case POWER_G3S5:
- forcing_shutdown = 0;
-
-#ifdef CONFIG_BATTERY_SMART
- /*
- * b:148045048: With the adapter to activate the smart battery
- * which is shutdown mode, will enable PMIC during activation
- * and have heavy loading, which will prevent the system from
- * powering on. Delay to boot system until the smart battry
- * is ready.
- */
- if (battery_hw_present() && boot_from_cutoff) {
- static int total_sleep_ms;
-
- if (total_sleep_ms < 4000) {
- msleep(10);
- total_sleep_ms += 10;
- return POWER_G3S5;
- }
- }
-#endif
-
- /*
- * Allow time for charger to be initialized, in case we're
- * trying to boot the AP with no battery.
- */
- while (charge_prevent_power_on(0) &&
- tries++ < CHARGER_INITIALIZED_TRIES) {
- msleep(CHARGER_INITIALIZED_DELAY_MS);
- }
-
- /* Return to G3 if battery level is too low. */
- if (charge_want_shutdown() ||
- tries > CHARGER_INITIALIZED_TRIES) {
- CPRINTS("power-up inhibited");
- chipset_force_shutdown(
- CHIPSET_SHUTDOWN_BATTERY_INHIBIT);
- return POWER_G3;
- }
-
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
- hook_call_deferred(&deassert_en_pp1800_s5_l_data, -1);
-#endif
- hook_call_deferred(&release_pmic_force_reset_data, -1);
- gpio_set_level(GPIO_PMIC_FORCE_RESET_ODL, 1);
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
- gpio_set_level(GPIO_EN_PP1800_S5_L, 0);
-#endif
-
- /* Power up to next state */
- return POWER_S5;
-
- case POWER_S5S3:
- hook_notify(HOOK_CHIPSET_PRE_INIT);
-
- /*
- * Release power button in case it was pressed by force shutdown
- * sequence.
- */
- gpio_set_level(GPIO_PMIC_EN_ODL, 1);
-
- /* If PMIC is off, switch it on by pulsing PMIC enable. */
- if (!(power_get_signals() & IN_PGOOD_PMIC)) {
- msleep(PMIC_EN_PULSE_MS);
- gpio_set_level(GPIO_PMIC_EN_ODL, 0);
- msleep(PMIC_EN_PULSE_MS);
- gpio_set_level(GPIO_PMIC_EN_ODL, 1);
- }
-
- /* If EC jumped, or has already booted once, reboot to RO. */
- if (system_jumped_to_this_image() || booted) {
- /*
- * TODO(b:109850749): How quickly does the EC come back
- * up? Would IN_PGOOD_PMIC be ready by the time we are
- * back? According to PMIC spec, it should take ~158 ms
- * after debounce (32 ms), minus PMIC_EN_PULSE_MS above.
- * It would be good to avoid another _EN pulse above.
- */
- chipset_reset(CHIPSET_RESET_AP_REQ);
- }
-
- /*
- * Wait for PMIC to bring up rails. Retry if it fails
- * (it may take 2 attempts on restart after we use
- * force reset).
- */
- if (power_wait_signals_timeout(IN_PGOOD_PMIC,
- PMIC_EN_TIMEOUT)) {
- if (s5s3_retry) {
- s5s3_retry = 0;
- return POWER_S5S3;
- }
- /* Give up, go back to G3. */
- return POWER_S5G3;
- }
-
- booted = 1;
- /* Enable S3 power supplies, release AP reset. */
- power_seq_run(s5s3_power_seq, ARRAY_SIZE(s5s3_power_seq));
- gpio_enable_interrupt(GPIO_AP_EC_WATCHDOG_L);
-
- /* Call hooks now that rails are up */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
- /*
- * Clearing the sleep failure detection tracking on the path
- * to S0 to handle any reset conditions.
- */
-#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION
- power_reset_host_sleep_state();
-#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */
-
- /* Power up to next state */
- return POWER_S3;
-
- case POWER_S3S0:
- power_seq_run(s3s0_power_seq, ARRAY_SIZE(s3s0_power_seq));
-
- if (power_wait_signals(IN_PGOOD_S0)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
- return POWER_S0S3;
- }
-
- /* Call hooks now that rails are up */
- hook_notify(HOOK_CHIPSET_RESUME);
-
-#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION
- sleep_resume_transition();
-#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */
-
- /*
- * 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);
-
- /* Power up to next state */
- return POWER_S0;
-
- case POWER_S0S3:
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SUSPEND);
-
-#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION
- sleep_suspend_transition();
-#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */
-
- /*
- * TODO(b:109850749): Check if we need some delay here to
- * "debounce" entering suspend (rk3399 uses 20ms delay).
- */
-
- power_seq_run(s0s3_power_seq, ARRAY_SIZE(s0s3_power_seq));
-
- /*
- * 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);
-
- /*
- * In case the power button is held awaiting power-off timeout,
- * power off immediately now that we're entering S3.
- */
- if (power_button_is_pressed()) {
- forcing_shutdown = 1;
- hook_call_deferred(&chipset_force_shutdown_button_data,
- -1);
- }
-
- return POWER_S3;
-
- case POWER_S3S5:
- /* PMIC has shutdown, transition to G3. */
- if (!(power_get_signals() & IN_PGOOD_PMIC))
- ap_shutdown = 1;
-
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
-
- gpio_disable_interrupt(GPIO_AP_EC_WATCHDOG_L);
- power_seq_run(s3s5_power_seq, ARRAY_SIZE(s3s5_power_seq));
-
- /* Call hooks after we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-
- /* Start shutting down */
- return POWER_S5;
-
- case POWER_S5G3:
- /* Release the power button, in case it was long pressed. */
- if (forcing_shutdown)
- gpio_set_level(GPIO_PMIC_EN_ODL, 1);
-
- /*
- * If PMIC is still not off, assert PMIC_FORCE_RESET_ODL.
- * This should only happen for forced shutdown where the AP is
- * not able to send a command to the PMIC, and where the long
- * power+home press did not work (if the PMIC is misconfigured).
- * Also, PMIC will lose RTC state, in that case.
- */
- if (power_get_signals() & IN_PGOOD_PMIC) {
- CPRINTS("Forcing PMIC off");
- gpio_set_level(GPIO_PMIC_FORCE_RESET_ODL, 0);
- msleep(5);
- hook_call_deferred(&release_pmic_force_reset_data,
- PMIC_FORCE_RESET_TIME);
-
- return POWER_S5G3;
- }
-
- return POWER_G3;
- }
-
- return state;
-}
-
-#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
-static void suspend_hang_detected(void)
-{
- CPRINTS("Warning: Detected sleep hang! Waking host up!");
- host_set_single_event(EC_HOST_EVENT_HANG_DETECT);
-}
-
-__override void power_chipset_handle_host_sleep_event(
- enum host_sleep_event state,
- struct host_sleep_event_context *ctx)
-{
- CPRINTS("Handle sleep: %d", state);
-
- if (state == HOST_SLEEP_EVENT_S3_SUSPEND) {
- /*
- * Indicate to power state machine that a new host event for
- * S3 suspend has been received and so chipset suspend
- * notification needs to be sent to listeners.
- */
- sleep_set_notify(SLEEP_NOTIFY_SUSPEND);
- sleep_start_suspend(ctx, suspend_hang_detected);
-
- } else if (state == HOST_SLEEP_EVENT_S3_RESUME) {
- /*
- * Wake up chipset task and indicate to power state machine that
- * listeners need to be notified of chipset resume.
- */
- sleep_set_notify(SLEEP_NOTIFY_RESUME);
- task_wake(TASK_ID_CHIPSET);
- sleep_complete_resume(ctx);
-
- }
-}
-#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */
-
-static void power_button_changed(void)
-{
- if (power_button_is_pressed()) {
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- hook_call_deferred(&chipset_exit_hard_off_button_data,
- POWERBTN_BOOT_DELAY);
-
- /* Delayed power down from S0/S3, cancel on PB release */
- hook_call_deferred(&chipset_force_shutdown_button_data,
- FORCED_SHUTDOWN_DELAY);
- } else {
- /* Power button released, cancel deferred shutdown/boot */
- hook_call_deferred(&chipset_exit_hard_off_button_data, -1);
- hook_call_deferred(&chipset_force_shutdown_button_data, -1);
- }
-}
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT);
-
-#ifdef CONFIG_LID_SWITCH
-static void lid_changed(void)
-{
- /* Power-up from off on lid open */
- if (lid_is_open() && chipset_in_state(CHIPSET_STATE_ANY_OFF))
- chipset_exit_hard_off();
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, lid_changed, HOOK_PRIO_DEFAULT);
-#endif
diff --git a/power/mt8192.c b/power/mt8192.c
deleted file mode 100644
index 323994faea..0000000000
--- a/power/mt8192.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/* Copyright 2020 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.
- */
-
-/*
- * MT8192 SoC power sequencing module for Chrome EC
- *
- * This implements the following features:
- *
- * - Cold reset powers on the AP
- *
- * When powered off:
- * - Press power button turns on the AP
- * - Hold power button turns on the AP, and then 8s later turns it off and
- * leaves it off until pwron is released and press again.
- * - Lid open turns on the AP
- *
- * When powered on:
- * - Holding power button for 8s powers off the AP
- * - Pressing and releaseing pwron within that 8s is ignored
- */
-
-#include "battery.h"
-#include "chipset.h"
-#include "common.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "lid_switch.h"
-#include "power.h"
-#include "power_button.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-
-#ifdef CONFIG_BRINGUP
-#define GPIO_SET_LEVEL(signal, value) \
- gpio_set_level_verbose(CC_CHIPSET, signal, value)
-#else
-#define GPIO_SET_LEVEL(signal, value) gpio_set_level(signal, value)
-#endif
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ##args)
-
-/* Input state flags */
-#define IN_SUSPEND_ASSERTED POWER_SIGNAL_MASK(AP_IN_S3_L)
-#define IN_PGOOD_PMIC POWER_SIGNAL_MASK(PMIC_PWR_GOOD)
-#define IN_AP_WDT_ASSERTED POWER_SIGNAL_MASK(AP_WDT_ASSERTED)
-
-/* Rails required for S3 and S0 */
-#define IN_PGOOD_S0 (IN_PGOOD_PMIC)
-#define IN_PGOOD_S3 (IN_PGOOD_PMIC)
-
-/* All inputs in the right state for S0 */
-#define IN_ALL_S0 (IN_PGOOD_S0 & ~IN_SUSPEND_ASSERTED)
-
-/* Long power key press to force shutdown in S0. go/crosdebug */
-#define FORCED_SHUTDOWN_DELAY (8 * SECOND)
-
-/* Long power key press to boot from S5/G3 state. */
-#ifndef POWERBTN_BOOT_DELAY
-#define POWERBTN_BOOT_DELAY (10 * MSEC)
-#endif
-#define PMIC_EN_PULSE_MS 50
-
-/* Maximum time it should for PMIC to turn on after toggling PMIC_EN_ODL. */
-#define PMIC_EN_TIMEOUT (300 * MSEC)
-
-/* Time delay in G3 to deassert EN_PP1800_S5_L */
-#define EN_PP1800_S5_L_DEASSERT_TIME (20 * MSEC)
-
-/*
- * Time delay for AP on/off the AP_EC_WDT when received SYS_RST_ODL.
- * Generally it can be done within 3 ms.
- */
-#define AP_EC_WDT_TIMEOUT (100 * MSEC)
-
-/* 30 ms for hard reset, we hold it longer to prevent TPM false alarm. */
-#define SYS_RST_PULSE_LENGTH (50 * MSEC)
-
-/* power signal list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
- {GPIO_PMIC_EC_PWRGD, POWER_SIGNAL_ACTIVE_HIGH, "PMIC_PWR_GOOD"},
- {GPIO_AP_IN_SLEEP_L, POWER_SIGNAL_ACTIVE_LOW, "AP_IN_S3_L"},
- {GPIO_AP_EC_WATCHDOG_L, POWER_SIGNAL_ACTIVE_LOW, "AP_WDT_ASSERTED"},
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-static int forcing_shutdown;
-
-static void watchdog_interrupt_deferred(void)
-{
- chipset_reset(CHIPSET_RESET_AP_WATCHDOG);
-}
-DECLARE_DEFERRED(watchdog_interrupt_deferred);
-
-static void reset_request_interrupt_deferred(void)
-{
- chipset_reset(CHIPSET_RESET_AP_REQ);
-}
-DECLARE_DEFERRED(reset_request_interrupt_deferred);
-
-void chipset_reset_request_interrupt(enum gpio_signal signal)
-{
- hook_call_deferred(&reset_request_interrupt_deferred_data, 0);
-}
-
-/*
- * Triggers on falling edge of AP watchdog line only. The falling edge can
- * happen in these 3 cases:
- * - AP asserts watchdog while the AP is on: this is a real AP-initiated reset.
- * - EC asserted GPIO_SYS_RST_ODL, so the AP is in reset and AP watchdog falls
- * as well. This is _not_ a watchdog reset. We mask these cases by disabling
- * the interrupt just before shutting down the AP, and re-enabling it just
- * after starting the AP.
- * - PMIC has shut down (e.g. the AP powered off by itself), this is not a
- * watchdog reset either. This should be covered by the case above if the
- * EC reacts quickly enough, but we mask those cases as well by testing if
- * the PMIC is still on when the watchdog line falls.
- */
-void chipset_watchdog_interrupt(enum gpio_signal signal)
-{
- /* Pass AP_EC_WATCHDOG_L signal to PMIC */
- GPIO_SET_LEVEL(GPIO_EC_PMIC_WATCHDOG_L, gpio_get_level(signal));
-
- /* Update power signals */
- power_signal_interrupt(signal);
-
- /*
- * case 1: PMIC is good, WDT asserts, and EC is not asserting
- * SYS_RST_ODL. This is AP initiated real WDT.
- */
- if (gpio_get_level(GPIO_SYS_RST_ODL) &&
- power_get_signals() & IN_PGOOD_PMIC &&
- power_get_signals() & IN_AP_WDT_ASSERTED)
- hook_call_deferred(&watchdog_interrupt_deferred_data, 0);
-
- /*
- * case 2&3: Fall through. The chipset_reset should have been
- * invoked.
- */
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * Force power off. This condition will reset once the state machine
- * transitions to G3.
- */
- forcing_shutdown = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-
-void chipset_force_shutdown_button(void)
-{
- chipset_force_shutdown(CHIPSET_SHUTDOWN_BUTTON);
-}
-DECLARE_DEFERRED(chipset_force_shutdown_button);
-
-void chipset_exit_hard_off_button(void)
-{
- /* Power up from off */
- forcing_shutdown = 0;
- chipset_exit_hard_off();
-}
-DECLARE_DEFERRED(chipset_exit_hard_off_button);
-
-void chipset_reset(enum chipset_reset_reason reason)
-{
- CPRINTS("%s: %d", __func__, reason);
- report_ap_reset(reason);
-
- GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 0);
- usleep(SYS_RST_PULSE_LENGTH);
- GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 1);
-}
-
-#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
-static void power_reset_host_sleep_state(void)
-{
- power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET);
- sleep_reset_tracking();
- power_chipset_handle_host_sleep_event(HOST_SLEEP_EVENT_DEFAULT_RESET,
- NULL);
-}
-
-static void handle_chipset_reset(void)
-{
- if (chipset_in_state(CHIPSET_STATE_SUSPEND)) {
- CPRINTS("Chipset reset: exit s3");
- power_reset_host_sleep_state();
- task_wake(TASK_ID_CHIPSET);
- }
-}
-DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST);
-#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */
-
-enum power_state power_chipset_init(void)
-{
- int exit_hard_off = 1;
-
- /* Enable reboot / sleep control inputs from AP */
- gpio_enable_interrupt(GPIO_AP_EC_WARM_RST_REQ);
- gpio_enable_interrupt(GPIO_AP_IN_SLEEP_L);
-
- if (system_get_reset_flags() & EC_RESET_FLAG_SYSJUMP) {
- if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) {
- disable_sleep(SLEEP_MASK_AP_RUN);
- power_signal_enable_interrupt(GPIO_AP_EC_WATCHDOG_L);
- CPRINTS("already in S0");
- return POWER_S0;
- }
- } else if (system_get_reset_flags() & EC_RESET_FLAG_AP_OFF) {
- exit_hard_off = 0;
- } else if ((system_get_reset_flags() & EC_RESET_FLAG_HIBERNATE) &&
- gpio_get_level(GPIO_AC_PRESENT)) {
- /*
- * If AC present, assume this is a wake-up by AC insert.
- * Boot EC only.
- *
- * Note that extpower module is not initialized at this point,
- * the only way is to ask GPIO_AC_PRESENT directly.
- */
- exit_hard_off = 0;
- }
-
- if (battery_is_present() == BP_YES)
- /*
- * (crosbug.com/p/28289): Wait battery stable.
- * Some batteries use clock stretching feature, which requires
- * more time to be stable.
- */
- battery_wait_for_stable();
-
- if (exit_hard_off)
- /* Auto-power on */
- chipset_exit_hard_off();
-
- /* Start from S5 if the PMIC is already up. */
- if (power_get_signals() & IN_PGOOD_PMIC) {
- /* Force shutdown from S5 if the PMIC is already up. */
- if (!exit_hard_off)
- forcing_shutdown = 1;
- return POWER_S5;
- }
-
- return POWER_G3;
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- /* Retry S5->S3 transition, if not zero. */
- static int s5s3_retry;
-
- /*
- * PMIC power went away (AP most likely decided to shut down):
- * transition to S5, G3.
- */
- static int ap_shutdown;
-
- switch (state) {
- case POWER_G3:
-
- /* Go back to S5->G3 if the PMIC unexpectedly starts again. */
- if (power_get_signals() & IN_PGOOD_PMIC)
- return POWER_S5G3;
- break;
-
- case POWER_S5:
- /*
- * If AP initiated shutdown, PMIC is off, and we can transition
- * to G3 immediately.
- */
- if (ap_shutdown) {
- ap_shutdown = 0;
- return POWER_S5G3;
- } else if (!forcing_shutdown) {
- /* Powering up. */
- s5s3_retry = 1;
- return POWER_S5S3;
- }
-
- /* Forcing shutdown */
-
- /* Long press has worked, transition to G3. */
- if (!(power_get_signals() & IN_PGOOD_PMIC))
- return POWER_S5G3;
-
- /*
- * Try to force PMIC shutdown with a long press. This takes 8s,
- * shorter than the common code S5->G3 timeout (10s).
- *
- * Note: We might run twice at this line because we
- * deasserts SYS_RST_ODL in S5->S3 and then WDT interrupt
- * handler sets the wake event for chipset_task. This should be
- * no harm, but to prevent misunderstanding in the console, we
- * check EC_PMIC_EN_ODL before set.
- */
- if (gpio_get_level(GPIO_EC_PMIC_EN_ODL)) {
- CPRINTS("Forcing shutdown with long press.");
- GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 0);
- }
-
- /*
- * Stay in S5, common code will drop to G3 after timeout
- * if the long press does not work.
- */
- return POWER_S5;
-
- case POWER_S3:
- if (!power_has_signals(IN_PGOOD_S3) || forcing_shutdown)
- return POWER_S3S5;
- else if (!(power_get_signals() & IN_SUSPEND_ASSERTED))
- return POWER_S3S0;
- break;
-
- case POWER_S0:
- if (!power_has_signals(IN_PGOOD_S0) || forcing_shutdown ||
- power_get_signals() & IN_SUSPEND_ASSERTED)
- return POWER_S0S3;
-
- break;
-
- case POWER_G3S5:
- forcing_shutdown = 0;
-
- /* Power up to next state */
- return POWER_S5;
-
- case POWER_S5S3:
- hook_notify(HOOK_CHIPSET_PRE_INIT);
-
- /*
- * Release power button in case it was pressed by force shutdown
- * sequence.
- */
- GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 1);
-
- /* If PMIC is off, switch it on by pulsing PMIC enable. */
- if (!(power_get_signals() & IN_PGOOD_PMIC)) {
- msleep(PMIC_EN_PULSE_MS);
- GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 0);
- msleep(PMIC_EN_PULSE_MS);
- GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 1);
- }
-
- /*
- * Wait for PMIC to bring up rails. Retry if it fails
- * (it may take 2 attempts on restart after we use
- * force reset).
- */
- if (power_wait_signals_timeout(IN_PGOOD_PMIC,
- PMIC_EN_TIMEOUT)) {
- if (s5s3_retry) {
- s5s3_retry = 0;
- return POWER_S5S3;
- }
- /* Give up, go back to G3. */
- return POWER_S5G3;
- }
-
- /* Release AP reset and waits for AP pulling WDT up. */
- power_signal_enable_interrupt(GPIO_AP_EC_WATCHDOG_L);
- GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 1);
- if (power_wait_mask_signals_timeout(0, IN_AP_WDT_ASSERTED,
- AP_EC_WDT_TIMEOUT)) {
- if (s5s3_retry) {
- s5s3_retry = 0;
- return POWER_S5S3;
- }
- /* Give up, go back to G3. */
- return POWER_S5G3;
- }
-
- /* Call hooks now that rails are up */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
- /*
- * Clearing the sleep failure detection tracking on the path
- * to S0 to handle any reset conditions.
- */
-#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION
- power_reset_host_sleep_state();
-#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */
- /* Power up to next state */
- return POWER_S3;
-
- case POWER_S3S0:
- if (power_wait_signals(IN_PGOOD_S0)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
- return POWER_S0S3;
- }
-
- /* Call hooks now that rails are up */
- hook_notify(HOOK_CHIPSET_RESUME);
-
-#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION
- sleep_resume_transition();
-#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */
-
- /*
- * 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);
-
- /* Power up to next state */
- return POWER_S0;
-
- case POWER_S0S3:
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SUSPEND);
-
-#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION
- sleep_suspend_transition();
-#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */
-
- /*
- * 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);
-
- /*
- * In case the power button is held awaiting power-off timeout,
- * power off immediately now that we're entering S3.
- */
- if (power_button_is_pressed()) {
- forcing_shutdown = 1;
- hook_call_deferred(&chipset_force_shutdown_button_data,
- -1);
- }
-
- return POWER_S3;
-
- case POWER_S3S5:
- /* PMIC has shutdown, transition to G3. */
- if (!(power_get_signals() & IN_PGOOD_PMIC))
- ap_shutdown = 1;
-
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
-
- /*
- * Assert SYS_RST_ODL, and waits for AP finishing epilogue and
- * asserting WDT.
- */
- GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 0);
- if (EC_ERROR_TIMEOUT ==
- power_wait_signals_timeout(IN_AP_WDT_ASSERTED,
- AP_EC_WDT_TIMEOUT)) {
- CPRINTS("Timeout waitting AP watchdog, force if off");
- GPIO_SET_LEVEL(GPIO_EC_PMIC_WATCHDOG_L, 0);
- }
- power_signal_disable_interrupt(GPIO_AP_EC_WATCHDOG_L);
-
- /* Call hooks after we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-
- /* Start shutting down */
- return POWER_S5;
-
- case POWER_S5G3:
- /* Release the power button, in case it was long pressed. */
- if (forcing_shutdown)
- GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 1);
-
- /* If PMIC is not off, go back to S5 and try again. */
- if (power_get_signals() & IN_PGOOD_PMIC)
- return POWER_S5;
-
- return POWER_G3;
- }
-
- return state;
-}
-
-static void power_button_changed(void)
-{
- if (power_button_is_pressed()) {
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- hook_call_deferred(&chipset_exit_hard_off_button_data,
- POWERBTN_BOOT_DELAY);
-
- /* Delayed power down from S0/S3, cancel on PB release */
- hook_call_deferred(&chipset_force_shutdown_button_data,
- FORCED_SHUTDOWN_DELAY);
- } else {
- /* Power button released, cancel deferred shutdown/boot */
- hook_call_deferred(&chipset_exit_hard_off_button_data, -1);
- hook_call_deferred(&chipset_force_shutdown_button_data, -1);
- }
-}
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT);
-
-#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
-static void suspend_hang_detected(void)
-{
- CPRINTS("Warning: Detected sleep hang! Waking host up!");
- host_set_single_event(EC_HOST_EVENT_HANG_DETECT);
-}
-
-__override void power_chipset_handle_host_sleep_event(
- enum host_sleep_event state,
- struct host_sleep_event_context *ctx)
-{
- CPRINTS("Handle sleep: %d", state);
-
- if (state == HOST_SLEEP_EVENT_S3_SUSPEND) {
- /*
- * Indicate to power state machine that a new host event for
- * S3 suspend has been received and so chipset suspend
- * notification needs to be sent to listeners.
- */
- sleep_set_notify(SLEEP_NOTIFY_SUSPEND);
- sleep_start_suspend(ctx, suspend_hang_detected);
-
- } else if (state == HOST_SLEEP_EVENT_S3_RESUME) {
- /*
- * Wake up chipset task and indicate to power state machine that
- * listeners need to be notified of chipset resume.
- */
- sleep_set_notify(SLEEP_NOTIFY_RESUME);
- task_wake(TASK_ID_CHIPSET);
- sleep_complete_resume(ctx);
-
- }
-}
-#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */
-
-#ifdef CONFIG_LID_SWITCH
-static void lid_changed(void)
-{
- /* Power-up from off on lid open */
- if (lid_is_open() && chipset_in_state(CHIPSET_STATE_ANY_OFF))
- chipset_exit_hard_off();
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, lid_changed, HOOK_PRIO_DEFAULT);
-#endif
diff --git a/power/qcom.c b/power/qcom.c
deleted file mode 100644
index ef9e329111..0000000000
--- a/power/qcom.c
+++ /dev/null
@@ -1,1169 +0,0 @@
-/* Copyright 2019 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.
- */
-
-/*
- * SC7X80 SoC power sequencing module for Chrome EC
- *
- * This implements the following features:
- *
- * - Cold reset powers on the AP
- *
- * When powered off:
- * - Press power button turns on the AP
- * - Hold power button turns on the AP, and then 8s later turns it off and
- * leaves it off until pwron is released and pressed again
- * - Lid open turns on the AP
- *
- * When powered on:
- * - Holding power button for 8s powers off the AP
- * - Pressing and releasing pwron within that 8s is ignored
- * - If POWER_GOOD is dropped by the AP, then we power the AP off
- */
-
-#include "charge_state.h"
-#include "chipset.h"
-#include "common.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "lid_switch.h"
-#include "power.h"
-#include "power/qcom.h"
-#include "power_button.h"
-#include "system.h"
-#include "task.h"
-#include "util.h"
-
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-/* Power signal list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
- [SC7X80_AP_RST_ASSERTED] = {
- GPIO_AP_RST_L,
- POWER_SIGNAL_ACTIVE_LOW | POWER_SIGNAL_DISABLE_AT_BOOT,
- "AP_RST_ASSERTED",
- },
- [SC7X80_PS_HOLD] = {
- GPIO_PS_HOLD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PS_HOLD",
- },
- [SC7X80_POWER_GOOD] = {
- GPIO_POWER_GOOD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "POWER_GOOD",
- },
- [SC7X80_AP_SUSPEND] = {
- GPIO_AP_SUSPEND,
- POWER_SIGNAL_ACTIVE_HIGH,
- "AP_SUSPEND",
- },
-#ifdef CONFIG_CHIPSET_SC7180
- [SC7X80_WARM_RESET] = {
- GPIO_WARM_RESET_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "WARM_RESET_L",
- },
- [SC7X80_DEPRECATED_AP_RST_REQ] = {
- GPIO_DEPRECATED_AP_RST_REQ,
- POWER_SIGNAL_ACTIVE_HIGH,
- "DEPRECATED_AP_RST_REQ",
- },
-#endif /* defined(CONFIG_CHIPSET_SC7180) */
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-/* Masks for power signals */
-#define IN_POWER_GOOD POWER_SIGNAL_MASK(SC7X80_POWER_GOOD)
-#define IN_AP_RST_ASSERTED POWER_SIGNAL_MASK(SC7X80_AP_RST_ASSERTED)
-#define IN_SUSPEND POWER_SIGNAL_MASK(SC7X80_AP_SUSPEND)
-
-
-/* Long power key press to force shutdown */
-#define DELAY_FORCE_SHUTDOWN (8 * SECOND)
-
-/*
- * If the power button is pressed to turn on, then held for this long, we
- * power off.
- *
- * Normal case: User releases power button and chipset_task() goes
- * into the inner loop, waiting for next event to occur (power button
- * press or POWER_GOOD == 0).
- */
-#define DELAY_SHUTDOWN_ON_POWER_HOLD (8 * SECOND)
-
-/*
- * After trigger PMIC power sequence, how long it triggers AP to turn on
- * or off. Observed that the worst case is ~150ms. Pick a safe vale.
- */
-#define PMIC_POWER_AP_RESPONSE_TIMEOUT (350 * MSEC)
-
-/*
- * After force off the switch cap, how long the PMIC/AP totally off.
- * Observed that the worst case is 2s. Pick a safe vale.
- */
-#define FORCE_OFF_RESPONSE_TIMEOUT (4 * SECOND)
-
-/* Wait for polling the AP on signal */
-#define PMIC_POWER_AP_WAIT (1 * MSEC)
-
-/* The length of an issued low pulse to the PMIC_RESIN_L signal */
-#define PMIC_RESIN_PULSE_LENGTH (20 * MSEC)
-
-/* The timeout of the check if the system can boot AP */
-#define CAN_BOOT_AP_CHECK_TIMEOUT (1500 * MSEC)
-
-/* Wait for polling if the system can boot AP */
-#define CAN_BOOT_AP_CHECK_WAIT (200 * MSEC)
-
-/* The timeout of the check if the switchcap outputs good voltage */
-#define SWITCHCAP_PG_CHECK_TIMEOUT (100 * MSEC)
-
-/* Wait for polling if the switchcap outputs good voltage */
-#define SWITCHCAP_PG_CHECK_WAIT (6 * MSEC)
-
-/*
- * Delay between power-on the system and power-on the PMIC.
- * Some latest PMIC firmware needs this delay longer, for doing a cold
- * reboot.
- *
- * Measured on Herobrine IOB + Trogdor MLB, the delay takes ~200ms. Set
- * it with margin.
- */
-#define SYSTEM_POWER_ON_DELAY (300 * MSEC)
-
-/*
- * Delay between the PMIC power drop and power-off the system.
- * Qualcomm measured the entire POFF duration is around 70ms. Setting
- * this delay to the same value as the above power-on sequence, which
- * has much safer margin.
- */
-#define PMIC_POWER_OFF_DELAY (150 * MSEC)
-
-/* The AP_RST_L transition count of a normal AP warm reset */
-#define EXPECTED_AP_RST_TRANSITIONS 3
-
-/*
- * The timeout of waiting the next AP_RST_L transition. We measured
- * the interval between AP_RST_L transitions is 130ms ~ 150ms. Pick
- * a safer value.
- */
-#define AP_RST_TRANSITION_TIMEOUT (450 * MSEC)
-
-/* TODO(crosbug.com/p/25047): move to HOOK_POWER_BUTTON_CHANGE */
-/* 1 if the power button was pressed last time we checked */
-static char power_button_was_pressed;
-
-/* 1 if lid-open event has been detected */
-static char lid_opened;
-
-/* Time where we will power off, if power button still held down */
-static timestamp_t power_off_deadline;
-
-/* Force AP power on (used for recovery keypress) */
-static int auto_power_on;
-
-enum power_request_t {
- POWER_REQ_NONE,
- POWER_REQ_OFF,
- POWER_REQ_ON,
- POWER_REQ_RESET,
-
- POWER_REQ_COUNT,
-};
-
-static enum power_request_t power_request;
-
-/**
- * Return values for check_for_power_off_event().
- */
-enum power_off_event_t {
- POWER_OFF_CANCEL,
- POWER_OFF_BY_POWER_BUTTON_PRESSED,
- POWER_OFF_BY_LONG_PRESS,
- POWER_OFF_BY_POWER_GOOD_LOST,
- POWER_OFF_BY_POWER_REQ_OFF,
- POWER_OFF_BY_POWER_REQ_RESET,
-
- POWER_OFF_EVENT_COUNT,
-};
-
-/**
- * Return values for check_for_power_on_event().
- */
-enum power_on_event_t {
- POWER_ON_CANCEL,
- POWER_ON_BY_AUTO_POWER_ON,
- POWER_ON_BY_LID_OPEN,
- POWER_ON_BY_POWER_BUTTON_PRESSED,
- POWER_ON_BY_POWER_REQ_ON,
- POWER_ON_BY_POWER_REQ_RESET,
-
- POWER_ON_EVENT_COUNT,
-};
-
-#ifdef CONFIG_CHIPSET_RESET_HOOK
-static int ap_rst_transitions;
-
-static void notify_chipset_reset(void)
-{
- if (ap_rst_transitions != EXPECTED_AP_RST_TRANSITIONS)
- CPRINTS("AP_RST_L transitions not expected: %d",
- ap_rst_transitions);
-
- ap_rst_transitions = 0;
- hook_notify(HOOK_CHIPSET_RESET);
-}
-DECLARE_DEFERRED(notify_chipset_reset);
-#endif
-
-void chipset_ap_rst_interrupt(enum gpio_signal signal)
-{
-#ifdef CONFIG_CHIPSET_RESET_HOOK
- int delay;
-
- /*
- * Only care the raising edge and AP in S0/S3. The single raising edge
- * of AP power-on during S5S3 is ignored.
- */
- if (gpio_get_level(GPIO_AP_RST_L) &&
- chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_SUSPEND)) {
- ap_rst_transitions++;
- if (ap_rst_transitions >= EXPECTED_AP_RST_TRANSITIONS) {
- /*
- * Reach the expected transition count. AP is booting
- * up. Notify HOOK_CHIPSET_RESET immediately.
- */
- delay = 0;
- } else {
- /*
- * Should have more transitions of the AP_RST_L signal.
- * In case the AP_RST_L signal is not toggled, still
- * notify HOOK_CHIPSET_RESET.
- */
- delay = AP_RST_TRANSITION_TIMEOUT;
- }
- hook_call_deferred(&notify_chipset_reset_data, delay);
- }
-#endif
- power_signal_interrupt(signal);
-}
-
-/* Issue a request to initiate a reset sequence */
-static void request_cold_reset(void)
-{
- power_request = POWER_REQ_RESET;
- task_wake(TASK_ID_CHIPSET);
-}
-
-#ifdef CONFIG_CHIPSET_SC7180
-
-/* 1 if AP_RST_L and PS_HOLD is overdriven by EC */
-static char ap_rst_overdriven;
-
-void chipset_warm_reset_interrupt(enum gpio_signal signal)
-{
- /*
- * The warm_reset signal is pulled-up by a rail from PMIC. If the
- * warm_reset drops, it means:
- * * Servo or Cr50 holds the signal, or
- * * its pull-up rail POWER_GOOD drops.
- */
- if (!gpio_get_level(GPIO_WARM_RESET_L)) {
- if (gpio_get_level(GPIO_POWER_GOOD)) {
- /*
- * Servo or Cr50 holds the WARM_RESET_L signal.
- *
- * Overdrive AP_RST_L to hold AP. Overdrive PS_HOLD to
- * emulate AP being up to trick the PMIC into thinking
- * there’s nothing weird going on.
- */
- ap_rst_overdriven = 1;
- gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH |
- GPIO_SEL_1P8V | GPIO_OUT_HIGH);
- gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH |
- GPIO_SEL_1P8V | GPIO_OUT_LOW);
- }
- /* Ignore the else clause, the pull-up rail drops. */
- } else {
- if (ap_rst_overdriven) {
- /*
- * Servo or Cr50 releases the WARM_RESET_L signal.
- *
- * Cold reset the PMIC, doing S0->S5->S0 transition,
- * by issuing a request to initiate a reset sequence,
- * to recover the system. The transition to S5 makes
- * POWER_GOOD drop that triggers an interrupt to
- * high-Z both AP_RST_L and PS_HOLD.
- */
- CPRINTS("Long warm reset ended, "
- "cold resetting to restore confidence.");
- request_cold_reset();
- }
- /* If not overdriven, just a normal power-up, do nothing. */
- }
- power_signal_interrupt(signal);
-}
-
-void chipset_power_good_interrupt(enum gpio_signal signal)
-{
- if (!gpio_get_level(GPIO_POWER_GOOD) && ap_rst_overdriven) {
- /*
- * POWER_GOOD is the pull-up rail of WARM_RESET_L.
- * When POWER_GOOD drops, high-Z both AP_RST_L and PS_HOLD
- * to restore their states.
- */
- gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH |
- GPIO_SEL_1P8V);
- gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH |
- GPIO_SEL_1P8V);
- ap_rst_overdriven = 0;
- }
- power_signal_interrupt(signal);
-}
-#endif /* defined(CONFIG_CHIPSET_SC7180) */
-
-static void sc7x80_lid_event(void)
-{
- /* Power task only cares about lid-open events */
- if (!lid_is_open())
- return;
-
- lid_opened = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, sc7x80_lid_event, HOOK_PRIO_DEFAULT);
-
-static void sc7x80_powerbtn_changed(void)
-{
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, sc7x80_powerbtn_changed,
- HOOK_PRIO_DEFAULT);
-
-/**
- * Wait the switchcap GPIO0 PVC_PG signal asserted.
- *
- * When the output voltage is over the threshold PVC_PG_ADJ,
- * the PVC_PG is asserted.
- *
- * PVG_PG_ADJ is configured to 3.0V.
- * GPIO0 is configured as PVC_PG.
- *
- * @param enable 1 to wait the PMIC/AP on.
- * 0 to wait the PMIC/AP off.
- *
- * @return EC_SUCCESS or error
- */
-static int wait_switchcap_power_good(int enable)
-{
- timestamp_t poll_deadline;
-
- poll_deadline = get_time();
- poll_deadline.val += SWITCHCAP_PG_CHECK_TIMEOUT;
- while (enable != board_is_switchcap_power_good() &&
- get_time().val < poll_deadline.val) {
- usleep(SWITCHCAP_PG_CHECK_WAIT);
- }
-
- /*
- * Check the timeout case. Just show a message. More check later
- * will switch the power state.
- */
- if (enable != board_is_switchcap_power_good()) {
- if (enable)
- CPRINTS("SWITCHCAP NO POWER GOOD!");
- else
- CPRINTS("SWITCHCAP STILL POWER GOOD!");
- return EC_ERROR_UNKNOWN;
- }
- return EC_SUCCESS;
-}
-
-/**
- * Get the state of the system power signals.
- *
- * @return 1 if the system is powered, 0 if not
- */
-static int is_system_powered(void)
-{
- return board_is_switchcap_enabled();
-}
-
-/**
- * Get the PMIC/AP power signal.
- *
- * We treat the PMIC chips and the AP as a whole here. Don't deal with
- * the individual chip.
- *
- * @return 1 if the PMIC/AP is powered, 0 if not
- */
-static int is_pmic_pwron(void)
-{
- /* Use POWER_GOOD to indicate PMIC/AP is on/off */
- return gpio_get_level(GPIO_POWER_GOOD);
-}
-
-/**
- * Wait the PMIC/AP power-on state.
- *
- * @param enable 1 to wait the PMIC/AP on.
- * 0 to wait the PMIC/AP off.
- * @param timeout Number of microsecond of timeout.
- *
- * @return EC_SUCCESS or error
- */
-static int wait_pmic_pwron(int enable, unsigned int timeout)
-{
- timestamp_t poll_deadline;
-
- /* Check the AP power status */
- if (enable == is_pmic_pwron())
- return EC_SUCCESS;
-
- poll_deadline = get_time();
- poll_deadline.val += timeout;
- while (enable != is_pmic_pwron() &&
- get_time().val < poll_deadline.val) {
- usleep(PMIC_POWER_AP_WAIT);
- }
-
- /* Check the timeout case */
- if (enable != is_pmic_pwron()) {
- if (enable)
- CPRINTS("AP POWER NOT READY!");
- else
- CPRINTS("AP POWER STILL UP!");
-
- return EC_ERROR_UNKNOWN;
- }
- return EC_SUCCESS;
-}
-
-/**
- * Set the state of the system power signals but without any check.
- *
- * The system power signals are the enable pins of SwitchCap.
- * They control the power of the set of PMIC chips and the AP.
- *
- * @param enable 1 to enable or 0 to disable
- */
-static void set_system_power_no_check(int enable)
-{
- board_set_switchcap_power(enable);
-}
-
-/**
- * Set the state of the system power signals.
- *
- * The system power signals are the enable pins of SwitchCap.
- * They control the power of the set of PMIC chips and the AP.
- *
- * @param enable 1 to enable or 0 to disable
- *
- * @return EC_SUCCESS or error
- */
-static int set_system_power(int enable)
-{
- int ret;
-
- CPRINTS("%s(%d)", __func__, enable);
- set_system_power_no_check(enable);
-
- ret = wait_switchcap_power_good(enable);
-
- if (!enable) {
- /* Ensure POWER_GOOD drop to low if it is a forced shutdown */
- ret |= wait_pmic_pwron(0, FORCE_OFF_RESPONSE_TIMEOUT);
- }
- usleep(SYSTEM_POWER_ON_DELAY);
-
- return ret;
-}
-
-/**
- * Set the PMIC/AP power-on state.
- *
- * It triggers the PMIC/AP power-on and power-off sequence.
- *
- * @param enable 1 to power the PMIC/AP on.
- * 0 to power the PMIC/AP off.
- *
- * @return EC_SUCCESS or error
- */
-static int set_pmic_pwron(int enable)
-{
- int ret;
-
- CPRINTS("%s(%d)", __func__, enable);
-
- /* Check the PMIC/AP power state */
- if (enable == is_pmic_pwron())
- return EC_SUCCESS;
-
- if (!gpio_get_level(GPIO_PMIC_KPD_PWR_ODL)) {
- CPRINTS("PMIC_KPD_PWR_ODL not pulled up by PMIC; cancel pwron");
- return EC_ERROR_UNKNOWN;
- }
-
- /*
- * Power-on sequence:
- * 1. Hold down PMIC_KPD_PWR_ODL, which is a power-on trigger
- * 2. PMIC supplies power to POWER_GOOD
- * 3. Release PMIC_KPD_PWR_ODL
- *
- * Power-off sequence:
- * 1. Hold down PMIC_KPD_PWR_ODL and PMIC_RESIN_L, which is a power-off
- * trigger (requiring reprogramming PMIC registers to make
- * PMIC_KPD_PWR_ODL + PMIC_RESIN_L as a shutdown trigger)
- * 2. PMIC stops supplying power to POWER_GOOD (requiring
- * reprogramming PMIC to set the stage-1 and stage-2 reset timers to
- * 0 such that the pull down happens just after the deboucing time
- * of the trigger, like 2ms)
- * 3. Release PMIC_KPD_PWR_ODL and PMIC_RESIN_L
- *
- * If the above PMIC registers not programmed or programmed wrong, it
- * falls back to the next functions, which cuts off the system power.
- */
-
- gpio_set_level(GPIO_PMIC_KPD_PWR_ODL, 0);
- if (!enable)
- gpio_set_level(GPIO_PMIC_RESIN_L, 0);
- ret = wait_pmic_pwron(enable, PMIC_POWER_AP_RESPONSE_TIMEOUT);
- gpio_set_level(GPIO_PMIC_KPD_PWR_ODL, 1);
- if (!enable)
- gpio_set_level(GPIO_PMIC_RESIN_L, 1);
-
- return ret;
-}
-
-enum power_state power_chipset_init(void)
-{
- int init_power_state;
- uint32_t reset_flags = system_get_reset_flags();
-
- /* Enable interrupts */
- if (IS_ENABLED(CONFIG_CHIPSET_SC7180)) {
- gpio_enable_interrupt(GPIO_WARM_RESET_L);
- gpio_enable_interrupt(GPIO_POWER_GOOD);
- }
-
- /*
- * Force the AP shutdown unless we are doing SYSJUMP. Otherwise,
- * the AP could stay in strange state.
- */
- if (!(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("not sysjump; forcing system shutdown");
- set_system_power_no_check(0);
- init_power_state = POWER_G3;
- } else {
- /* In the SYSJUMP case, we check if the AP is on */
- if (power_get_signals() & IN_POWER_GOOD) {
- CPRINTS("SOC ON");
- init_power_state = POWER_S0;
-
- /*
- * Reenable the power signal AP_RST_L interrupt, which
- * should be enabled during S5->S3 but sysjump makes
- * it back to default, disabled.
- */
- power_signal_enable_interrupt(GPIO_AP_RST_L);
-
- /* Disable idle task deep sleep when in S0 */
- disable_sleep(SLEEP_MASK_AP_RUN);
- } else {
- CPRINTS("SOC OFF");
- init_power_state = POWER_G3;
- }
- }
-
- /* Leave power off only if requested by reset flags */
- if (!(reset_flags & EC_RESET_FLAG_AP_OFF) &&
- !(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("auto_power_on set due to reset_flag 0x%x",
- system_get_reset_flags());
- auto_power_on = 1;
- }
-
- if (battery_is_present() == BP_YES) {
- /*
- * (crosbug.com/p/28289): Wait battery stable.
- * Some batteries use clock stretching feature, which requires
- * more time to be stable.
- */
- battery_wait_for_stable();
- }
-
- return init_power_state;
-}
-
-/*****************************************************************************/
-
-/**
- * Power off the AP
- */
-static void power_off(void)
-{
- /* Check PMIC POWER_GOOD */
- if (is_pmic_pwron()) {
- /* Do a graceful way to shutdown PMIC/AP first */
- set_pmic_pwron(0);
- usleep(PMIC_POWER_OFF_DELAY);
-
- /*
- * Disable signal interrupts, as they are floating when
- * switchcap off.
- */
- power_signal_disable_interrupt(GPIO_AP_RST_L);
- }
-
- /* Check the switchcap status */
- if (is_system_powered()) {
- /* Force to switch off all rails */
- set_system_power(0);
- }
-
- lid_opened = 0;
-}
-
-/**
- * Check if the power is enough to boot the AP.
- */
-static int power_is_enough(void)
-{
- timestamp_t poll_deadline;
-
- /* If powered by adapter only, wait a while for PD negoiation. */
- poll_deadline = get_time();
- poll_deadline.val += CAN_BOOT_AP_CHECK_TIMEOUT;
-
- /*
- * Wait for PD negotiation. If a system with drained battery, don't
- * waste the time and exit the loop.
- */
- while (!system_can_boot_ap() && !charge_want_shutdown() &&
- get_time().val < poll_deadline.val) {
- usleep(CAN_BOOT_AP_CHECK_WAIT);
- }
-
- return system_can_boot_ap() && !charge_want_shutdown();
-}
-
-/**
- * Power on the AP
- *
- * @return EC_SUCCESS or error
- */
-static int power_on(void)
-{
- int ret;
-
- ret = set_system_power(1);
- if (ret != EC_SUCCESS)
- return ret;
-
- /* Enable signal interrupts */
- power_signal_enable_interrupt(GPIO_AP_RST_L);
-
- ret = set_pmic_pwron(1);
- if (ret != EC_SUCCESS) {
- CPRINTS("POWER_GOOD not seen in time");
- return ret;
- }
-
- CPRINTS("POWER_GOOD seen");
- return EC_SUCCESS;
-}
-
-/**
- * Check if there has been a power-on event
- *
- * This checks all power-on event signals and returns non-zero if any have been
- * triggered (with debounce taken into account).
- *
- * @return non-zero if there has been a power-on event, 0 if not.
- */
-static uint8_t check_for_power_on_event(void)
-{
- if (power_request == POWER_REQ_ON) {
- power_request = POWER_REQ_NONE;
- return POWER_ON_BY_POWER_REQ_ON;
- } else if (power_request == POWER_REQ_RESET) {
- power_request = POWER_REQ_NONE;
- return POWER_ON_BY_POWER_REQ_RESET;
- }
- /* Clear invalid request */
- power_request = POWER_REQ_NONE;
-
- /* power on requested at EC startup for recovery */
- if (auto_power_on) {
- auto_power_on = 0;
- return POWER_ON_BY_AUTO_POWER_ON;
- }
-
- /* Check lid open */
- if (lid_opened) {
- lid_opened = 0;
- return POWER_ON_BY_LID_OPEN;
- }
-
- /* check for power button press */
- if (power_button_is_pressed())
- return POWER_ON_BY_POWER_BUTTON_PRESSED;
-
- return POWER_OFF_CANCEL;
-}
-
-/**
- * Check for some event triggering the shutdown.
- *
- * It can be either a long power button press or a shutdown triggered from the
- * AP and detected by reading POWER_GOOD.
- *
- * @return non-zero if a shutdown should happen, 0 if not
- */
-static uint8_t check_for_power_off_event(void)
-{
- timestamp_t now;
- int pressed = 0;
-
- if (power_request == POWER_REQ_OFF) {
- power_request = POWER_REQ_NONE;
- return POWER_OFF_BY_POWER_REQ_OFF;
- } else if (power_request == POWER_REQ_RESET) {
- /*
- * The power_request flag will be cleared later
- * in check_for_power_on_event() in S5.
- */
- return POWER_OFF_BY_POWER_REQ_RESET;
- }
- /* Clear invalid request */
- power_request = POWER_REQ_NONE;
-
- /*
- * Check for power button press.
- */
- if (power_button_is_pressed())
- pressed = POWER_OFF_BY_POWER_BUTTON_PRESSED;
-
- now = get_time();
- if (pressed) {
- if (!power_button_was_pressed) {
- power_off_deadline.val = now.val + DELAY_FORCE_SHUTDOWN;
- CPRINTS("power waiting for long press %u",
- power_off_deadline.le.lo);
- /* Ensure we will wake up to check the power key */
- timer_arm(power_off_deadline, TASK_ID_CHIPSET);
- } else if (timestamp_expired(power_off_deadline, &now)) {
- power_off_deadline.val = 0;
- CPRINTS("power off after long press now=%u, %u",
- now.le.lo, power_off_deadline.le.lo);
- return POWER_OFF_BY_LONG_PRESS;
- }
- } else if (power_button_was_pressed) {
- CPRINTS("power off cancel");
- timer_cancel(TASK_ID_CHIPSET);
- }
-
- power_button_was_pressed = pressed;
-
- /* POWER_GOOD released by AP : shutdown immediately */
- if (!power_has_signals(IN_POWER_GOOD)) {
- CPRINTS("POWER_GOOD is lost");
- return POWER_OFF_BY_POWER_GOOD_LOST;
- }
-
- return POWER_OFF_CANCEL;
-}
-
-/**
- * Cancel the power button timer.
- *
- * The timer was previously created in the check_for_power_off_event(),
- * which waited for the power button long press. Should cancel the timer
- * during the power state transition; otherwise, EC will crash.
- */
-static inline void cancel_power_button_timer(void)
-{
- if (power_button_was_pressed)
- timer_cancel(TASK_ID_CHIPSET);
-}
-
-/*****************************************************************************/
-/* Chipset interface */
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /* Issue a request to initiate a power-off sequence */
- power_request = POWER_REQ_OFF;
- task_wake(TASK_ID_CHIPSET);
-}
-
-void chipset_reset(enum chipset_reset_reason reason)
-{
- int rv;
-
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * Warm reset sequence:
- * 1. Issue a low pulse to PMIC_RESIN_L, which triggers PMIC
- * to do a warm reset (requiring reprogramming PMIC registers
- * to make PMIC_RESIN_L as a warm reset trigger).
- * 2. PMIC then issues a low pulse to AP_RST_L to reset AP.
- * EC monitors the signal to see any low pulse.
- * 2.1. If a low pulse found, done.
- * 2.2. If a low pulse not found (the above PMIC registers
- * not programmed or programmed wrong), issue a request
- * to initiate a cold reset power sequence.
- */
-
- gpio_set_level(GPIO_PMIC_RESIN_L, 0);
- usleep(PMIC_RESIN_PULSE_LENGTH);
- gpio_set_level(GPIO_PMIC_RESIN_L, 1);
-
- rv = power_wait_signals_timeout(IN_AP_RST_ASSERTED,
- PMIC_POWER_AP_RESPONSE_TIMEOUT);
- /* Exception case: PMIC not work as expected, request a cold reset */
- if (rv != EC_SUCCESS) {
- CPRINTS("AP refuses to warm reset. Cold resetting.");
- request_cold_reset();
- }
-}
-
-/*
- * Flag to fake the suspend signal to 1 or 0, or -1 means not fake it.
- *
- * TODO(waihong): Remove this flag and debug command when the AP_SUSPEND
- * signal is working.
- */
-static int fake_suspend = -1;
-
-static int command_fake_suspend(int argc, char **argv)
-{
- int v;
-
- if (argc < 2) {
- ccprintf("fake_suspend: %s\n",
- fake_suspend == -1 ? "reset"
- : (fake_suspend ? "on" : "off"));
- return EC_SUCCESS;
- }
-
- if (!strcasecmp(argv[1], "reset"))
- fake_suspend = -1;
- else if (parse_bool(argv[1], &v))
- fake_suspend = v;
- else
- return EC_ERROR_PARAM1;
-
- task_wake(TASK_ID_CHIPSET);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(fakesuspend, command_fake_suspend,
- "on/off/reset",
- "Fake the AP_SUSPEND signal");
-
-/* Get system sleep state through GPIOs */
-static inline int chipset_get_sleep_signal(void)
-{
- if (fake_suspend == -1)
- return (power_get_signals() & IN_SUSPEND) == IN_SUSPEND;
- else
- return fake_suspend;
-}
-
-static void suspend_hang_detected(void)
-{
- CPRINTS("Warning: Detected sleep hang! Waking host up!");
- host_set_single_event(EC_HOST_EVENT_HANG_DETECT);
-}
-
-static void power_reset_host_sleep_state(void)
-{
- power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET);
- sleep_reset_tracking();
- power_chipset_handle_host_sleep_event(HOST_SLEEP_EVENT_DEFAULT_RESET,
- NULL);
-}
-
-static void handle_chipset_reset(void)
-{
- if (chipset_in_state(CHIPSET_STATE_SUSPEND)) {
- CPRINTS("Chipset reset: exit s3");
- power_reset_host_sleep_state();
- task_wake(TASK_ID_CHIPSET);
- }
-}
-DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST);
-
-__override void power_chipset_handle_host_sleep_event(
- enum host_sleep_event state,
- struct host_sleep_event_context *ctx)
-{
- CPRINTS("Handle sleep: %d", state);
-
- if (state == HOST_SLEEP_EVENT_S3_SUSPEND) {
- /*
- * Indicate to power state machine that a new host event for
- * S3 suspend has been received and so chipset suspend
- * notification needs to be sent to listeners.
- */
- sleep_set_notify(SLEEP_NOTIFY_SUSPEND);
- sleep_start_suspend(ctx, suspend_hang_detected);
- power_signal_enable_interrupt(GPIO_AP_SUSPEND);
-
- } else if (state == HOST_SLEEP_EVENT_S3_RESUME) {
- /*
- * Wake up chipset task and indicate to power state machine that
- * listeners need to be notified of chipset resume.
- */
- sleep_set_notify(SLEEP_NOTIFY_RESUME);
- task_wake(TASK_ID_CHIPSET);
- power_signal_disable_interrupt(GPIO_AP_SUSPEND);
- sleep_complete_resume(ctx);
-
- } else if (state == HOST_SLEEP_EVENT_DEFAULT_RESET) {
- power_signal_disable_interrupt(GPIO_AP_SUSPEND);
- }
-}
-
-/**
- * Power handler for steady states
- *
- * @param state Current power state
- * @return Updated power state
- */
-enum power_state power_handle_state(enum power_state state)
-{
- static uint8_t boot_from_off, shutdown_from_on;
-
- switch (state) {
- case POWER_G3:
- boot_from_off = check_for_power_on_event();
- if (boot_from_off)
- return POWER_G3S5;
- break;
-
- case POWER_G3S5:
- return POWER_S5;
-
- case POWER_S5:
- if (!boot_from_off)
- boot_from_off = check_for_power_on_event();
-
- if (boot_from_off) {
- CPRINTS("power on %d", boot_from_off);
- return POWER_S5S3;
- }
- break;
-
- case POWER_S5S3:
- /*
- * Wait for power button release before actually boot AP.
- * It may be a long-hold power button with volume buttons
- * to trigger the recovery button. We don't want AP up
- * during the long-hold.
- */
- power_button_wait_for_release(-1);
-
- /* If no enough power, return back to S5. */
- if (!power_is_enough()) {
- boot_from_off = 0;
- return POWER_S5;
- }
-
- /* Initialize components to ready state before AP is up. */
- hook_notify(HOOK_CHIPSET_PRE_INIT);
-
- if (power_on() != EC_SUCCESS) {
- power_off();
- boot_from_off = 0;
- return POWER_S5;
- }
- CPRINTS("AP running ...");
-
- /* Call hooks now that AP is running */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
- /*
- * Clearing the sleep failure detection tracking on the path
- * to S0 to handle any reset conditions.
- */
- power_reset_host_sleep_state();
- return POWER_S3;
-
- case POWER_S3:
- if (!shutdown_from_on)
- shutdown_from_on = check_for_power_off_event();
-
- if (shutdown_from_on) {
- CPRINTS("power off %d", shutdown_from_on);
- return POWER_S3S5;
- }
-
- /*
- * AP has woken up and it deasserts the suspend signal;
- * go to S0.
- *
- * In S0, it will wait for a host event and then trigger the
- * RESUME hook.
- */
- if (!chipset_get_sleep_signal())
- return POWER_S3S0;
- break;
-
- case POWER_S3S0:
- cancel_power_button_timer();
-
-#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK
- /*
- * Notify the RESUME_INIT hooks, i.e. enabling SPI driver
- * to receive host commands/events.
- *
- * If boot from an off state, notify the RESUME hooks too;
- * otherwise (resume from S3), the normal RESUME hooks will
- * be notified later, after receive a host resume event.
- */
- hook_notify(HOOK_CHIPSET_RESUME_INIT);
- if (boot_from_off)
- hook_notify(HOOK_CHIPSET_RESUME);
-#else
- hook_notify(HOOK_CHIPSET_RESUME);
-#endif
- sleep_resume_transition();
-
- boot_from_off = 0;
- disable_sleep(SLEEP_MASK_AP_RUN);
- return POWER_S0;
-
- case POWER_S0:
- shutdown_from_on = check_for_power_off_event();
- if (shutdown_from_on) {
- return POWER_S0S3;
- } else if (power_get_host_sleep_state()
- == HOST_SLEEP_EVENT_S3_SUSPEND &&
- chipset_get_sleep_signal()) {
- return POWER_S0S3;
- }
- /* When receive the host event, trigger the RESUME hook. */
- sleep_notify_transition(SLEEP_NOTIFY_RESUME,
- HOOK_CHIPSET_RESUME);
- break;
-
- case POWER_S0S3:
- cancel_power_button_timer();
-
- /*
- * Call SUSPEND hooks only if we haven't notified listeners of
- * S3 suspend.
- */
- sleep_notify_transition(SLEEP_NOTIFY_SUSPEND,
- HOOK_CHIPSET_SUSPEND);
-#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK
- /*
- * Pair with the HOOK_CHIPSET_RESUME_INIT, i.e. disabling SPI
- * driver, by notifying the SUSPEND_COMPLETE hooks.
- *
- * If shutdown from an on state, notify the SUSPEND hooks too;
- * otherwise (suspend from S0), the normal SUSPEND hooks have
- * been notified in the above sleep_notify_transition() call.
- */
- if (shutdown_from_on)
- hook_notify(HOOK_CHIPSET_SUSPEND);
- hook_notify(HOOK_CHIPSET_SUSPEND_COMPLETE);
-#else
- hook_notify(HOOK_CHIPSET_SUSPEND);
-#endif
- sleep_suspend_transition();
-
- enable_sleep(SLEEP_MASK_AP_RUN);
- return POWER_S3;
-
- case POWER_S3S5:
- cancel_power_button_timer();
-
- /* Call hooks before we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
-
- power_off();
- CPRINTS("power shutdown complete");
-
- /* Call hooks after we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-
- shutdown_from_on = 0;
-
- /*
- * Wait forever for the release of the power button; otherwise,
- * this power button press will then trigger a power-on in S5.
- */
- power_button_wait_for_release(-1);
- power_button_was_pressed = 0;
- return POWER_S5;
-
- case POWER_S5G3:
- return POWER_G3;
- }
-
- return state;
-}
-
-/*****************************************************************************/
-/* Console debug command */
-
-static const char *power_req_name[POWER_REQ_COUNT] = {
- "none",
- "off",
- "on",
-};
-
-/* Power states that we can report */
-enum power_state_t {
- PSTATE_UNKNOWN,
- PSTATE_OFF,
- PSTATE_ON,
- PSTATE_COUNT,
-};
-
-static const char * const state_name[] = {
- "unknown",
- "off",
- "on",
-};
-
-static int command_power(int argc, char **argv)
-{
- int v;
-
- if (argc < 2) {
- enum power_state_t state;
-
- state = PSTATE_UNKNOWN;
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- state = PSTATE_OFF;
- if (chipset_in_state(CHIPSET_STATE_ON))
- state = PSTATE_ON;
- ccprintf("%s\n", state_name[state]);
-
- return EC_SUCCESS;
- }
-
- if (!parse_bool(argv[1], &v))
- return EC_ERROR_PARAM1;
-
- power_request = v ? POWER_REQ_ON : POWER_REQ_OFF;
- ccprintf("Requesting power %s\n", power_req_name[power_request]);
- task_wake(TASK_ID_CHIPSET);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(power, command_power,
- "on/off",
- "Turn AP power on/off");
diff --git a/power/rk3288.c b/power/rk3288.c
deleted file mode 100644
index c647ab97b2..0000000000
--- a/power/rk3288.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/* Copyright 2013 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.
- */
-
-/*
- * Rockchip SoC power sequencing module for Chrome EC
- *
- * This implements the following features:
- *
- * - Cold reset powers on the AP
- *
- * When powered off:
- * - Press pwron turns on the AP
- * - Hold pwron turns on the AP, and then 9s later turns it off and leaves
- * it off until pwron is released and pressed again
- *
- * When powered on:
- * - Holding pwron for 10.2s powers off the AP
- * - Pressing and releasing pwron within that 10.2s is ignored
- * - If POWER_GOOD is dropped by the pmic, then we cut off the pmic source
- * - If SUSPEND_L goes low, enter suspend mode.
- *
- */
-
-#include "battery.h"
-#include "charge_state.h"
-#include "chipset.h" /* This module implements chipset functions too */
-#include "clock.h"
-#include "common.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "lid_switch.h"
-#include "keyboard_scan.h"
-#include "power.h"
-#include "power_button.h"
-#include "power_led.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-/* masks for power signals */
-#define IN_POWER_GOOD POWER_SIGNAL_MASK(RK_POWER_GOOD)
-#define IN_SUSPEND POWER_SIGNAL_MASK(RK_SUSPEND_ASSERTED)
-
-/* Long power key press to force shutdown */
-#define DELAY_FORCE_SHUTDOWN (8 * SECOND)
-
-/*
- * If the power key is pressed to turn on, then held for this long, we
- * power off.
- *
- * Normal case: User releases power button and chipset_task() goes
- * into the inner loop, waiting for next event to occur (power button
- * press or power good == 0).
- */
-#define DELAY_SHUTDOWN_ON_POWER_HOLD (8 * SECOND)
-
-/*
- * The hold time for pulling down the PMIC_WARM_RESET_L pin so that
- * the AP can entery the recovery mode (flash SPI flash from USB).
- */
-#define PMIC_WARM_RESET_L_HOLD_TIME (4 * MSEC)
-
-/*
- * Startup time for the PMIC source regulator.
- */
-#define PMIC_SOURCE_STARTUP_TIME (50 * MSEC)
-
-/*
- * Time before PMIC can be reset.
- */
-#define PMIC_STARTUP_MS 300
-
-/* TODO(crosbug.com/p/25047): move to HOOK_POWER_BUTTON_CHANGE */
-/* 1 if the power button was pressed last time we checked */
-static char power_button_was_pressed;
-
-/* 1 if lid-open event has been detected */
-static char lid_opened;
-
-/* time where we will power off, if power button still held down */
-static timestamp_t power_off_deadline;
-
-/* force AP power on (used for recovery keypress) */
-static int auto_power_on;
-
-enum power_request_t {
- POWER_REQ_NONE,
- POWER_REQ_OFF,
- POWER_REQ_ON,
-
- POWER_REQ_COUNT,
-};
-
-static enum power_request_t power_request;
-
-
-/* Forward declaration */
-static void chipset_turn_off_power_rails(void);
-
-
-/**
- * Set the PMIC WARM RESET signal.
- *
- * @param asserted Resetting (=0) or idle (=1)
- */
-static void set_pmic_warm_reset(int asserted)
-{
- /* Signal is active-low */
- gpio_set_level(GPIO_PMIC_WARM_RESET_L, asserted ? 0 : 1);
-}
-
-
-/**
- * Set the PMIC PWRON signal.
- *
- * @param asserted Assert (=1) or deassert (=0) the signal.
- */
-static void set_pmic_pwron(int asserted)
-{
- /* Signal is active-high */
- gpio_set_level(GPIO_PMIC_PWRON, asserted ? 1 : 0);
-}
-
-/**
- * Set the PMIC source to force shutdown the AP.
- *
- * @param asserted Assert (=1) or deassert (=0) the signal.
- */
-static void set_pmic_source(int asserted)
-{
- /* Signal is active-high */
- gpio_set_level(GPIO_PMIC_SOURCE_PWREN, asserted ? 1 : 0);
-}
-
-/**
- * Check for some event triggering the shutdown.
- *
- * It can be either a long power button press or a shutdown triggered from the
- * AP and detected by reading POWER_GOOD.
- *
- * @return non-zero if a shutdown should happen, 0 if not
- */
-static int check_for_power_off_event(void)
-{
- timestamp_t now;
- int pressed = 0;
- int ret = 0;
-
- /*
- * Check for power button press.
- */
- if (power_button_is_pressed()) {
- pressed = 1;
- } else if (power_request == POWER_REQ_OFF) {
- power_request = POWER_REQ_NONE;
- return 4; /* return non-zero for shudown down */
- }
-
- now = get_time();
- if (pressed) {
- if (!power_button_was_pressed) {
- power_off_deadline.val = now.val + DELAY_FORCE_SHUTDOWN;
- CPRINTS("power waiting for long press %u",
- power_off_deadline.le.lo);
- /* Ensure we will wake up to check the power key */
- timer_arm(power_off_deadline, TASK_ID_CHIPSET);
- } else if (timestamp_expired(power_off_deadline, &now)) {
- power_off_deadline.val = 0;
- CPRINTS("power off after long press now=%u, %u",
- now.le.lo, power_off_deadline.le.lo);
- return 2;
- }
- } else if (power_button_was_pressed) {
- CPRINTS("power off cancel");
- timer_cancel(TASK_ID_CHIPSET);
- }
-
- /* POWER_GOOD released by AP : shutdown immediately */
- if (!power_has_signals(IN_POWER_GOOD)) {
- if (power_button_was_pressed)
- timer_cancel(TASK_ID_CHIPSET);
- ret = 3;
- }
-
- power_button_was_pressed = pressed;
-
- return ret;
-}
-
-static void rockchip_lid_event(void)
-{
- /* Power task only cares about lid-open events */
- if (!lid_is_open())
- return;
-
- lid_opened = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, rockchip_lid_event, HOOK_PRIO_DEFAULT);
-
-enum power_state power_chipset_init(void)
-{
- int init_power_state;
- uint32_t reset_flags = system_get_reset_flags();
-
- /*
- * Force the AP shutdown unless we are doing SYSJUMP. Otherwise,
- * the AP could stay in strange state.
- */
- if (!(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("not sysjump; forcing AP shutdown");
- chipset_turn_off_power_rails();
-
- /*
- * The warm reset triggers AP into the RK recovery mode (
- * flash SPI from USB).
- */
- chipset_reset(CHIPSET_RESET_INIT);
-
- init_power_state = POWER_G3;
- } else {
- /* In the SYSJUMP case, we check if the AP is on */
- if (power_get_signals() & IN_POWER_GOOD)
- init_power_state = POWER_S0;
- else
- init_power_state = POWER_G3;
- }
-
- /* Leave power off only if requested by reset flags */
- if (!(reset_flags & EC_RESET_FLAG_AP_OFF) &&
- !(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("auto_power_on set due to reset_flag 0x%x",
- system_get_reset_flags());
- auto_power_on = 1;
- }
-
- /*
- * Some batteries use clock stretching feature, which requires
- * more time to be stable. See http://crosbug.com/p/28289
- */
- battery_wait_for_stable();
-
- return init_power_state;
-}
-
-/*****************************************************************************/
-/* Chipset interface */
-
-static void chipset_turn_off_power_rails(void)
-{
- /* Release the power on pin, if it was asserted */
- set_pmic_pwron(0);
- /* Close the pmic power source immediately */
- set_pmic_source(0);
-
- /* Keep AP and PMIC in reset the whole time */
- set_pmic_warm_reset(1);
-}
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
- chipset_turn_off_power_rails();
-
- /* clean-up internal variable */
- power_request = POWER_REQ_NONE;
-}
-
-/*****************************************************************************/
-
-/**
- * Check if there has been a power-on event
- *
- * This checks all power-on event signals and returns non-zero if any have been
- * triggered (with debounce taken into account).
- *
- * @return non-zero if there has been a power-on event, 0 if not.
- */
-static int check_for_power_on_event(void)
-{
- int ap_off_flag;
-
- ap_off_flag = system_get_reset_flags() & EC_RESET_FLAG_AP_OFF;
- system_clear_reset_flags(EC_RESET_FLAG_AP_OFF);
- /* check if system is already ON */
- if (power_get_signals() & IN_POWER_GOOD) {
- if (ap_off_flag) {
- CPRINTS(
- "system is on, but "
- "EC_RESET_FLAG_AP_OFF is on");
- return 0;
- } else {
- CPRINTS(
- "system is on, thus clear "
- "auto_power_on");
- /* no need to arrange another power on */
- auto_power_on = 0;
- return 1;
- }
- }
-
- /* power on requested at EC startup for recovery */
- if (auto_power_on) {
- auto_power_on = 0;
- return 2;
- }
-
- /* Check lid open */
- if (lid_opened) {
- lid_opened = 0;
- return 3;
- }
-
- /* check for power button press */
- if (power_button_is_pressed())
- return 4;
-
- if (power_request == POWER_REQ_ON) {
- power_request = POWER_REQ_NONE;
- return 5;
- }
-
- return 0;
-}
-
-/**
- * Power on the AP
- */
-static void power_on(void)
-{
- int i;
-
- set_pmic_source(1);
- usleep(PMIC_SOURCE_STARTUP_TIME);
-
- set_pmic_pwron(1);
- /*
- * BUG Workaround(crosbug.com/p/31635): usleep hangs in task when using
- * big delays.
- */
- for (i = 0; i < PMIC_STARTUP_MS; i++)
- usleep(1 * MSEC);
-
- set_pmic_warm_reset(0);
-}
-
-/**
- * Power off the AP
- */
-static void power_off(void)
-{
- unsigned int power_off_timeout = 100; /* ms */
-
- /* Call hooks before we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
- /* switch off all rails */
- chipset_turn_off_power_rails();
- /* Change SUSPEND_L and EC_INT pin to high-Z to reduce power draw. */
- gpio_set_flags(GPIO_SUSPEND_L, GPIO_INPUT);
- gpio_set_flags(GPIO_EC_INT_L, GPIO_INPUT);
-
- /* Wait till we actually turn off to not mess up the state machine. */
- while (power_get_signals() & IN_POWER_GOOD) {
- msleep(1);
- power_off_timeout--;
- ASSERT(power_off_timeout);
- }
-
- lid_opened = 0;
- enable_sleep(SLEEP_MASK_AP_RUN);
- powerled_set_state(POWERLED_STATE_OFF);
-
- CPRINTS("power shutdown complete");
-
- /* Call hooks after we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-}
-
-void chipset_reset(enum chipset_reset_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- CPRINTS("assert GPIO_PMIC_WARM_RESET_L for %d ms",
- PMIC_WARM_RESET_L_HOLD_TIME / MSEC);
- set_pmic_warm_reset(1);
- usleep(PMIC_WARM_RESET_L_HOLD_TIME);
- set_pmic_warm_reset(0);
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- int value;
- static int boot_from_g3;
-
- switch (state) {
- case POWER_G3:
- boot_from_g3 = check_for_power_on_event();
- if (boot_from_g3)
- return POWER_G3S5;
- break;
-
- case POWER_G3S5:
- return POWER_S5;
-
- case POWER_S5:
- if (boot_from_g3) {
- value = boot_from_g3;
- boot_from_g3 = 0;
- } else {
- value = check_for_power_on_event();
- }
-
- if (value) {
- CPRINTS("power on %d", value);
- return POWER_S5S3;
- }
- return state;
-
- case POWER_S5S3:
- hook_notify(HOOK_CHIPSET_PRE_INIT);
-
- power_on();
-
- disable_sleep(SLEEP_MASK_AP_RUN);
- powerled_set_state(POWERLED_STATE_ON);
-
- if (power_wait_signals(IN_POWER_GOOD) == EC_SUCCESS) {
- CPRINTS("POWER_GOOD seen");
- if (power_button_wait_for_release(
- DELAY_SHUTDOWN_ON_POWER_HOLD) ==
- EC_SUCCESS) {
- power_button_was_pressed = 0;
- set_pmic_pwron(0);
-
- /* setup misc gpio for S3/S0 functionality */
- gpio_set_flags(GPIO_SUSPEND_L, GPIO_INPUT
- | GPIO_INT_BOTH | GPIO_PULL_DOWN);
- gpio_set_flags(GPIO_EC_INT_L, GPIO_OUTPUT
- | GPIO_OUT_HIGH);
-
- /* Call hooks now that AP is running */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
- return POWER_S3;
- } else {
- CPRINTS("long-press button, shutdown");
- power_off();
- /*
- * Since the AP may be up already, return S0S3
- * state to go through the suspend hook.
- */
- return POWER_S0S3;
- }
- } else {
- CPRINTS("POWER_GOOD not seen in time");
- }
-
- chipset_turn_off_power_rails();
- return POWER_S5;
-
- case POWER_S3:
- if (!(power_get_signals() & IN_POWER_GOOD))
- return POWER_S3S5;
- else if (!(power_get_signals() & IN_SUSPEND))
- return POWER_S3S0;
- return state;
-
- case POWER_S3S0:
- powerled_set_state(POWERLED_STATE_ON);
- hook_notify(HOOK_CHIPSET_RESUME);
- return POWER_S0;
-
- case POWER_S0:
- value = check_for_power_off_event();
- if (value) {
- CPRINTS("power off %d", value);
- power_off();
- return POWER_S0S3;
- } else if (power_get_signals() & IN_SUSPEND)
- return POWER_S0S3;
- return state;
-
- case POWER_S0S3:
- if (lid_is_open())
- powerled_set_state(POWERLED_STATE_SUSPEND);
- else
- powerled_set_state(POWERLED_STATE_OFF);
- /* Call hooks here since we don't know it prior to AP suspend */
- hook_notify(HOOK_CHIPSET_SUSPEND);
- return POWER_S3;
-
- case POWER_S3S5:
- power_button_wait_for_release(-1);
- power_button_was_pressed = 0;
- return POWER_S5;
-
- case POWER_S5G3:
- return POWER_G3;
- }
-
- return state;
-}
-
-static void powerbtn_rockchip_changed(void)
-{
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, powerbtn_rockchip_changed,
- HOOK_PRIO_DEFAULT);
-
-/*****************************************************************************/
-/* Console debug command */
-
-static const char *power_req_name[POWER_REQ_COUNT] = {
- "none",
- "off",
- "on",
-};
-
-/* Power states that we can report */
-enum power_state_t {
- PSTATE_UNKNOWN,
- PSTATE_OFF,
- PSTATE_SUSPEND,
- PSTATE_ON,
-
- PSTATE_COUNT,
-};
-
-static const char * const state_name[] = {
- "unknown",
- "off",
- "suspend",
- "on",
-};
-
-static int command_power(int argc, char **argv)
-{
- int v;
-
- if (argc < 2) {
- enum power_state_t state;
-
- state = PSTATE_UNKNOWN;
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- state = PSTATE_OFF;
- if (chipset_in_state(CHIPSET_STATE_SUSPEND))
- state = PSTATE_SUSPEND;
- if (chipset_in_state(CHIPSET_STATE_ON))
- state = PSTATE_ON;
- ccprintf("%s\n", state_name[state]);
-
- return EC_SUCCESS;
- }
-
- if (!parse_bool(argv[1], &v))
- return EC_ERROR_PARAM1;
-
- power_request = v ? POWER_REQ_ON : POWER_REQ_OFF;
- ccprintf("Requesting power %s\n", power_req_name[power_request]);
- task_wake(TASK_ID_CHIPSET);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(power, command_power,
- "on/off",
- "Turn AP power on/off");
diff --git a/power/rk3399.c b/power/rk3399.c
deleted file mode 100644
index 9db25f0b28..0000000000
--- a/power/rk3399.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/* Copyright 2013 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.
- */
-
-/* rk3399 chipset power control module for Chrome EC */
-
-/*
- * The description of each CONFIG_CHIPSET_POWER_SEQ_VERSION:
- *
- * Version 0: Initial/default revision for clamshell / convertible.
- * Version 1: Simplified power tree for tablet / detachable.
- */
-
-#include "charge_state.h"
-#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 "task.h"
-#include "timer.h"
-#include "usb_charge.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-/* Input state flags */
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
- #define IN_PGOOD_PP1250_S3 POWER_SIGNAL_MASK(PP1250_S3_PWR_GOOD)
- #define IN_PGOOD_PP900_S0 POWER_SIGNAL_MASK(PP900_S0_PWR_GOOD)
-#else
- #define IN_PGOOD_PP5000 POWER_SIGNAL_MASK(PP5000_PWR_GOOD)
- #define IN_PGOOD_SYS POWER_SIGNAL_MASK(SYS_PWR_GOOD)
-#endif
-
-#define IN_PGOOD_AP POWER_SIGNAL_MASK(AP_PWR_GOOD)
-#define IN_SUSPEND_DEASSERTED POWER_SIGNAL_MASK(SUSPEND_DEASSERTED)
-
-/* Rails requires for S3 and S0 */
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
- #define IN_PGOOD_S3 (IN_PGOOD_PP1250_S3)
- #define IN_PGOOD_S0 (IN_PGOOD_S3 | IN_PGOOD_PP900_S0 | IN_PGOOD_AP)
- /* This board can optionally wake-on-USB in S3 */
- #define S3_USB_WAKE
- /* This board has non-INT power signal pins */
- #define POWER_SIGNAL_POLLING
- /* This board supports CR50 deep sleep mode */
- #define CR50_DEEP_SLEEP
- /*
- * If AP_PWR_GOOD assertion does not trigger an interrupt, poll the
- * signal every 5ms, up to 200 times (~ 1 second timeout).
- */
- #define PGOOD_S0_POLL_TIMEOUT (5 * MSEC)
- #define PGOOD_S0_POLL_TRIES 200
-#else
- #define IN_PGOOD_S3 (IN_PGOOD_PP5000)
- #define IN_PGOOD_S0 (IN_PGOOD_S3 | IN_PGOOD_AP | IN_PGOOD_SYS)
-#endif
-
-/* All inputs in the right state for S0 */
-#define IN_ALL_S0 (IN_PGOOD_S0 | IN_SUSPEND_DEASSERTED)
-
-/* Long power key press to force shutdown in S0 */
-#define FORCED_SHUTDOWN_DELAY (8 * SECOND)
-
-#define CHARGER_INITIALIZED_DELAY_MS 100
-#define CHARGER_INITIALIZED_TRIES 40
-
-/* Data structure for a GPIO operation for power sequencing */
-struct power_seq_op {
- /* enum gpio_signal in 8 bits */
- uint8_t signal;
- uint8_t level;
- /* Number of milliseconds to delay after setting signal to level */
- uint8_t delay;
-};
-BUILD_ASSERT(GPIO_COUNT < 256);
-
-/*
- * This is the power sequence for POWER_S5S3.
- * The entries in the table are handled sequentially from the top
- * to the bottom.
- */
-
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
-static const struct power_seq_op s5s3_power_seq[] = {
- { GPIO_PP900_S3_EN, 1, 2 },
- { GPIO_PP3300_S3_EN, 1, 2 },
- { GPIO_PP1800_S3_EN, 1, 2 },
- { GPIO_PP1250_S3_EN, 1, 2 },
-};
-#else
-static const struct power_seq_op s5s3_power_seq[] = {
- { GPIO_PPVAR_LOGIC_EN, 1, 0 },
- { GPIO_PP900_AP_EN, 1, 0 },
- { GPIO_PP900_PCIE_EN, 1, 2 },
- { GPIO_PP900_PMU_EN, 1, 0 },
- { GPIO_PP900_PLL_EN, 1, 0 },
- { GPIO_PP900_USB_EN, 1, 2 },
- { GPIO_SYS_RST_L, 0, 0 },
- { GPIO_PP1800_PMU_EN_L, 0, 2 },
- { GPIO_LPDDR_PWR_EN, 1, 2 },
- { GPIO_PP1800_USB_EN_L, 0, 2 },
- { GPIO_PP3300_USB_EN_L, 0, 0 },
- { GPIO_PP5000_EN, 1, 0 },
- { GPIO_PP3300_TRACKPAD_EN_L, 0, 1 },
- { GPIO_PP1800_LID_EN_L, 0, 0 },
- { GPIO_PP1800_SIXAXIS_EN_L, 0, 2 },
- { GPIO_PP1800_SENSOR_EN_L, 0, 0 },
-};
-#endif
-
-/* The power sequence for POWER_S3S0 */
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
-static const struct power_seq_op s3s0_power_seq[] = {
- { GPIO_AP_CORE_EN, 1, 2 },
- { GPIO_PP1800_S0_EN, 1, 0 },
-};
-#else
-static const struct power_seq_op s3s0_power_seq[] = {
- { GPIO_PPVAR_CLOGIC_EN, 1, 2 },
- { GPIO_PP900_DDRPLL_EN, 1, 2 },
- { GPIO_PP1800_AP_AVDD_EN_L, 0, 2 },
- { GPIO_AP_CORE_EN, 1, 2 },
- { GPIO_PP1800_S0_EN_L, 0, 2 },
- { GPIO_PP3300_S0_EN_L, 0, 0 },
-};
-#endif
-
-#ifdef S3_USB_WAKE
-/* Sigs that may already be on in S3, if we need to wake-on-USB */
-static const struct power_seq_op s3s0_usb_wake_power_seq[] = {
- { GPIO_PP900_S0_EN, 1, 2 },
- { GPIO_PP1800_USB_EN, 1, 2 },
- { GPIO_PP3300_S0_EN, 1, 2 },
-};
-#endif
-
-/* The power sequence for POWER_S0S3 */
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
-static const struct power_seq_op s0s3_power_seq[] = {
- { GPIO_AP_CORE_EN, 0, 20 },
-};
-#else
-static const struct power_seq_op s0s3_power_seq[] = {
- { GPIO_PP3300_S0_EN_L, 1, 20 },
- { GPIO_PP1800_S0_EN_L, 1, 1 },
- { GPIO_AP_CORE_EN, 0, 20 },
- { GPIO_PP1800_AP_AVDD_EN_L, 1, 1 },
- { GPIO_PP900_DDRPLL_EN, 0, 1 },
- { GPIO_PPVAR_CLOGIC_EN, 0, 0 },
-};
-#endif
-
-#ifdef S3_USB_WAKE
-/* Sigs that need to be left on in S3, if we need to wake-on-USB */
-static const struct power_seq_op s0s3_usb_wake_power_seq[] = {
- { GPIO_PP3300_S0_EN, 0, 20 },
- { GPIO_PP1800_S0_EN, 0, 1 },
- { GPIO_PP1800_USB_EN, 0, 1 },
- { GPIO_PP900_S0_EN, 0, 0 },
-};
-#endif
-
-/* The power sequence for POWER_S3S5 */
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
-static const struct power_seq_op s3s5_power_seq[] = {
- { GPIO_SYS_RST_L, 0, 0 },
- { GPIO_PP1250_S3_EN, 0, 2 },
- { GPIO_PP1800_S3_EN, 0, 2 },
- { GPIO_PP3300_S3_EN, 0, 2 },
- { GPIO_PP900_S3_EN, 0, 0 },
-};
-#else
-static const struct power_seq_op s3s5_power_seq[] = {
- { GPIO_PP1800_SENSOR_EN_L, 1, 0},
- { GPIO_PP1800_SIXAXIS_EN_L, 1, 0},
- { GPIO_PP1800_LID_EN_L, 1, 0 },
- { GPIO_PP3300_TRACKPAD_EN_L, 1, 0 },
- { GPIO_PP5000_EN, 0, 0 },
- { GPIO_PP3300_USB_EN_L, 1, 20 },
- { GPIO_PP1800_USB_EN_L, 1, 10 },
- { GPIO_LPDDR_PWR_EN, 0, 20 },
- { GPIO_PP1800_PMU_EN_L, 1, 2 },
- { GPIO_PP900_PLL_EN, 0, 0 },
- { GPIO_PP900_PMU_EN, 0, 0 },
- { GPIO_PP900_USB_EN, 0, 6 },
- { GPIO_PP900_PCIE_EN, 0, 0 },
- { GPIO_PP900_AP_EN, 0, 0 },
- { GPIO_PPVAR_LOGIC_EN, 0, 0 },
-};
-#endif
-
-static int forcing_shutdown;
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * Force power off. This condition will reset once the state machine
- * transitions to G3.
- */
- forcing_shutdown = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-
-#define SYS_RST_HOLD_US (1 * MSEC)
-void chipset_reset(enum chipset_reset_reason reason)
-{
-#ifdef CONFIG_CMD_RTC
- /* Print out the RTC to help correlate resets in logs. */
- print_system_rtc(CC_CHIPSET);
-#endif
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /* Pulse SYS_RST */
- gpio_set_level(GPIO_SYS_RST_L, 0);
- if (in_interrupt_context())
- udelay(SYS_RST_HOLD_US);
- else
- usleep(SYS_RST_HOLD_US);
- gpio_set_level(GPIO_SYS_RST_L, 1);
-}
-
-enum power_state power_chipset_init(void)
-{
- if (system_jumped_to_this_image()) {
- if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) {
- disable_sleep(SLEEP_MASK_AP_RUN);
- CPRINTS("already in S0");
- return POWER_S0;
- }
- } else if (!(system_get_reset_flags() & EC_RESET_FLAG_AP_OFF))
- /* Auto-power on */
- chipset_exit_hard_off();
-
- return POWER_G3;
-}
-
-static void force_shutdown(void)
-{
- forcing_shutdown = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_DEFERRED(force_shutdown);
-
-/*
- * Debounce PGOOD_AP if we lose it suddenly during S0, since output voltage
- * transitions may cause spurious pulses.
- */
-#define PGOOD_AP_DEBOUNCE_TIMEOUT (100 * MSEC)
-
-/*
- * The AP informs the EC of its S0 / S3 state through IN_SUSPEND_DEASSERTED /
- * AP_EC_S3_S0_L. Latency between deassertion and power rails coming up must
- * be minimized, so check for deassertion at various stages of our suspend
- * power sequencing, and immediately transition out of suspend if necessary.
- */
-#define SLEEP_INTERVAL_MS 5
-#define MSLEEP_CHECK_ABORTED_SUSPEND(msec) \
- do { \
- int sleep_remain = msec; \
- do { \
- msleep(MIN(sleep_remain, SLEEP_INTERVAL_MS)); \
- sleep_remain -= SLEEP_INTERVAL_MS; \
- if (!forcing_shutdown && \
- power_get_signals() & IN_SUSPEND_DEASSERTED) { \
- CPRINTS("suspend aborted"); \
- return POWER_S3S0; \
- } \
- } while (sleep_remain > 0); \
- } while (0)
-BUILD_ASSERT(POWER_S3S0 != 0);
-
-/**
- * Step through the power sequence table and do corresponding GPIO operations.
- *
- * @param power_seq_ops The pointer to the power sequence table.
- * @param op_count The number of entries of power_seq_ops.
- * @return non-zero if suspend aborted during POWER_S0S3, 0 otherwise.
- */
-static int power_seq_run(const struct power_seq_op *power_seq_ops, int op_count)
-{
- int i;
-
- for (i = 0; i < op_count; i++) {
- gpio_set_level(power_seq_ops[i].signal,
- power_seq_ops[i].level);
- if (!power_seq_ops[i].delay)
- continue;
- if ((power_seq_ops == s0s3_power_seq)
-#ifdef S3_USB_WAKE
- || (power_seq_ops == s0s3_usb_wake_power_seq)
-#endif
- )
- MSLEEP_CHECK_ABORTED_SUSPEND(power_seq_ops[i].delay);
- else
- msleep(power_seq_ops[i].delay);
- }
- return 0;
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
-#ifndef CR50_DEEP_SLEEP
- static int sys_reset_asserted;
-#endif
-#ifdef S3_USB_WAKE
- static int usb_wake_enabled;
-#endif
- int tries = 0;
-
- switch (state) {
- case POWER_G3:
- break;
-
- case POWER_S5:
- if (forcing_shutdown)
- return POWER_S5G3;
- else
- return POWER_S5S3;
- break;
-
- case POWER_S3:
- if (!power_has_signals(IN_PGOOD_S3) || forcing_shutdown)
- return POWER_S3S5;
- else if (power_get_signals() & IN_SUSPEND_DEASSERTED)
- return POWER_S3S0;
- break;
-
- case POWER_S0:
- if (!power_has_signals(IN_PGOOD_S3) ||
- forcing_shutdown ||
- !(power_get_signals() & IN_SUSPEND_DEASSERTED))
- return POWER_S0S3;
-
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION != 1
- /*
- * Wait up to PGOOD_AP_DEBOUNCE_TIMEOUT for IN_PGOOD_AP to
- * come back before transitioning back to S3. PGOOD_SYS can
- * also glitch, with a glitch duration < 1ms, so debounce
- * it here as well.
- */
- if (power_wait_signals_timeout(IN_PGOOD_AP | IN_PGOOD_SYS,
- PGOOD_AP_DEBOUNCE_TIMEOUT)
- == EC_ERROR_TIMEOUT)
- return POWER_S0S3;
-
- /*
- * power_wait_signals_timeout() can block and consume task
- * wake events, so re-verify the state of the world.
- */
- if (!power_has_signals(IN_PGOOD_S3) ||
- forcing_shutdown ||
- !(power_get_signals() & IN_SUSPEND_DEASSERTED))
- return POWER_S0S3;
-#endif
-
- break;
-
- case POWER_G3S5:
- forcing_shutdown = 0;
-
- /*
- * Allow time for charger to be initialized, in case we're
- * trying to boot the AP with no battery.
- */
- while (charge_prevent_power_on(0) &&
- tries++ < CHARGER_INITIALIZED_TRIES) {
- msleep(CHARGER_INITIALIZED_DELAY_MS);
- }
-
- /* Return to G3 if battery level is too low. */
- if (charge_want_shutdown() ||
- tries > CHARGER_INITIALIZED_TRIES) {
- CPRINTS("power-up inhibited");
- chipset_force_shutdown(
- CHIPSET_SHUTDOWN_BATTERY_INHIBIT);
- return POWER_G3;
- }
-
- /* Power up to next state */
- return POWER_S5;
-
- case POWER_S5S3:
- power_seq_run(s5s3_power_seq, ARRAY_SIZE(s5s3_power_seq));
-
-#ifndef CR50_DEEP_SLEEP
- /*
- * Assert SYS_RST now, to be released in S3S0, to avoid
- * resetting the TPM soon after power-on.
- */
- sys_reset_asserted = 1;
-#endif
-
- if (power_wait_signals(IN_PGOOD_S3)) {
- chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
- return POWER_S3S5;
- }
-
- /* Call hooks now that rails are up */
- hook_notify(HOOK_CHIPSET_STARTUP);
-
- /* Power up to next state */
- return POWER_S3;
-
- case POWER_S3S0:
-#ifdef S3_USB_WAKE
- /* Bring up S3 USB wake rails, if they are down */
- if (!usb_wake_enabled)
- power_seq_run(s3s0_usb_wake_power_seq,
- ARRAY_SIZE(s3s0_usb_wake_power_seq));
- usb_wake_enabled = 0;
-#endif
- power_seq_run(s3s0_power_seq, ARRAY_SIZE(s3s0_power_seq));
-
-#ifndef CR50_DEEP_SLEEP
- /* Release SYS_RST if we came from S5 */
- if (sys_reset_asserted) {
-#endif
- msleep(10);
- gpio_set_level(GPIO_SYS_RST_L, 1);
-
-#ifndef CR50_DEEP_SLEEP
- sys_reset_asserted = 0;
- }
-#endif
-
-#ifdef POWER_SIGNAL_POLLING
- /*
- * Poll power signals every PGOOD_S0_POLL_TIMEOUT us, since
- * AP_PWR_GOOD assertion doesn't trigger a power signal
- * interrupt.
- */
- while (power_wait_signals_timeout(IN_PGOOD_S0,
- PGOOD_S0_POLL_TIMEOUT) == EC_ERROR_TIMEOUT &&
- ++tries < PGOOD_S0_POLL_TRIES)
- ;
-
- if (tries >= PGOOD_S0_POLL_TRIES) {
- CPRINTS("power timeout on input; "
- "wanted 0x%04x, got 0x%04x",
- IN_PGOOD_S0, power_get_signals() & IN_PGOOD_S0);
-#else
- if (power_wait_signals(IN_PGOOD_S0)) {
-#endif /* POWER_SIGNAL_POLLING */
- chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT);
- return POWER_S0S3;
- }
-
- /* 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);
-
- /* Power up to next state */
- return POWER_S0;
-
- case POWER_S0S3:
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SUSPEND);
- MSLEEP_CHECK_ABORTED_SUSPEND(20);
-
- if (power_seq_run(s0s3_power_seq, ARRAY_SIZE(s0s3_power_seq)))
- return POWER_S3S0;
-
-#ifdef S3_USB_WAKE
- /* Leave up rails needed for S3 USB wake, if requested */
- usb_wake_enabled = (power_get_host_sleep_state() ==
- HOST_SLEEP_EVENT_S3_WAKEABLE_SUSPEND);
- if (!usb_wake_enabled &&
- power_seq_run(s0s3_usb_wake_power_seq,
- ARRAY_SIZE(s0s3_usb_wake_power_seq)))
- return POWER_S3S0;
-#endif
-
- /*
- * 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);
-
- /*
- * In case the power button is held awaiting power-off timeout,
- * power off immediately now that we're entering S3.
- */
- if (power_button_is_pressed()) {
- forcing_shutdown = 1;
- hook_call_deferred(&force_shutdown_data, -1);
- }
-
- return POWER_S3;
-
- case POWER_S3S5:
-#ifdef S3_USB_WAKE
- /* Make sure all S3 rails are off */
- if (usb_wake_enabled) {
- power_seq_run(s0s3_usb_wake_power_seq,
- ARRAY_SIZE(s0s3_usb_wake_power_seq));
- usb_wake_enabled = 0;
- }
-#endif
-
- /* Call hooks before we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
-
- power_seq_run(s3s5_power_seq, ARRAY_SIZE(s3s5_power_seq));
-
- /* Call hooks after we remove power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-
- /* Start shutting down */
- return POWER_S5;
-
- case POWER_S5G3:
- return POWER_G3;
- }
-
- return state;
-}
-
-static void power_button_changed(void)
-{
- static uint8_t tablet_boot_on_button_release;
-
- if (power_button_is_pressed()) {
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION != 1
- /* Power up from off */
- chipset_exit_hard_off();
-#else
- tablet_boot_on_button_release = 1;
-#endif
- }
- /* Delayed power down from S0/S3, cancel on PB release */
- hook_call_deferred(&force_shutdown_data,
- FORCED_SHUTDOWN_DELAY);
- } else {
-#if CONFIG_CHIPSET_POWER_SEQ_VERSION == 1
- if (tablet_boot_on_button_release) {
- /* Power up from off */
- chipset_exit_hard_off();
- tablet_boot_on_button_release = 0;
- }
-#endif
- /* Power button released, cancel deferred shutdown */
- hook_call_deferred(&force_shutdown_data, -1);
- }
-}
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT);
-
-#ifdef CONFIG_LID_SWITCH
-static void lid_changed(void)
-{
- /* Power-up from off on lid open */
- if (lid_is_open() && chipset_in_state(CHIPSET_STATE_ANY_OFF))
- chipset_exit_hard_off();
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, lid_changed, HOOK_PRIO_DEFAULT);
-#endif
-
-#ifdef POWER_SIGNAL_POLLING
-/*
- * Polling for non-INT power signal pins.
- * Call power_signal_interrupt() when the GPIO status of those pins changes.
- */
-static void power_signal_changed(void)
-{
- static uint8_t in_signals; /* Current power signal status */
- uint8_t inew = 0;
- const struct power_signal_info *s = power_signal_list;
- int i;
-
- BUILD_ASSERT(POWER_SIGNAL_COUNT <= 8);
-
- for (i = 0; i < POWER_SIGNAL_COUNT; i++, s++) {
- /* Skip if this is an INT pin. */
- if (s->gpio < GPIO_IH_COUNT)
- continue;
-
- if (power_signal_is_asserted(s))
- inew |= 1 << i;
- }
-
- if (inew != in_signals) {
- /*
- * Pass a fake power gpio_signal to power_signal_interrupt().
- * Note that here we make power_signal_interrupt() reentrant.
- */
- power_signal_interrupt(POWER_SIGNAL_COUNT);
- in_signals = inew;
- }
-}
-DECLARE_HOOK(HOOK_TICK, power_signal_changed, HOOK_PRIO_DEFAULT);
-#endif
diff --git a/power/sdm845.c b/power/sdm845.c
deleted file mode 100644
index a8cc70b8ea..0000000000
--- a/power/sdm845.c
+++ /dev/null
@@ -1,882 +0,0 @@
-/* Copyright 2018 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.
- */
-
-/*
- * SDM845 SoC power sequencing module for Chrome EC
- *
- * This implements the following features:
- *
- * - Cold reset powers on the AP
- *
- * When powered off:
- * - Press power button turns on the AP
- * - Hold power button turns on the AP, and then 8s later turns it off and
- * leaves it off until pwron is released and pressed again
- * - Lid open turns on the AP
- *
- * When powered on:
- * - Holding power button for 8s powers off the AP
- * - Pressing and releasing pwron within that 8s is ignored
- * - If POWER_GOOD is dropped by the AP, then we power the AP off
- */
-
-#include "charge_state.h"
-#include "chipset.h"
-#include "common.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "lid_switch.h"
-#include "power.h"
-#include "power_button.h"
-#include "system.h"
-#include "task.h"
-#include "util.h"
-
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-/* Masks for power signals */
-#define IN_POWER_GOOD POWER_SIGNAL_MASK(SDM845_POWER_GOOD)
-#define IN_AP_RST_ASSERTED POWER_SIGNAL_MASK(SDM845_AP_RST_ASSERTED)
-
-
-/* Long power key press to force shutdown */
-#define DELAY_FORCE_SHUTDOWN (8 * SECOND)
-
-/*
- * If the power button is pressed to turn on, then held for this long, we
- * power off.
- *
- * Normal case: User releases power button and chipset_task() goes
- * into the inner loop, waiting for next event to occur (power button
- * press or POWER_GOOD == 0).
- */
-#define DELAY_SHUTDOWN_ON_POWER_HOLD (8 * SECOND)
-
-/*
- * After trigger PMIC power sequence, how long it triggers AP to turn on
- * or off. Observed that the worst case is ~150ms. Pick a safe vale.
- */
-#define PMIC_POWER_AP_RESPONSE_TIMEOUT (350 * MSEC)
-
-/*
- * After force off the switch cap, how long the PMIC/AP totally off.
- * Observed that the worst case is 2s. Pick a safe vale.
- */
-#define FORCE_OFF_RESPONSE_TIMEOUT (4 * SECOND)
-
-/* Wait for polling the AP on signal */
-#define PMIC_POWER_AP_WAIT (1 * MSEC)
-
-/* The length of an issued low pulse to the PMIC_RESIN_L signal */
-#define PMIC_RESIN_PULSE_LENGTH (20 * MSEC)
-
-/* The timeout of the check if the system can boot AP */
-#define CAN_BOOT_AP_CHECK_TIMEOUT (500 * MSEC)
-
-/* Wait for polling if the system can boot AP */
-#define CAN_BOOT_AP_CHECK_WAIT (100 * MSEC)
-
-/* The timeout of the check if the switchcap outputs good voltage */
-#define SWITCHCAP_PG_CHECK_TIMEOUT (50 * MSEC)
-
-/* Wait for polling if the switchcap outputs good voltage */
-#define SWITCHCAP_PG_CHECK_WAIT (5 * MSEC)
-
-/* Delay between power-on the system and power-on the PMIC */
-#define SYSTEM_POWER_ON_DELAY (10 * MSEC)
-
-/* TODO(crosbug.com/p/25047): move to HOOK_POWER_BUTTON_CHANGE */
-/* 1 if the power button was pressed last time we checked */
-static char power_button_was_pressed;
-
-/* 1 if lid-open event has been detected */
-static char lid_opened;
-
-/* 1 if AP_RST_L and PS_HOLD is overdriven by EC */
-static char ap_rst_overdriven;
-
-/* Time where we will power off, if power button still held down */
-static timestamp_t power_off_deadline;
-
-/* Force AP power on (used for recovery keypress) */
-static int auto_power_on;
-
-enum power_request_t {
- POWER_REQ_NONE,
- POWER_REQ_OFF,
- POWER_REQ_ON,
- POWER_REQ_RESET,
-
- POWER_REQ_COUNT,
-};
-
-static enum power_request_t power_request;
-
-/**
- * Return values for check_for_power_off_event().
- */
-enum power_off_event_t {
- POWER_OFF_CANCEL,
- POWER_OFF_BY_POWER_BUTTON_PRESSED,
- POWER_OFF_BY_LONG_PRESS,
- POWER_OFF_BY_POWER_GOOD_LOST,
- POWER_OFF_BY_POWER_REQ_OFF,
- POWER_OFF_BY_POWER_REQ_RESET,
-
- POWER_OFF_EVENT_COUNT,
-};
-
-/**
- * Return values for check_for_power_on_event().
- */
-enum power_on_event_t {
- POWER_ON_CANCEL,
- POWER_ON_BY_IN_POWER_GOOD,
- POWER_ON_BY_AUTO_POWER_ON,
- POWER_ON_BY_LID_OPEN,
- POWER_ON_BY_POWER_BUTTON_PRESSED,
- POWER_ON_BY_POWER_REQ_ON,
- POWER_ON_BY_POWER_REQ_RESET,
-
- POWER_ON_EVENT_COUNT,
-};
-
-/* Issue a request to initiate a reset sequence */
-static void request_cold_reset(void)
-{
- power_request = POWER_REQ_RESET;
- task_wake(TASK_ID_CHIPSET);
-}
-
-/* AP-requested reset GPIO interrupt handlers */
-static void chipset_reset_request_handler(void)
-{
- CPRINTS("AP wants reset");
- chipset_reset(CHIPSET_RESET_AP_REQ);
-}
-DECLARE_DEFERRED(chipset_reset_request_handler);
-
-void chipset_reset_request_interrupt(enum gpio_signal signal)
-{
- hook_call_deferred(&chipset_reset_request_handler_data, 0);
-}
-
-void chipset_warm_reset_interrupt(enum gpio_signal signal)
-{
- /*
- * The warm_reset signal is pulled-up by a rail from PMIC. If the
- * warm_reset drops, it means:
- * * Servo or Cr50 holds the signal, or
- * * its pull-up rail POWER_GOOD drops.
- */
- if (!gpio_get_level(GPIO_WARM_RESET_L)) {
- if (gpio_get_level(GPIO_POWER_GOOD)) {
- /*
- * Servo or Cr50 holds the WARM_RESET_L signal.
- *
- * Overdrive AP_RST_L to hold AP. Overdrive PS_HOLD to
- * emulate AP being up to trick the PMIC into thinking
- * there’s nothing weird going on.
- */
- ap_rst_overdriven = 1;
- gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH |
- GPIO_SEL_1P8V | GPIO_OUT_HIGH);
- gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH |
- GPIO_SEL_1P8V | GPIO_OUT_LOW);
- } else {
- /*
- * The pull-up rail POWER_GOOD drops.
- *
- * High-Z both AP_RST_L and PS_HOLD to restore their
- * states.
- */
- gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH |
- GPIO_SEL_1P8V);
- gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH |
- GPIO_SEL_1P8V);
- ap_rst_overdriven = 0;
- }
- } else {
- if (ap_rst_overdriven) {
- /*
- * Servo or Cr50 releases the WARM_RESET_L signal.
- *
- * Cold reset the PMIC, doing S0->S5->S0 transition,
- * by issuing a request to initiate a reset sequence,
- * to recover the system. The transition to S5 makes
- * POWER_GOOD drop that triggers an interrupt to
- * high-Z both AP_RST_L and PS_HOLD.
- */
- request_cold_reset();
- }
- /* If not overdriven, just a normal power-up, do nothing. */
- }
-
- power_signal_interrupt(signal);
-}
-
-static void sdm845_lid_event(void)
-{
- /* Power task only cares about lid-open events */
- if (!lid_is_open())
- return;
-
- lid_opened = 1;
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, sdm845_lid_event, HOOK_PRIO_DEFAULT);
-
-static void powerbtn_sdm845_changed(void)
-{
- task_wake(TASK_ID_CHIPSET);
-}
-DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, powerbtn_sdm845_changed,
- HOOK_PRIO_DEFAULT);
-
-/**
- * Wait the switchcap GPIO0 PVC_PG signal asserted.
- *
- * When the output voltage is over the threshold PVC_PG_ADJ,
- * the PVC_PG is asserted.
- *
- * PVG_PG_ADJ is configured to 3.0V.
- * GPIO0 is configured as PVC_PG.
- *
- * @param enable 1 to wait the PMIC/AP on.
- 0 to wait the PMIC/AP off.
- */
-static void wait_switchcap_power_good(int enable)
-{
- timestamp_t poll_deadline;
-
- poll_deadline = get_time();
- poll_deadline.val += SWITCHCAP_PG_CHECK_TIMEOUT;
- while (enable != gpio_get_level(GPIO_DA9313_GPIO0) &&
- get_time().val < poll_deadline.val) {
- usleep(SWITCHCAP_PG_CHECK_WAIT);
- }
-
- /*
- * Check the timeout case. Just show a message. More check later
- * will switch the power state.
- */
- if (enable != gpio_get_level(GPIO_DA9313_GPIO0)) {
- if (enable)
- CPRINTS("SWITCHCAP NO POWER GOOD!");
- else
- CPRINTS("SWITCHCAP STILL POWER GOOD!");
- }
-
-}
-
-/**
- * Get the state of the system power signals.
- *
- * @return 1 if the system is powered, 0 if not
- */
-static int is_system_powered(void)
-{
- return gpio_get_level(GPIO_SWITCHCAP_ON_L);
-}
-
-/**
- * Get the PMIC/AP power signal.
- *
- * We treat the PMIC chips and the AP as a whole here. Don't deal with
- * the individual chip.
- *
- * @return 1 if the PMIC/AP is powered, 0 if not
- */
-static int is_pmic_pwron(void)
-{
- /* Use POWER_GOOD to indicate PMIC/AP is on/off */
- return gpio_get_level(GPIO_POWER_GOOD);
-}
-
-/**
- * Wait the PMIC/AP power-on state.
- *
- * @param enable 1 to wait the PMIC/AP on.
- 0 to wait the PMIC/AP off.
- * @param timeout Number of microsecond of timeout.
- */
-static void wait_pmic_pwron(int enable, unsigned int timeout)
-{
- timestamp_t poll_deadline;
-
- /* Check the AP power status */
- if (enable == is_pmic_pwron())
- return;
-
- poll_deadline = get_time();
- poll_deadline.val += timeout;
- while (enable != is_pmic_pwron() &&
- get_time().val < poll_deadline.val) {
- usleep(PMIC_POWER_AP_WAIT);
- }
-
- /* Check the timeout case */
- if (enable != is_pmic_pwron()) {
- if (enable)
- CPRINTS("AP POWER NOT READY!");
- else
- CPRINTS("AP POWER STILL UP!");
- }
-}
-
-/**
- * Set the state of the system power signals.
- *
- * The system power signals are the enable pins of SwitchCap and VBOB.
- * They control the power of the set of PMIC chips and the AP.
- *
- * @param enable 1 to enable or 0 to disable
- */
-static void set_system_power(int enable)
-{
- CPRINTS("%s(%d)", __func__, enable);
- gpio_set_level(GPIO_SWITCHCAP_ON_L, enable);
- wait_switchcap_power_good(enable);
- gpio_set_level(GPIO_VBOB_EN, enable);
- if (enable) {
- usleep(SYSTEM_POWER_ON_DELAY);
- } else {
- /* Ensure POWER_GOOD drop to low if it is a forced shutdown */
- wait_pmic_pwron(0, FORCE_OFF_RESPONSE_TIMEOUT);
- }
-}
-
-/**
- * Set the PMIC/AP power-on state.
- *
- * It triggers the PMIC/AP power-on and power-off sequence.
- *
- * @param enable 1 to power the PMIC/AP on.
- 0 to power the PMIC/AP off.
- */
-static void set_pmic_pwron(int enable)
-{
- CPRINTS("%s(%d)", __func__, enable);
-
- /* Check the PMIC/AP power state */
- if (enable == is_pmic_pwron())
- return;
-
- /*
- * Power-on sequence:
- * 1. Hold down PMIC_KPD_PWR_ODL, which is a power-on trigger
- * 2. PM845 supplies power to POWER_GOOD
- * 3. Release PMIC_KPD_PWR_ODL
- *
- * Power-off sequence:
- * 1. Hold down PMIC_KPD_PWR_ODL and PMIC_RESIN_L, which is a power-off
- * trigger (requiring reprogramming PMIC registers to make
- * PMIC_KPD_PWR_ODL + PMIC_RESIN_L as a shutdown trigger)
- * 2. PM845 stops supplying power to POWER_GOOD (requiring
- * reprogramming PMIC to set the stage-1 and stage-2 reset timers to
- * 0 such that the pull down happens just after the deboucing time
- * of the trigger, like 2ms)
- * 3. Release PMIC_KPD_PWR_ODL and PMIC_RESIN_L
- *
- * If the above PMIC registers not programmed or programmed wrong, it
- * falls back to the next functions, which cuts off the system power.
- */
-
- gpio_set_level(GPIO_PMIC_KPD_PWR_ODL, 0);
- if (!enable)
- gpio_set_level(GPIO_PMIC_RESIN_L, 0);
- wait_pmic_pwron(enable, PMIC_POWER_AP_RESPONSE_TIMEOUT);
- gpio_set_level(GPIO_PMIC_KPD_PWR_ODL, 1);
- if (!enable)
- gpio_set_level(GPIO_PMIC_RESIN_L, 1);
-}
-
-enum power_state power_chipset_init(void)
-{
- int init_power_state;
- uint32_t reset_flags = system_get_reset_flags();
-
- /* Enable interrupts */
- gpio_enable_interrupt(GPIO_AP_RST_REQ);
- gpio_enable_interrupt(GPIO_WARM_RESET_L);
- gpio_enable_interrupt(GPIO_POWER_GOOD);
-
- /*
- * Force the AP shutdown unless we are doing SYSJUMP. Otherwise,
- * the AP could stay in strange state.
- */
- if (!(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("not sysjump; forcing system shutdown");
- set_system_power(0);
- init_power_state = POWER_G3;
- } else {
- /* In the SYSJUMP case, we check if the AP is on */
- if (power_get_signals() & IN_POWER_GOOD) {
- CPRINTS("SOC ON");
- init_power_state = POWER_S0;
- /* Disable idle task deep sleep when in S0 */
- disable_sleep(SLEEP_MASK_AP_RUN);
- } else {
- CPRINTS("SOC OFF");
- init_power_state = POWER_G3;
- }
- }
-
- /* Leave power off only if requested by reset flags */
- if (!(reset_flags & EC_RESET_FLAG_AP_OFF) &&
- !(reset_flags & EC_RESET_FLAG_SYSJUMP)) {
- CPRINTS("auto_power_on set due to reset_flag 0x%x",
- system_get_reset_flags());
- auto_power_on = 1;
- }
-
- if (battery_is_present() == BP_YES) {
- /*
- * (crosbug.com/p/28289): Wait battery stable.
- * Some batteries use clock stretching feature, which requires
- * more time to be stable.
- */
- battery_wait_for_stable();
- }
-
- return init_power_state;
-}
-
-/*****************************************************************************/
-
-/**
- * Power off the AP
- */
-static void power_off(void)
-{
- /* Check the power off status */
- if (!is_system_powered())
- return;
-
- /* Call hooks before we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN);
-
- /* Do a graceful way to shutdown PMIC/AP first */
- set_pmic_pwron(0);
-
- /* Disable signal interrupts, as they are floating when switchcap off */
- power_signal_disable_interrupt(GPIO_AP_RST_L);
- power_signal_disable_interrupt(GPIO_PMIC_FAULT_L);
-
- /* Force to switch off all rails */
- set_system_power(0);
-
- /* Turn off the 3.3V and 5V rails. */
- gpio_set_level(GPIO_EN_PP3300_A, 0);
-#ifdef CONFIG_POWER_PP5000_CONTROL
- power_5v_enable(task_get_current(), 0);
-#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
- gpio_set_level(GPIO_EN_PP5000, 0);
-#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
-
- lid_opened = 0;
- enable_sleep(SLEEP_MASK_AP_RUN);
- CPRINTS("power shutdown complete");
-
- /* Call hooks after we drop power rails */
- hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
-}
-
-/**
- * Check if the power is enough to boot the AP.
- */
-static int power_is_enough(void)
-{
- timestamp_t poll_deadline;
-
- /* If powered by adapter only, wait a while for PD negoiation. */
- poll_deadline = get_time();
- poll_deadline.val += CAN_BOOT_AP_CHECK_TIMEOUT;
-
- /*
- * Wait for PD negotiation. If a system with drained battery, don't
- * waste the time and exit the loop.
- */
- while (!system_can_boot_ap() && !charge_want_shutdown() &&
- get_time().val < poll_deadline.val) {
- usleep(CAN_BOOT_AP_CHECK_WAIT);
- }
-
- return system_can_boot_ap() && !charge_want_shutdown();
-}
-
-/**
- * Power on the AP
- */
-static void power_on(void)
-{
- /*
- * If no enough power, return and the state machine will transition
- * back to S5.
- */
- if (!power_is_enough())
- return;
-
- /*
- * When power_on() is called, we are at S5S3. Initialize components
- * to ready state before AP is up.
- */
- hook_notify(HOOK_CHIPSET_PRE_INIT);
-
- /* Enable the 3.3V and 5V rail. */
- gpio_set_level(GPIO_EN_PP3300_A, 1);
-#ifdef CONFIG_POWER_PP5000_CONTROL
- power_5v_enable(task_get_current(), 1);
-#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
- gpio_set_level(GPIO_EN_PP5000, 1);
-#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
-
- set_system_power(1);
-
- /* Enable signal interrupts */
- power_signal_enable_interrupt(GPIO_AP_RST_L);
- power_signal_enable_interrupt(GPIO_PMIC_FAULT_L);
-
- set_pmic_pwron(1);
-
- disable_sleep(SLEEP_MASK_AP_RUN);
-
- CPRINTS("AP running ...");
-}
-
-/**
- * Check if there has been a power-on event
- *
- * This checks all power-on event signals and returns non-zero if any have been
- * triggered (with debounce taken into account).
- *
- * @return non-zero if there has been a power-on event, 0 if not.
- */
-static uint8_t check_for_power_on_event(void)
-{
- int ap_off_flag;
-
- ap_off_flag = system_get_reset_flags() & EC_RESET_FLAG_AP_OFF;
- system_clear_reset_flags(EC_RESET_FLAG_AP_OFF);
-
- if (power_request == POWER_REQ_ON) {
- power_request = POWER_REQ_NONE;
- return POWER_ON_BY_POWER_REQ_ON;
- } else if (power_request == POWER_REQ_RESET) {
- power_request = POWER_REQ_NONE;
- return POWER_ON_BY_POWER_REQ_RESET;
- }
- /* Clear invalid request */
- power_request = POWER_REQ_NONE;
-
- /* check if system is already ON */
- if (power_get_signals() & IN_POWER_GOOD) {
- if (ap_off_flag) {
- CPRINTS("system is on, but EC_RESET_FLAG_AP_OFF is on");
- return POWER_ON_CANCEL;
- }
- CPRINTS("system is on, thus clear auto_power_on");
- /* no need to arrange another power on */
- auto_power_on = 0;
- return POWER_ON_BY_IN_POWER_GOOD;
- }
- if (ap_off_flag) {
- CPRINTS("EC_RESET_FLAG_AP_OFF is on");
- power_off();
- return POWER_ON_CANCEL;
- }
-
- CPRINTS("POWER_GOOD is not asserted");
-
- /* power on requested at EC startup for recovery */
- if (auto_power_on) {
- auto_power_on = 0;
- return POWER_ON_BY_AUTO_POWER_ON;
- }
-
- /* Check lid open */
- if (lid_opened) {
- lid_opened = 0;
- return POWER_ON_BY_LID_OPEN;
- }
-
- /* check for power button press */
- if (power_button_is_pressed())
- return POWER_ON_BY_POWER_BUTTON_PRESSED;
-
- return POWER_OFF_CANCEL;
-}
-
-/**
- * Check for some event triggering the shutdown.
- *
- * It can be either a long power button press or a shutdown triggered from the
- * AP and detected by reading POWER_GOOD.
- *
- * @return non-zero if a shutdown should happen, 0 if not
- */
-static uint8_t check_for_power_off_event(void)
-{
- timestamp_t now;
- int pressed = 0;
-
- if (power_request == POWER_REQ_OFF) {
- power_request = POWER_REQ_NONE;
- return POWER_OFF_BY_POWER_REQ_OFF;
- } else if (power_request == POWER_REQ_RESET) {
- /*
- * The power_request flag will be cleared later
- * in check_for_power_on_event() in S5.
- */
- return POWER_OFF_BY_POWER_REQ_RESET;
- }
- /* Clear invalid request */
- power_request = POWER_REQ_NONE;
-
- /*
- * Check for power button press.
- */
- if (power_button_is_pressed())
- pressed = POWER_OFF_BY_POWER_BUTTON_PRESSED;
-
- now = get_time();
- if (pressed) {
- if (!power_button_was_pressed) {
- power_off_deadline.val = now.val + DELAY_FORCE_SHUTDOWN;
- CPRINTS("power waiting for long press %u",
- power_off_deadline.le.lo);
- /* Ensure we will wake up to check the power key */
- timer_arm(power_off_deadline, TASK_ID_CHIPSET);
- } else if (timestamp_expired(power_off_deadline, &now)) {
- power_off_deadline.val = 0;
- CPRINTS("power off after long press now=%u, %u",
- now.le.lo, power_off_deadline.le.lo);
- return POWER_OFF_BY_LONG_PRESS;
- }
- } else if (power_button_was_pressed) {
- CPRINTS("power off cancel");
- timer_cancel(TASK_ID_CHIPSET);
- }
-
- power_button_was_pressed = pressed;
-
- /* POWER_GOOD released by AP : shutdown immediately */
- if (!power_has_signals(IN_POWER_GOOD)) {
- if (power_button_was_pressed)
- timer_cancel(TASK_ID_CHIPSET);
-
- CPRINTS("POWER_GOOD is lost");
- return POWER_OFF_BY_POWER_GOOD_LOST;
- }
-
- return POWER_OFF_CANCEL;
-}
-
-/*****************************************************************************/
-/* Chipset interface */
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /* Issue a request to initiate a power-off sequence */
- power_request = POWER_REQ_OFF;
- task_wake(TASK_ID_CHIPSET);
-}
-
-void chipset_reset(enum chipset_reset_reason reason)
-{
- int rv;
-
- CPRINTS("%s(%d)", __func__, reason);
- report_ap_reset(reason);
-
- /*
- * Warm reset sequence:
- * 1. Issue a low pulse to PMIC_RESIN_L, which triggers PMIC
- * to do a warm reset (requiring reprogramming PMIC registers
- * to make PMIC_RESIN_L as a warm reset trigger).
- * 2. PMIC then issues a low pulse to AP_RST_L to reset AP.
- * EC monitors the signal to see any low pulse.
- * 2.1. If a low pulse found, done.
- * 2.2. If a low pulse not found (the above PMIC registers
- * not programmed or programmed wrong), issue a request
- * to initiate a cold reset power sequence.
- */
-
- gpio_set_level(GPIO_PMIC_RESIN_L, 0);
- usleep(PMIC_RESIN_PULSE_LENGTH);
- gpio_set_level(GPIO_PMIC_RESIN_L, 1);
-
- rv = power_wait_signals_timeout(IN_AP_RST_ASSERTED,
- PMIC_POWER_AP_RESPONSE_TIMEOUT);
- /* Exception case: PMIC not work as expected, request a cold reset */
- if (rv != EC_SUCCESS)
- request_cold_reset();
-}
-
-/**
- * Power handler for steady states
- *
- * @param state Current power state
- * @return Updated power state
- */
-enum power_state power_handle_state(enum power_state state)
-{
- uint8_t value;
- static uint8_t boot_from_g3, shutdown_from_s0;
-
- switch (state) {
- case POWER_G3:
- boot_from_g3 = check_for_power_on_event();
- if (boot_from_g3)
- return POWER_G3S5;
- break;
-
- case POWER_G3S5:
- return POWER_S5;
-
- case POWER_S5:
- if (boot_from_g3) {
- value = boot_from_g3;
- boot_from_g3 = 0;
- } else {
- value = check_for_power_on_event();
- }
-
- if (value) {
- CPRINTS("power on %d", value);
- return POWER_S5S3;
- }
- break;
-
- case POWER_S5S3:
- /*
- * Wait for power button release before actually boot AP.
- * It may be a long-hold power button with volume buttons
- * to trigger the recovery button. We don't want AP up
- * during the long-hold.
- */
- power_button_wait_for_release(-1);
-
- power_on();
- if (power_wait_signals(IN_POWER_GOOD) != EC_SUCCESS) {
- CPRINTS("POWER_GOOD not seen in time");
- set_system_power(0);
- return POWER_S5;
- }
-
- CPRINTS("POWER_GOOD seen");
- /* Call hooks now that AP is running */
- hook_notify(HOOK_CHIPSET_STARTUP);
- return POWER_S3;
-
- case POWER_S3:
- if (shutdown_from_s0) {
- value = shutdown_from_s0;
- shutdown_from_s0 = 0;
- } else {
- value = check_for_power_off_event();
- }
-
- if (value) {
- CPRINTS("power off %d", value);
- return POWER_S3S5;
- }
- /* Go to S3S0 directly, as don't know if it is in suspend */
- return POWER_S3S0;
-
- case POWER_S3S0:
- hook_notify(HOOK_CHIPSET_RESUME);
- return POWER_S0;
-
- case POWER_S0:
- shutdown_from_s0 = check_for_power_off_event();
- if (shutdown_from_s0)
- return POWER_S0S3;
- break;
-
- case POWER_S0S3:
- /*
- * If the power button is pressing, we need cancel the long
- * press timer, otherwise EC will crash.
- */
- if (power_button_was_pressed)
- timer_cancel(TASK_ID_CHIPSET);
-
- /* Call hooks here since we don't know it prior to AP suspend */
- hook_notify(HOOK_CHIPSET_SUSPEND);
- return POWER_S3;
-
- case POWER_S3S5:
- power_off();
- /*
- * Wait forever for the release of the power button; otherwise,
- * this power button press will then trigger a power-on in S5.
- */
- power_button_wait_for_release(-1);
- power_button_was_pressed = 0;
- return POWER_S5;
-
- case POWER_S5G3:
- return POWER_G3;
- }
-
- return state;
-}
-
-/*****************************************************************************/
-/* Console debug command */
-
-static const char *power_req_name[POWER_REQ_COUNT] = {
- "none",
- "off",
- "on",
-};
-
-/* Power states that we can report */
-enum power_state_t {
- PSTATE_UNKNOWN,
- PSTATE_OFF,
- PSTATE_ON,
- PSTATE_COUNT,
-};
-
-static const char * const state_name[] = {
- "unknown",
- "off",
- "on",
-};
-
-static int command_power(int argc, char **argv)
-{
- int v;
-
- if (argc < 2) {
- enum power_state_t state;
-
- state = PSTATE_UNKNOWN;
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- state = PSTATE_OFF;
- if (chipset_in_state(CHIPSET_STATE_ON))
- state = PSTATE_ON;
- ccprintf("%s\n", state_name[state]);
-
- return EC_SUCCESS;
- }
-
- if (!parse_bool(argv[1], &v))
- return EC_ERROR_PARAM1;
-
- power_request = v ? POWER_REQ_ON : POWER_REQ_OFF;
- ccprintf("Requesting power %s\n", power_req_name[power_request]);
- task_wake(TASK_ID_CHIPSET);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(power, command_power,
- "on/off",
- "Turn AP power on/off");
diff --git a/power/skylake.c b/power/skylake.c
deleted file mode 100644
index a4cb649fd5..0000000000
--- a/power/skylake.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/* Copyright 2015 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.
- */
-
-/* Skylake IMVP8 / ROP PMIC chipset power control module for Chrome EC */
-
-#include "chipset.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "lpc.h"
-#include "panic.h"
-#include "power/intel_x86.h"
-#include "power_button.h"
-#include "system.h"
-#include "timer.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
-
-static int forcing_shutdown; /* Forced shutdown in progress? */
-
-/* Power signals list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
-#ifdef CONFIG_POWER_S0IX
- [X86_SLP_S0_DEASSERTED] = {
- GPIO_PCH_SLP_S0_L,
- POWER_SIGNAL_ACTIVE_HIGH | POWER_SIGNAL_DISABLE_AT_BOOT,
- "SLP_S0_DEASSERTED",
- },
-#endif
- [X86_SLP_S3_DEASSERTED] = {
- SLP_S3_SIGNAL_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SLP_S3_DEASSERTED",
- },
- [X86_SLP_S4_DEASSERTED] = {
- SLP_S4_SIGNAL_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SLP_S4_DEASSERTED",
- },
- [X86_SLP_SUS_DEASSERTED] = {
- GPIO_PCH_SLP_SUS_L,
- POWER_SIGNAL_ACTIVE_HIGH,
- "SLP_SUS_DEASSERTED",
- },
- [X86_RSMRST_L_PWRGD] = {
- GPIO_RSMRST_L_PGOOD,
- POWER_SIGNAL_ACTIVE_HIGH,
- "RSMRST_N_PWRGD",
- },
- [X86_PMIC_DPWROK] = {
- GPIO_PMIC_DPWROK,
- POWER_SIGNAL_ACTIVE_HIGH,
- "PMIC_DPWROK",
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-
-
-void chipset_force_shutdown(enum chipset_shutdown_reason reason)
-{
- CPRINTS("%s()", __func__);
-
- /*
- * Force off. Sending a reset command to the PMIC will power off
- * the EC, so simulate a long power button press instead. This
- * condition will reset once the state machine transitions to G3.
- * Consider reducing the latency here by changing the power off
- * hold time on the PMIC.
- */
- if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
- report_ap_reset(reason);
- forcing_shutdown = 1;
- power_button_pch_press();
- }
-}
-
-__attribute__((weak)) void chipset_set_pmic_slp_sus_l(int level)
-{
- gpio_set_level(GPIO_PMIC_SLP_SUS_L, level);
-}
-
-enum power_state chipset_force_g3(void)
-{
- CPRINTS("Forcing fake G3.");
-
- chipset_set_pmic_slp_sus_l(0);
-
- return POWER_G3;
-}
-
-static void handle_slp_sus(enum power_state state)
-{
- /* If we're down or going down don't do anythin with SLP_SUS_L. */
- if (state == POWER_G3 || state == POWER_S5G3)
- return;
-
- /* Always mimic PCH SLP_SUS request for all other states. */
- chipset_set_pmic_slp_sus_l(gpio_get_level(GPIO_PCH_SLP_SUS_L));
-}
-
-void chipset_handle_espi_reset_assert(void)
-{
- /*
- * If eSPI_Reset# pin is asserted without SLP_SUS# being asserted, then
- * it means that there is an unexpected power loss (global reset
- * event). In this case, check if shutdown was being forced by pressing
- * power button. If yes, release power button.
- */
- if ((power_get_signals() & IN_PCH_SLP_SUS_DEASSERTED) &&
- forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
-}
-
-enum power_state power_handle_state(enum power_state state)
-{
- enum power_state new_state;
-
- /* Process RSMRST_L state changes. */
- common_intel_x86_handle_rsmrst(state);
-
- if (state == POWER_S5 && forcing_shutdown) {
- power_button_pch_release();
- forcing_shutdown = 0;
- }
-
- new_state = common_intel_x86_power_handle_state(state);
-
- /* Process SLP_SUS_L state changes after a new state is decided. */
- handle_slp_sus(new_state);
-
- return new_state;
-}
-
-/* Workaround for flags getting lost with power cycle */
-__attribute__((weak)) int board_has_working_reset_flags(void)
-{
- return 1;
-}
-
-#ifdef CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET
-void chipset_handle_reboot(void)
-{
- int flags;
-
- if (system_jumped_to_this_image())
- return;
-
- /* Interrogate current reset flags from previous reboot. */
- flags = system_get_reset_flags();
-
- /*
- * Do not make PMIC re-sequence the power rails if the following reset
- * conditions are not met.
- */
- if (!(flags &
- (EC_RESET_FLAG_WATCHDOG | EC_RESET_FLAG_SOFT |
- EC_RESET_FLAG_HARD)))
- return;
-
- /* Preserve AP off request. */
- if (flags & EC_RESET_FLAG_AP_OFF) {
- /* Do not issue PMIC reset if board cannot save reset flags */
- if (!board_has_working_reset_flags()) {
- ccprintf("Skip PMIC reset due to board issue.\n");
- cflush();
- return;
- }
- chip_save_reset_flags(EC_RESET_FLAG_AP_OFF);
- }
-
-#ifdef CONFIG_CHIP_PANIC_BACKUP
- /* Ensure panic data if any is backed up. */
- chip_panic_data_backup();
-#endif
-
- ccprintf("Restarting system with PMIC.\n");
- /* Flush console */
- cflush();
-
- /* Bring down all rails but RTC rail (including EC power). */
- gpio_set_level(GPIO_EC_PLATFORM_RST, 1);
- while (1)
- ; /* wait here */
-}
-#if !defined(CONFIG_VBOOT_EFS) || !defined(CONFIG_VBOOT_EFS2)
-/* This is run in main for EFS1 & EFS2 */
-DECLARE_HOOK(HOOK_INIT, chipset_handle_reboot, HOOK_PRIO_FIRST);
-#endif
-#endif /* CONFIG_CHIPSET_HAS_PLATFORM_RESET */