summaryrefslogtreecommitdiff
path: root/common/throttle_ap.c
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2013-09-06 13:01:48 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-09-11 01:49:48 +0000
commit793b52f327b20ee5897dc04093ac30a5d000d6e9 (patch)
treeb85f745c8c3f0d3d877733d18caadb626e56927b /common/throttle_ap.c
parente6401d2e83939a63cbd156fa193f9768063d9325 (diff)
downloadchrome-ec-793b52f327b20ee5897dc04093ac30a5d000d6e9.tar.gz
Handle multiple independent sources and types of CPU throttling
Depending on the system, the AP can be throttled in at least two different ways - politely, where it's just asked to slow down a bit, and forcefully using a hardware signal (like PROCHOT). In addition, the request for throttling can come from multiple tasks. This CL provides a single interface, specifying both the type of throttling desired and the source of the throttling request. For each type, any source can can start throttling, but all sources must agree before it stops. The changes are protected by a mutex, so that requests from multiple tasks don't interfere with each other. BUG=chrome-os-partner:20739,chromium:287985,chromium:287983 BRANCH=ToT TEST=manual Build-time test: cd src/platform/ec make BOARD=falco runtests Run-time test: Lower the temp thresholds, turn the fan off, and watch the throttling turn off and on as things heat up. For example, on the EC console: > temps PECI : 339 K = 66 C ECInternal : 324 K = 51 C G781Internal : 328 K = 55 C G781External : 327 K = 54 C > thermalset 0 341 343 sensor warn high halt fan_off fan_max name 0 341 343 383 333 363 PECI 1 0 0 0 0 0 ECInternal 2 0 0 0 0 0 G781Internal 3 0 0 0 0 0 G781External > > temps PECI : 339 K = 66 C ECInternal : 324 K = 51 C G781Internal : 328 K = 55 C G781External : 327 K = 54 C > > fanduty 0 Setting fan duty cycle to 0% > > apthrottle AP throttling type 0 is off (0x00000000) AP throttling type 1 is off (0x00000000) > [430.152000 thermal WARN] [430.152233 event set 0x00020000] [430.152497 event clear 0x00020000] [430.152714 ACPI query = 18] [430.152444 sci 0x00020000] [430.153051 set AP throttling type 0 to on (0x00000001)] > gpioget CPU_PROCHOT 0 CPU_PROCHOT > [436.153742 thermal HIGH] [436.153979 set AP throttling type 1 to on (0x00000001)] > gpioget CPU_PROCHOT 1* CPU_PROCHOT > [441.155319 thermal no longer high] [441.155587 set AP throttling type 1 to off (0x00000000)] [442.155604 thermal HIGH] [442.155841 set AP throttling type 1 to on (0x00000001)] [446.156623 thermal no longer high] [446.156890 set AP throttling type 1 to off (0x00000000)] temps PECI : 343 K = 70 C ECInternal : 324 K = 51 C G781Internal : 328 K = 55 C G781External : 327 K = 54 C > [447.156827 thermal HIGH] [447.157064 set AP throttling type 1 to on (0x00000001)] apthrottle AP throttling type 0 is on (0x00000001) AP throttling type 1 is on (0x00000001) > gpioget CPU_PROCHOT 1 CPU_PROCHOT > Now turn the fan back on: > fanauto > [456.159306 thermal no longer high] [456.159574 set AP throttling type 1 to off (0x00000000)] > apthrottle AP throttling type 0 is on (0x00000001) AP throttling type 1 is off (0x00000000) > temps PECI : 341 K = 68 C ECInternal : 324 K = 51 C G781Internal : 328 K = 55 C G781External : 327 K = 54 C > [473.163905 thermal no longer warn] [473.164168 event set 0x00040000] [473.164453 event clear 0x00040000] [473.164670 ACPI query = 19] [473.164379 sci 0x00040000] [473.164987 set AP throttling type 0 to off (0x00000000)] temps PECI : 340 K = 67 C ECInternal : 324 K = 51 C G781Internal : 328 K = 55 C G781External : 327 K = 54 C > > apthrottle AP throttling type 0 is off (0x00000000) AP throttling type 1 is off (0x00000000) > Change-Id: I9ee1491a637d7766395c71e57483fbd9177ea554 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/168802
Diffstat (limited to 'common/throttle_ap.c')
-rw-r--r--common/throttle_ap.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/common/throttle_ap.c b/common/throttle_ap.c
new file mode 100644
index 0000000000..0c671842db
--- /dev/null
+++ b/common/throttle_ap.c
@@ -0,0 +1,96 @@
+/* Copyright (c) 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 chipset throttling code for Chrome EC */
+
+#include "chipset.h"
+#include "common.h"
+#include "console.h"
+#include "host_command.h"
+#include "task.h"
+#include "throttle_ap.h"
+#include "util.h"
+
+/* Console output macros */
+#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
+#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
+
+/*****************************************************************************/
+/* This enforces the virtual OR of all throttling sources. */
+static struct mutex throttle_mutex;
+static uint32_t throttle_request[NUM_THROTTLE_TYPES];
+
+void throttle_ap(enum throttle_level level,
+ enum throttle_type type,
+ enum throttle_sources source)
+{
+ uint32_t tmpval, bitmask;
+
+ mutex_lock(&throttle_mutex);
+
+ bitmask = (1 << source);
+
+ switch (level) {
+ case THROTTLE_ON:
+ throttle_request[type] |= bitmask;
+ break;
+ case THROTTLE_OFF:
+ throttle_request[type] &= ~bitmask;
+ break;
+ }
+
+ tmpval = throttle_request[type]; /* save for printing */
+
+ switch (type) {
+ case THROTTLE_SOFT:
+#ifdef HAS_TASK_HOSTCMD
+ host_throttle_cpu(tmpval);
+#endif
+ break;
+ case THROTTLE_HARD:
+#ifdef CONFIG_CHIPSET_CAN_THROTTLE
+ chipset_throttle_cpu(tmpval);
+#endif
+ break;
+
+ case NUM_THROTTLE_TYPES:
+ /* Make the compiler shut up. Don't use 'default', because
+ * we still want to catch any new types.
+ */
+ break;
+ }
+
+ mutex_unlock(&throttle_mutex);
+
+ /* print outside the mutex */
+ CPRINTF("[%T set AP throttling type %d to %s (0x%08x)]\n",
+ type, tmpval ? "on" : "off", tmpval);
+
+}
+
+/*****************************************************************************/
+/* Console commands */
+
+static int command_apthrottle(int argc, char **argv)
+{
+ int i;
+ uint32_t tmpval;
+
+ for (i = 0; i < NUM_THROTTLE_TYPES; i++) {
+ mutex_lock(&throttle_mutex);
+ tmpval = throttle_request[i];
+ mutex_unlock(&throttle_mutex);
+
+ ccprintf("AP throttling type %d is %s (0x%08x)\n", i,
+ tmpval ? "on" : "off", tmpval);
+ }
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(apthrottle, command_apthrottle,
+ NULL,
+ "Display the AP throttling state",
+ NULL);
+