summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2020-03-04 12:53:25 -0700
committerCommit Bot <commit-bot@chromium.org>2020-04-09 00:56:31 +0000
commit3b831bbf6ee24a09ef65064d7374e6ef7960eedf (patch)
tree1e60e398e159b257a3cba56bc037844d0b289d84 /power
parent4d39614441258dc5788c2a55000abe56ac43d3fe (diff)
downloadchrome-ec-3b831bbf6ee24a09ef65064d7374e6ef7960eedf.tar.gz
icelake: Cleanup power sequencing for IceLake/TigerLake/JasperLake
Configure PWROK generation related signals for Ice Lake, Tiger Lake, and Jasper Lake SoCs. The array driven sequencing provides better flexibility for the PWROK signals, some of which may be automatically handled by the platform and some require EC control. BUG=b:150726713 BRANCH=none TEST=make buildall TEST=Volteer: verify VCCIN enable and SYS_PWROK generation during S0 and verify signals are deasserted when exiting S0. TEST=Wadledoo: verified 2ms delay between ALL_SYS_PWRGD and PCH_PWROK, verified JPL sequences to S0. Change-Id: Iceae29c65398643839b31f6cd757352282849fda Signed-off-by: Keith Short <keithshort@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2088285 Reviewed-by: Vijay P Hiremath <vijay.p.hiremath@intel.com> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'power')
-rw-r--r--power/icelake.c119
-rw-r--r--power/icelake.h39
2 files changed, 99 insertions, 59 deletions
diff --git a/power/icelake.c b/power/icelake.c
index fe48e22d24..a40395434c 100644
--- a/power/icelake.c
+++ b/power/icelake.c
@@ -83,11 +83,6 @@ __overridable int intel_x86_get_pg_ec_all_sys_pwrgd(void)
return gpio_get_level(GPIO_PG_EC_ALL_SYS_PWRGD);
}
-__overridable void board_jsl_all_sys_pwrgd(int value)
-{
-
-}
-
void chipset_force_shutdown(enum chipset_shutdown_reason reason)
{
int timeout_ms = 50;
@@ -149,16 +144,6 @@ enum power_state chipset_force_g3(void)
return POWER_G3;
}
-/*
- * Ice Lake and Tiger Lake permit PCH_PWROK and SYS_PWROK signals coming
- * up in any order. If the platform needs extra time for peripherals to come
- * up, the board can override this function.
- */
-__overridable void board_icl_tgl_all_sys_pwrgood(void)
-{
-
-}
-
static void enable_pp5000_rail(void)
{
if (IS_ENABLED(CONFIG_POWER_PP5000_CONTROL))
@@ -168,15 +153,6 @@ static void enable_pp5000_rail(void)
}
-#ifdef CONFIG_CHIPSET_JASPERLAKE
-static void assert_ec_ap_vccst_pwrgd_pch_pwrok(void)
-{
- GPIO_SET_LEVEL(GPIO_EC_AP_VCCST_PWRGD_OD, 1);
- GPIO_SET_LEVEL(GPIO_EC_AP_PCH_PWROK_OD, 1);
-}
-DECLARE_DEFERRED(assert_ec_ap_vccst_pwrgd_pch_pwrok);
-#endif /* CONFIG_CHIPSET_JASPERLAKE */
-
static void dsw_pwrok_pass_thru(void)
{
int dswpwrok_in = intel_x86_get_pg_ec_dsw_pwrok();
@@ -207,33 +183,74 @@ static void dsw_pwrok_pass_thru(void)
}
}
-enum power_state power_handle_state(enum power_state state)
+/*
+ * Return 0 if PWROK signal is deasserted, non-zero if asserted
+ */
+static int pwrok_signal_get(const struct intel_x86_pwrok_signal *signal)
+{
+ int level = gpio_get_level(signal->gpio);
+
+ if (signal->active_low)
+ level = !level;
+
+ return level;
+}
+
+/*
+ * 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();
- int all_sys_pwrgd_out;
+ 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 ((!all_sys_pwrgd_in && !pwrok_signal_get(pwrok_signal))
+ || (all_sys_pwrgd_in && pwrok_signal_get(pwrok_signal)))
+ continue;
+
+ 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();
-#ifdef CONFIG_CHIPSET_JASPERLAKE
- /*
- * Set ALL_SYS_PWRGD after receiving both PG_DRAM and PG_PP1050_ST.
- * Assert VCCST power good and PCH_PWROK, when ALL_SYS_PWRGD is
- * received with a 2ms delay minimum.
- */
- if (all_sys_pwrgd_in && !gpio_get_level(GPIO_EC_AP_VCCST_PWRGD_OD)) {
- board_jsl_all_sys_pwrgd(all_sys_pwrgd_in);
- hook_call_deferred(&assert_ec_ap_vccst_pwrgd_pch_pwrok_data,
- 2 * MSEC);
- } else if (!all_sys_pwrgd_in &&
- gpio_get_level(GPIO_EC_AP_VCCST_PWRGD_OD)) {
- GPIO_SET_LEVEL(GPIO_EC_AP_VCCST_PWRGD_OD, 0);
- GPIO_SET_LEVEL(GPIO_EC_AP_PCH_PWROK_OD, 0);
- board_jsl_all_sys_pwrgd(all_sys_pwrgd_in);
- }
-#endif /* CONFIG_CHIPSET_JASPERLAKE */
+ all_sys_pwrgd_pass_thru();
common_intel_x86_handle_rsmrst(state);
@@ -312,22 +329,6 @@ enum power_state power_handle_state(enum power_state state)
break;
#endif /* CONFIG_CHIPSET_JASPERLAKE */
- 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, call board
- * specific handling if provided.
- */
- all_sys_pwrgd_in = intel_x86_get_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)
- board_icl_tgl_all_sys_pwrgood();
- GPIO_SET_LEVEL(GPIO_PCH_SYS_PWROK, all_sys_pwrgd_in);
- }
- break;
-
default:
break;
}
diff --git a/power/icelake.h b/power/icelake.h
index c051a2516a..08c14718ec 100644
--- a/power/icelake.h
+++ b/power/icelake.h
@@ -8,6 +8,8 @@
#ifndef __CROS_EC_ICELAKE_H
#define __CROS_EC_ICELAKE_H
+#include "stdbool.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)
@@ -40,4 +42,41 @@ enum power_signal {
POWER_SIGNAL_COUNT
};
+struct intel_x86_pwrok_signal {
+ enum gpio_signal gpio;
+ bool active_low;
+ int delay_ms;
+};
+
+/*
+ * Ice Lake/Tiger Lake/Jasper Lake PWROK Generation
+ *
+ * The following signals are controlled based on the state of the ALL_SYS_PWRGD
+ * signal
+ *
+ * VCCIN enable (input to the VCCIN voltage rail controller)
+ * VCCST_PWRGD (input to the SoC)
+ * PCH_PWROK (input to the SoC)
+ * SYS_PWROK (input to the SoC)
+ *
+ * For any the above signals that are controlled by the EC, create an entry
+ * in the pwrok_signal_assert_list[] and pwrok_signal_deassert_list[] arrays.
+ * The typical order for asserting the signals is shown above, the deassert
+ * order is the reverse.
+ *
+ * ALL_SYS_PWRGD indicates when all the following are asserted.
+ * RSMRST_PWRGD & DPWROK
+ * S4 voltage rails good (DDR)
+ * VCCST voltage rail good
+ * S0 voltage rails good
+ *
+ * ALL_SYS_PWRGD can be implemented as a single GPIO if the platform power logic
+ * combines the above power good signals. Otherwise your board can override
+ * intel_x86_get_pg_ec_all_sys_pwrgd() to check multiple power good signals.
+ */
+extern const struct intel_x86_pwrok_signal pwrok_signal_assert_list[];
+extern const int pwrok_signal_assert_count;
+extern const struct intel_x86_pwrok_signal pwrok_signal_deassert_list[];
+extern const int pwrok_signal_deassert_count;
+
#endif /* __CROS_EC_ICELAKE_H */