summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2018-07-04 09:13:41 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-07-27 19:11:09 -0700
commitbe93944bf6900f5efb190340841d6dbeb3371c16 (patch)
tree753aa54fc3ef98bf5b07730dab3613a8e75bfe01 /power
parente7b3fe0a346cc3471555272e008cf95fc69a7925 (diff)
downloadchrome-ec-be93944bf6900f5efb190340841d6dbeb3371c16.tar.gz
icelake: Add power sequencing support for icelake
This CL adds code to support x86 power sequencing for icelake. BRANCH=none CQ-DEPEND=I0bf29d69de471c64f905ee8aa070b15b4f34f2ba BUG=b:111121615,b:111853963 TEST=make buildall. Also tested on P0 and verified that AP gets to S0. Change-Id: I3513f2e598162b2362d56c33df76d16b63864bd3 Signed-off-by: Scott Collyer <scollyer@google.com> Reviewed-on: https://chromium-review.googlesource.com/1123318 Commit-Ready: Furquan Shaikh <furquan@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/build.mk1
-rw-r--r--power/icelake.c145
-rw-r--r--power/icelake.h29
-rw-r--r--power/intel_x86.c4
4 files changed, 178 insertions, 1 deletions
diff --git a/power/build.mk b/power/build.mk
index a15b6cf49e..69eece1c36 100644
--- a/power/build.mk
+++ b/power/build.mk
@@ -10,6 +10,7 @@ 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_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_RK3288)+=rk3288.o
diff --git a/power/icelake.c b/power/icelake.c
new file mode 100644
index 0000000000..3f5a89a5cb
--- /dev/null
+++ b/power/icelake.c
@@ -0,0 +1,145 @@
+/* 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 "icelake.h"
+#include "chipset.h"
+#include "console.h"
+#include "gpio.h"
+#include "intel_x86.h"
+#include "power.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)
+{
+ int timeout_ms = 50;
+
+ CPRINTS("%s()", __func__, reason);
+ report_ap_reset(reason);
+
+ /* Turn off DSW load switch. */
+ gpio_set_level(GPIO_EN_PP3300_A, 0);
+
+ /*
+ * TODO(b/111810925): Replace this wait with
+ * power_wait_signals_timeout()
+ */
+ /* Now wait for DSW_PWROK to go away. */
+ while (gpio_get_level(GPIO_PG_EC_DSW_PWROK) && (timeout_ms > 0)) {
+ msleep(1);
+ timeout_ms--;
+ };
+
+ if (!timeout_ms)
+ CPRINTS("DSW_PWROK 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;
+}
+
+enum power_state power_handle_state(enum power_state state)
+{
+ int dswpwrok_in = gpio_get_level(GPIO_PG_EC_DSW_PWROK);
+ static int dswpwrok_out = -1;
+ int timeout_ms = 100;
+
+ /* Pass-through DSW_PWROK to ICL. */
+ if (dswpwrok_in != dswpwrok_out) {
+ 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_EC_PCH_DSW_PWROK, dswpwrok_in);
+ dswpwrok_out = dswpwrok_in;
+ }
+
+ common_intel_x86_handle_rsmrst(state);
+
+ switch (state) {
+
+ case POWER_G3S5:
+ /*
+ * 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. */
+ dswpwrok_in = gpio_get_level(GPIO_PG_EC_DSW_PWROK);
+ /*
+ * 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_EC_PCH_DSW_PWROK, dswpwrok_in);
+ CPRINTS("Pass thru GPIO_DSW_PWROK: %d", dswpwrok_in);
+ dswpwrok_out = dswpwrok_in;
+
+ /*
+ * TODO(b/111810925): Replace this wait with
+ * power_wait_signals_timeout()
+ */
+ /* Now wait 100ms for SLP_SUS_L to go high based on tPCH32 */
+ while (power_has_signals(IN_PCH_SLP_SUS_DEASSERTED) &&
+ (timeout_ms > 0)) {
+ msleep(1);
+ timeout_ms--;
+ }
+ if (!timeout_ms) {
+ CPRINTS("SLP_SUS_L didn't go high! Assuming G3.");
+ return POWER_G3;
+ }
+ 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;
+
+ default:
+ break;
+ }
+
+ return common_intel_x86_power_handle_state(state);
+}
diff --git a/power/icelake.h b/power/icelake.h
new file mode 100644
index 0000000000..f28e1d71dd
--- /dev/null
+++ b/power/icelake.h
@@ -0,0 +1,29 @@
+/* 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 */
+
+#ifndef __CROS_EC_ICELAKE_H
+#define __CROS_EC_ICELAKE_H
+
+/* Input state flags. */
+#define IN_PCH_SLP_S3_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S3_DEASSERTED)
+#define IN_PCH_SLP_S4_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S4_DEASSERTED)
+#define IN_PCH_SLP_SUS_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_SUS_DEASSERTED)
+
+#define IN_ALL_PM_SLP_DEASSERTED (IN_PCH_SLP_S3_DEASSERTED | \
+ IN_PCH_SLP_S4_DEASSERTED | \
+ IN_PCH_SLP_SUS_DEASSERTED)
+
+#define IN_PGOOD_ALL_CORE POWER_SIGNAL_MASK(X86_DSW_DPWROK)
+
+#define IN_ALL_S0 (IN_PGOOD_ALL_CORE | IN_ALL_PM_SLP_DEASSERTED)
+
+#define CHIPSET_G3S5_POWERUP_SIGNAL IN_PCH_SLP_SUS_DEASSERTED
+
+#define CHARGER_INITIALIZED_DELAY_MS 100
+#define CHARGER_INITIALIZED_TRIES 40
+
+#endif /* __CROS_EC_ICELAKE_H */
diff --git a/power/intel_x86.c b/power/intel_x86.c
index f090d784c7..91cd050fa9 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -29,6 +29,8 @@
#include "apollolake.h"
#elif defined(CONFIG_CHIPSET_CANNONLAKE)
#include "cannonlake.h"
+#elif defined(CONFIG_CHIPSET_ICELAKE)
+#include "icelake.h"
#elif defined(CONFIG_CHIPSET_SKYLAKE)
#include "skylake.h"
#endif
@@ -469,7 +471,7 @@ void common_intel_x86_handle_rsmrst(enum power_state state)
/* Only passthrough RSMRST_L de-assertion on power up */
if (rsmrst_in && !power_s5_up)
return;
-#elif defined(CONFIG_CHIPSET_SKYLAKE) || defined(CONFIG_CHIPSET_CANNONLAKE)
+#elif defined(CONFIG_CHIPSET_X86_RSMRST_DELAY)
/*
* Wait at least 10ms between power signals going high
* and deasserting RSMRST to PCH.