diff options
author | Keith Short <keithshort@chromium.org> | 2022-04-27 09:48:45 -0600 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-04-28 23:37:57 +0000 |
commit | a123436acbb7aa28bf31986beb703a3007c63d85 (patch) | |
tree | 53d8a401cf9fcc0f97381a12abaadd2c7d8fc15e | |
parent | d2e7a65e711220ca1faab4b815b0cf9244ca9ced (diff) | |
download | chrome-ec-a123436acbb7aa28bf31986beb703a3007c63d85.tar.gz |
throttle_ap: Add option to gate PROCHOT based on C10
For some x86 boards, the PROCHOT signal is not valid once the AP enters
the C10 state. Add an option to gate PROCHOT detection if the C10 state
is asserted. When the AP exits C10, the EC rechecks the PROCHOT state.
Note that only the Volteer baseboard enables the PROCHOT interrupt, so
it is the only board that is updated to call
throttle_ap_config_prochot().
All gpio.inc files that connect to throttle_ap_prochot_input_interrupt()
all use the pin name EC_PROCHOT_IN_L. Confirmed with these searches:
$ grep -r "GPIO_INT.*throttle_ap_prochot_input_interrupt" . \
| wc -l
31
$ grep -r "EC_PROCHOT_IN_L.*throttle_ap_prochot_input_interrupt" . \
| wc -l
31
$ grep -r "gpio_enable_interrupt.*EC_PROCHOT_IN_L" .
./baseboard/volteer/power.c: \
gpio_enable_interrupt(GPIO_EC_PROCHOT_IN_L);
BUG=b:185810479
BRANCH=volteer
TEST=make buildall
Signed-off-by: Keith Short <keithshort@chromium.org>
Change-Id: I73fb328675d9faade13fe0192570dc838de028a6
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3615479
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r-- | baseboard/volteer/power.c | 6 | ||||
-rw-r--r-- | common/throttle_ap.c | 62 | ||||
-rw-r--r-- | include/config.h | 8 | ||||
-rw-r--r-- | include/throttle_ap.h | 33 | ||||
-rw-r--r-- | util/config_allowed.txt | 1 | ||||
-rw-r--r-- | zephyr/Kconfig.powerseq | 9 | ||||
-rw-r--r-- | zephyr/shim/include/config_chip.h | 5 |
7 files changed, 112 insertions, 12 deletions
diff --git a/baseboard/volteer/power.c b/baseboard/volteer/power.c index fa20cfa93f..005319c3fa 100644 --- a/baseboard/volteer/power.c +++ b/baseboard/volteer/power.c @@ -6,6 +6,7 @@ #include "gpio.h" #include "hooks.h" #include "power/icelake.h" +#include "throttle_ap.h" /* * PWROK signal configuration, see the PWROK Generation Flow Diagram (Figure @@ -48,9 +49,14 @@ const struct intel_x86_pwrok_signal pwrok_signal_deassert_list[] = { }; const int pwrok_signal_deassert_count = ARRAY_SIZE(pwrok_signal_deassert_list); +static const struct prochot_cfg volteer_prochot_cfg = { + .gpio_prochot_in = GPIO_EC_PROCHOT_IN_L, +}; + static void baseboard_init(void) { /* Enable monitoring of the PROCHOT input to the EC */ + throttle_ap_config_prochot(&volteer_prochot_cfg); gpio_enable_interrupt(GPIO_EC_PROCHOT_IN_L); } DECLARE_HOOK(HOOK_INIT, baseboard_init, HOOK_PRIO_DEFAULT); diff --git a/common/throttle_ap.c b/common/throttle_ap.c index 6d794916ae..33e004ba7b 100644 --- a/common/throttle_ap.c +++ b/common/throttle_ap.c @@ -21,14 +21,20 @@ #define CPUTS(outstr) cputs(CC_THERMAL, outstr) #define CPRINTS(format, args...) cprints(CC_THERMAL, format, ## args) +/* + * When C10 deasserts, PROCHOT may also change state when the corresponding + * power rail is turned back on. Recheck PROCHOT directly from the C10 exit + * using a shorter debounce than the PROCHOT interrupt. + */ #define PROCHOT_IN_DEBOUNCE_US (100 * MSEC) +#define C10_IN_DEBOUNCE_US (10 * MSEC) /*****************************************************************************/ /* This enforces the virtual OR of all throttling sources. */ K_MUTEX_DEFINE(throttle_mutex); static uint32_t throttle_request[NUM_THROTTLE_TYPES]; static int debounced_prochot_in; -static enum gpio_signal gpio_prochot_in = GPIO_COUNT; +static const struct prochot_cfg *prochot_cfg; void throttle_ap(enum throttle_level level, enum throttle_type type, @@ -78,17 +84,36 @@ void throttle_ap(enum throttle_level level, } +void throttle_ap_config_prochot(const struct prochot_cfg *cfg) +{ + prochot_cfg = cfg; +} + +__maybe_unused static bool prochot_is_gated_by_c10(int prochot_in) +{ +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 + int c10_in = gpio_get_level(prochot_cfg->gpio_c10_in); + + if (!prochot_cfg->c10_active_high) + c10_in = !c10_in; + + if (c10_in && prochot_in) { + return true; + } +#endif + return false; +} + static void prochot_input_deferred(void) { int prochot_in; /* - * Shouldn't be possible, but better to protect against buffer - * overflow + * Validate board called throttle_ap_config_prochot(). */ - ASSERT(signal_is_gpio(gpio_prochot_in)); + ASSERT(prochot_cfg); - prochot_in = gpio_get_level(gpio_prochot_in); + prochot_in = gpio_get_level(prochot_cfg->gpio_prochot_in); if (IS_ENABLED(CONFIG_CPU_PROCHOT_ACTIVE_LOW)) prochot_in = !prochot_in; @@ -106,6 +131,14 @@ static void prochot_input_deferred(void) if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) return; + /* + * b/185810479 When the AP enters C10, the PROCHOT signal may not be + * valid. Refer to the CONFIG_CPU_PROCHOT_GATE_ON_C10 documentation + * for details. + */ + if (prochot_is_gated_by_c10(prochot_in)) + return; + debounced_prochot_in = prochot_in; if (debounced_prochot_in) { @@ -126,13 +159,6 @@ DECLARE_DEFERRED(prochot_input_deferred); void throttle_ap_prochot_input_interrupt(enum gpio_signal signal) { /* - * Save the PROCHOT signal that generated the interrupt so we don't - * rely on a specific pin name. - */ - if (gpio_prochot_in == GPIO_COUNT) - gpio_prochot_in = signal; - - /* * Trigger deferred notification of PROCHOT change so we can ignore * any pulses that are too short. */ @@ -140,6 +166,18 @@ void throttle_ap_prochot_input_interrupt(enum gpio_signal signal) PROCHOT_IN_DEBOUNCE_US); } +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 +void throttle_ap_c10_input_interrupt(enum gpio_signal signal) +{ + /* + * This interrupt is configured to fire only when the AP exits C10 + * and de-asserts the C10 signal. Recheck the PROCHOT signal in case + * another PROCHOT source is active when the AP exits C10. + */ + hook_call_deferred(&prochot_input_deferred_data, C10_IN_DEBOUNCE_US); +} +#endif + /*****************************************************************************/ /* Console commands */ #ifdef CONFIG_CMD_APTHROTTLE diff --git a/include/config.h b/include/config.h index 8ba8a4de0c..f7a507655b 100644 --- a/include/config.h +++ b/include/config.h @@ -3623,6 +3623,14 @@ */ #undef CONFIG_CPU_PROCHOT_ACTIVE_LOW +/* + * When the AP enters C10, the power rails VCCIO, VCCSTG, and VCCPLL_OC may be + * turned off by the board. If the PROCHOT# signal is pulled up by any of + * these rails, PROCHOT cannot be relied upon while C10 is active. + * Enable this option to gate PROCHOT detection when C10 is active. + */ +#undef CONFIG_CPU_PROCHOT_GATE_ON_C10 + /* Support PS/2 interface */ #undef CONFIG_PS2 diff --git a/include/throttle_ap.h b/include/throttle_ap.h index fbfa36aed3..09669d70b1 100644 --- a/include/throttle_ap.h +++ b/include/throttle_ap.h @@ -35,6 +35,19 @@ enum throttle_sources { }; /** + * PROCHOT detection GPIOs. PROCHOT in assumed to be active high unless + * CONFIG_CPU_PROCHOT_ACTIVE_LOW is enabled. + * C10 input polarity is explicitly specified in the struct below. + */ +struct prochot_cfg { + enum gpio_signal gpio_prochot_in; +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 + enum gpio_signal gpio_c10_in; + bool c10_active_high; +#endif +}; + +/** * Enable/disable CPU throttling. * * This is a virtual "OR" operation. Any caller can enable CPU throttling of @@ -53,6 +66,14 @@ void throttle_ap(enum throttle_level level, enum throttle_sources source); /** + * Configure the GPIOs used to monitor the PROCHOT signal. + * + * @param cfg GPIO configuration for the PROCHOT and optional C10 + * signals. + */ +void throttle_ap_config_prochot(const struct prochot_cfg *cfg); + +/** * Interrupt handler to monitor PROCHOT input to the EC. The PROCHOT signal * can be asserted by the AP or by other devices on the board, such as chargers * and voltage regulators. @@ -65,6 +86,18 @@ void throttle_ap(enum throttle_level level, */ void throttle_ap_prochot_input_interrupt(enum gpio_signal signal); +/** + * Interrupt handler to monitor the C10 input to the EC. The C10 signal + * can be asserted by the AP when entering an idle state. This interrupt + * is configured for the edge indicating C10 is de-asserting (GPIO_INT_RISING + * if the signal is active low, GPIO_INT_FALLING for an active high signal). + * + * The board initialization is responsible for enabling the interrupt. + * + * @param signal GPIO signal connected to C10 input. + */ +void throttle_ap_c10_input_interrupt(enum gpio_signal signal); + #else static inline void throttle_ap(enum throttle_level level, enum throttle_type type, diff --git a/util/config_allowed.txt b/util/config_allowed.txt index f34197d4b6..d8e6959794 100644 --- a/util/config_allowed.txt +++ b/util/config_allowed.txt @@ -338,6 +338,7 @@ CONFIG_CONSOLE_INPUT_LINE_SIZE CONFIG_CONSOLE_UART CONFIG_CONSOLE_VERBOSE CONFIG_CPU_PROCHOT_ACTIVE_LOW +CONFIG_CPU_PROCHOT_GATE_ON_C10 CONFIG_CRC8 CONFIG_CROS_EC_RO_MEM_SIZE CONFIG_CROS_EC_RW_MEM_SIZE diff --git a/zephyr/Kconfig.powerseq b/zephyr/Kconfig.powerseq index a99453f5a7..cee5be53a4 100644 --- a/zephyr/Kconfig.powerseq +++ b/zephyr/Kconfig.powerseq @@ -104,6 +104,15 @@ config PLATFORM_EC_POWERSEQ_CPU_PROCHOT_ACTIVE_LOW If CPU_PROCHOT should be treated as active-low, enable this configuration option. +config PLATFORM_EC_POWERSEQ_CPU_PROCHOT_GATE_ON_C10 + bool "Gate PROCHOT detection based on the AP C10 state" + default y if PLATFORM_EC_POWERSEQ_CPU_PROCHOT_ACTIVE_LOW + help + When the AP enters C10, the power rails VCCIO, VCCSTG, and VCCPLL_OC + may be turned off by the board. If the PROCHOT# signal is pulled up + by any of these rails, PROCHOT is not valid while the AP is in C10, + Enable this option to gate PROCHOT detection when C10 is active. + config PLATFORM_EC_POWERSEQ_RTC_RESET bool "Board has an RTC reset" help diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index 416e1f397a..ceaaa17193 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -816,6 +816,11 @@ extern struct jump_data mock_jump_data; #define CONFIG_CPU_PROCHOT_ACTIVE_LOW #endif +#undef CONFIG_CPU_PROCHOT_GATE_ON_C10 +#ifdef CONFIG_PLATFORM_EC_POWERSEQ_CPU_PROCHOT_GATE_ON_C10 +#define CONFIG_CPU_PROCHOT_GATE_ON_C10 +#endif + #undef CONFIG_POWER_TRACK_HOST_SLEEP_STATE #if defined(CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP) || \ defined(CONFIG_AP_PWRSEQ_HOST_SLEEP) |