summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2021-04-24 14:26:16 -0600
committerCommit Bot <commit-bot@chromium.org>2021-04-29 18:34:01 +0000
commit13a437909f984da73327a8e4ce6ed8adb0ccdce6 (patch)
tree2091a3e14d33ae6bf9bc390f7cb450304ff7fbc4
parent85ea1cd0acb35b141d9f5deef26ff96e32d87365 (diff)
downloadchrome-ec-13a437909f984da73327a8e4ce6ed8adb0ccdce6.tar.gz
zephyr: npcx: Add power management support
Add power management support for the NPCX family. BUG=b:184653704 BRANCH=none TEST=zmake testall TEST=Verify deep sleep on Volteer (with next CL) and measure power. Signed-off-by: Keith Short <keithshort@chromium.org> Change-Id: I86eef50c13742e7ca717da38a92636e589af6c58 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2855527 Reviewed-by: Wealian Liao <whliao@nuvoton.corp-partner.google.com>
-rw-r--r--zephyr/Kconfig.stacks2
-rw-r--r--zephyr/drivers/cros_system/cros_system_npcx.c9
-rw-r--r--zephyr/include/cros/nuvoton/npcx.dtsi19
-rw-r--r--zephyr/include/drivers/cros_system.h29
-rw-r--r--zephyr/shim/chip/npcx/CMakeLists.txt1
-rw-r--r--zephyr/shim/chip/npcx/power_policy.c39
-rw-r--r--zephyr/shim/src/system.c22
7 files changed, 120 insertions, 1 deletions
diff --git a/zephyr/Kconfig.stacks b/zephyr/Kconfig.stacks
index 48020d4c51..0efe1c008d 100644
--- a/zephyr/Kconfig.stacks
+++ b/zephyr/Kconfig.stacks
@@ -7,7 +7,7 @@ if SOC_SERIES_NPCX7
# Zephyr internal stack sizes
config IDLE_STACK_SIZE
- default 128
+ default 192
config ISR_STACK_SIZE
default 1024
diff --git a/zephyr/drivers/cros_system/cros_system_npcx.c b/zephyr/drivers/cros_system/cros_system_npcx.c
index d814a8967f..c5b8e1a2f8 100644
--- a/zephyr/drivers/cros_system/cros_system_npcx.c
+++ b/zephyr/drivers/cros_system/cros_system_npcx.c
@@ -515,6 +515,12 @@ static int cros_system_npcx_hibernate(const struct device *dev,
return 0;
}
+__maybe_unused static uint64_t
+cros_system_npcx_deep_sleep_ticks(const struct device *dev)
+{
+ return npcx_clock_get_sleep_ticks();
+}
+
static struct cros_system_npcx_data cros_system_npcx_dev_data;
static const struct cros_system_npcx_config cros_system_dev_cfg = {
@@ -531,6 +537,9 @@ static const struct cros_system_driver_api cros_system_driver_npcx_api = {
.chip_vendor = cros_system_npcx_get_chip_vendor,
.chip_name = cros_system_npcx_get_chip_name,
.chip_revision = cros_system_npcx_get_chip_revision,
+#ifdef CONFIG_SOC_POWER_MANAGEMENT_TRACE
+ .deep_sleep_ticks = cros_system_npcx_deep_sleep_ticks,
+#endif
};
DEVICE_DEFINE(cros_system_npcx_0, "CROS_SYSTEM", cros_system_npcx_init, NULL,
diff --git a/zephyr/include/cros/nuvoton/npcx.dtsi b/zephyr/include/cros/nuvoton/npcx.dtsi
index 62f4b6b861..8251a34ade 100644
--- a/zephyr/include/cros/nuvoton/npcx.dtsi
+++ b/zephyr/include/cros/nuvoton/npcx.dtsi
@@ -98,4 +98,23 @@
};
};
+ power-states {
+ suspend_to_idle_instant: suspend_to_idle_instant {
+ compatible = "zephyr,power-state";
+ power-state-name = "suspend-to-idle";
+ substate-id = <0>;
+ min-residency-us = <500>;
+ };
+
+ suspend_to_idle_normal: suspend_to_idle_normal {
+ compatible = "zephyr,power-state";
+ power-state-name = "suspend-to-idle";
+ substate-id = <1>;
+ min-residency-us = <200100>;
+ };
+ };
+};
+
+&cpu0 {
+ cpu-power-states = <&suspend_to_idle_instant &suspend_to_idle_normal>;
};
diff --git a/zephyr/include/drivers/cros_system.h b/zephyr/include/drivers/cros_system.h
index fcd3ef3b6a..77b1174e26 100644
--- a/zephyr/include/drivers/cros_system.h
+++ b/zephyr/include/drivers/cros_system.h
@@ -82,6 +82,13 @@ typedef const char *(*cros_system_chip_name_api)(const struct device *dev);
*/
typedef const char *(*cros_system_chip_revision_api)(const struct device *dev);
+/**
+ * @typedef cros_system_get_deep_sleep_ticks_api
+ * @brief Callback API for getting number of ticks spent in deep sleep.
+ * See cros_system_deep_sleep_ticks() for argument descriptions
+ */
+typedef uint64_t (*cros_system_deep_sleep_ticks_api)(const struct device *dev);
+
/** @brief Driver API structure. */
__subsystem struct cros_system_driver_api {
cros_system_get_reset_cause_api get_reset_cause;
@@ -90,6 +97,7 @@ __subsystem struct cros_system_driver_api {
cros_system_chip_vendor_api chip_vendor;
cros_system_chip_name_api chip_name;
cros_system_chip_revision_api chip_revision;
+ cros_system_deep_sleep_ticks_api deep_sleep_ticks;
};
/**
@@ -229,6 +237,27 @@ z_impl_cros_system_chip_revision(const struct device *dev)
}
/**
+ * @brief Get total number of ticks spent in deep sleep.
+ *
+ * @param dev Pointer to the device structure for the driver instance.
+ * @retval Number of ticks spent in deep sleep.
+ */
+__syscall uint64_t cros_system_deep_sleep_ticks(const struct device *dev);
+
+static inline uint64_t
+z_impl_cros_system_deep_sleep_ticks(const struct device *dev)
+{
+ const struct cros_system_driver_api *api =
+ (const struct cros_system_driver_api *)dev->api;
+
+ if (!api->deep_sleep_ticks) {
+ return 0;
+ }
+
+ return api->deep_sleep_ticks(dev);
+}
+
+/**
* @}
*/
#include <syscalls/cros_system.h>
diff --git a/zephyr/shim/chip/npcx/CMakeLists.txt b/zephyr/shim/chip/npcx/CMakeLists.txt
index 86b7a9ae2f..79d81f720e 100644
--- a/zephyr/shim/chip/npcx/CMakeLists.txt
+++ b/zephyr/shim/chip/npcx/CMakeLists.txt
@@ -12,3 +12,4 @@ zephyr_library_sources_ifdef(CONFIG_CROS_EC system.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_EXTERNAL_STORAGE
system_external_storage.c)
+zephyr_library_sources_ifdef(CONFIG_PM_POLICY_APP power_policy.c)
diff --git a/zephyr/shim/chip/npcx/power_policy.c b/zephyr/shim/chip/npcx/power_policy.c
new file mode 100644
index 0000000000..e3f280438f
--- /dev/null
+++ b/zephyr/shim/chip/npcx/power_policy.c
@@ -0,0 +1,39 @@
+/* Copyright 2021 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.
+ */
+
+#include <zephyr.h>
+#include <power/power.h>
+#include <soc.h>
+
+#include "console.h"
+#include "system.h"
+
+static const struct pm_state_info pm_min_residency[] =
+ PM_STATE_INFO_DT_ITEMS_LIST(DT_NODELABEL(cpu0));
+
+/* CROS PM policy handler */
+struct pm_state_info pm_policy_next_state(int32_t ticks)
+{
+ /* Deep sleep is allowed and console is not in use. */
+ if (DEEP_SLEEP_ALLOWED != 0 && !npcx_power_console_is_in_use()) {
+ for (int i = ARRAY_SIZE(pm_min_residency) - 1; i >= 0; i--) {
+ /* Find suitable power state by residency time */
+ if (ticks == K_TICKS_FOREVER ||
+ ticks >= k_us_to_ticks_ceil32(
+ pm_min_residency[i]
+ .min_residency_us)) {
+ return pm_min_residency[i];
+ }
+ }
+ }
+
+ return (struct pm_state_info){ PM_STATE_ACTIVE, 0, 0 };
+}
+
+/* CROS PM device policy handler */
+bool pm_policy_low_power_devices(enum pm_state state)
+{
+ return pm_is_sleep_state(state);
+}
diff --git a/zephyr/shim/src/system.c b/zephyr/shim/src/system.c
index c8b5c81341..4984759602 100644
--- a/zephyr/shim/src/system.c
+++ b/zephyr/shim/src/system.c
@@ -10,6 +10,7 @@
#include "bbram.h"
#include "common.h"
+#include "console.h"
#include "cros_version.h"
#include "system.h"
#include "watchdog.h"
@@ -105,6 +106,27 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds)
continue;
}
+#ifdef CONFIG_PM
+/**
+ * Print low power idle statistics
+ */
+static int command_idle_stats(int argc, char **argv)
+{
+ const struct device *sys_dev = device_get_binding("CROS_SYSTEM");
+
+ timestamp_t ts = get_time();
+ uint64_t deep_sleep_ticks = cros_system_deep_sleep_ticks(sys_dev);
+
+ ccprintf("Time spent in deep-sleep: %.6llds\n",
+ k_ticks_to_us_near64(deep_sleep_ticks));
+ ccprintf("Total time on: %.6llds\n", ts.val);
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats,
+ "",
+ "Print last idle stats");
+#endif
+
const char *system_get_chip_vendor(void)
{
const struct device *sys_dev = device_get_binding("CROS_SYSTEM");