summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2022-04-27 09:48:45 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-04-28 23:37:57 +0000
commita123436acbb7aa28bf31986beb703a3007c63d85 (patch)
tree53d8a401cf9fcc0f97381a12abaadd2c7d8fc15e /common
parentd2e7a65e711220ca1faab4b815b0cf9244ca9ced (diff)
downloadchrome-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>
Diffstat (limited to 'common')
-rw-r--r--common/throttle_ap.c62
1 files changed, 50 insertions, 12 deletions
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