power: npcx: add leakage-io support for better power consumption
This CL adds a DT node, 'power_leakage_io', which property, 'leak-gpios', contains GPIOs that have leakage current. In oerder to get better power consumption, npcx power driver will disable the connections between these io pads and input buffers before entering deep sleep. Then, restore the connections after ec wakes up. The users can overwrite this property at board DT file. Here is an example: &power_leakage_io { leak-gpios = <&gpio0 0 0 &gpiob 1 0>; }; Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
parent
9267655f42
commit
8cf0feb3e2
3 changed files with 89 additions and 0 deletions
|
@ -52,6 +52,14 @@
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Dummy node of IOs that have leakage current. The user can override
|
||||||
|
* 'leak-gpios' prop. at board DT file to save more power consumption.
|
||||||
|
*/
|
||||||
|
power_leakage_io: power-leakage-io {
|
||||||
|
compatible = "nuvoton,npcx-leakage-io";
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
soc {
|
soc {
|
||||||
bbram: bb-ram@400af000 {
|
bbram: bb-ram@400af000 {
|
||||||
compatible = "nuvoton,npcx-bbram";
|
compatible = "nuvoton,npcx-bbram";
|
||||||
|
|
16
dts/bindings/pinctrl/nuvoton,npcx-leakage-io.yaml
Normal file
16
dts/bindings/pinctrl/nuvoton,npcx-leakage-io.yaml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (c) 2022 Nuvoton Technology Corporation.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: Nuvoton, NPCX power leakage IOs
|
||||||
|
|
||||||
|
compatible: "nuvoton,npcx-leakage-io"
|
||||||
|
|
||||||
|
include: [base.yaml]
|
||||||
|
|
||||||
|
properties:
|
||||||
|
leak-gpios:
|
||||||
|
type: phandle-array
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
Array of IOs that have leakage current. The user can overwrite this
|
||||||
|
property at the board level DT file to save more power consumption.
|
|
@ -47,10 +47,12 @@
|
||||||
|
|
||||||
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
|
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
|
||||||
#include <zephyr/zephyr.h>
|
#include <zephyr/zephyr.h>
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
#include <zephyr/drivers/espi.h>
|
#include <zephyr/drivers/espi.h>
|
||||||
#include <zephyr/pm/pm.h>
|
#include <zephyr/pm/pm.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
|
|
||||||
|
#include "soc_gpio.h"
|
||||||
#include "soc_host.h"
|
#include "soc_host.h"
|
||||||
#include "soc_power.h"
|
#include "soc_power.h"
|
||||||
|
|
||||||
|
@ -84,6 +86,57 @@ enum {
|
||||||
NPCX_STANDARD_WAKE_UP,
|
NPCX_STANDARD_WAKE_UP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NODE_LEAKAGE_IO DT_INST(0, nuvoton_npcx_leakage_io)
|
||||||
|
#if DT_NODE_HAS_PROP(NODE_LEAKAGE_IO, leak_gpios)
|
||||||
|
struct npcx_leak_gpio {
|
||||||
|
const struct device *gpio;
|
||||||
|
gpio_pin_t pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NPCX_POWER_LEAKAGE_IO_INIT(node_id, prop, idx) { \
|
||||||
|
.gpio = DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx)), \
|
||||||
|
.pin = DT_GPIO_PIN_BY_IDX(node_id, prop, idx), \
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get io array which have leakage current from 'leak-gpios' property of
|
||||||
|
* 'power_leakage_io' DT node. User can overwrite this prop. at board DT file to
|
||||||
|
* save power consumption when ec enter deep sleep.
|
||||||
|
*
|
||||||
|
* &power_leakage_io {
|
||||||
|
* leak-gpios = <&gpio0 0 0
|
||||||
|
* &gpiob 1 0>;
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
static struct npcx_leak_gpio leak_gpios[] = {
|
||||||
|
DT_FOREACH_PROP_ELEM(NODE_LEAKAGE_IO, leak_gpios, NPCX_POWER_LEAKAGE_IO_INIT)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void npcx_power_suspend_leak_io_pads(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(leak_gpios); i++) {
|
||||||
|
npcx_gpio_disable_io_pads(leak_gpios[i].gpio, leak_gpios[i].pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void npcx_power_restore_leak_io_pads(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(leak_gpios); i++) {
|
||||||
|
npcx_gpio_enable_io_pads(leak_gpios[i].gpio, leak_gpios[i].pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void npcx_power_suspend_leak_io_pads(void)
|
||||||
|
{
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
void npcx_power_restore_leak_io_pads(void)
|
||||||
|
{
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
#endif /* DT_NODE_HAS_PROP(NODE_LEAKAGE_IO, leak_gpios) */
|
||||||
|
|
||||||
static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode)
|
static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode)
|
||||||
{
|
{
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
|
@ -99,6 +152,12 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode)
|
||||||
npcx_clock_control_turn_on_system_sleep(slp_mode == NPCX_DEEP_SLEEP,
|
npcx_clock_control_turn_on_system_sleep(slp_mode == NPCX_DEEP_SLEEP,
|
||||||
wk_mode == NPCX_INSTANT_WAKE_UP);
|
wk_mode == NPCX_INSTANT_WAKE_UP);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the connection between io pads that have leakage current and
|
||||||
|
* input buffer to save power consumption.
|
||||||
|
*/
|
||||||
|
npcx_power_suspend_leak_io_pads();
|
||||||
|
|
||||||
/* Turn on eSPI/LPC host access wake-up interrupt. */
|
/* Turn on eSPI/LPC host access wake-up interrupt. */
|
||||||
if (IS_ENABLED(CONFIG_ESPI_NPCX)) {
|
if (IS_ENABLED(CONFIG_ESPI_NPCX)) {
|
||||||
npcx_host_enable_access_interrupt();
|
npcx_host_enable_access_interrupt();
|
||||||
|
@ -129,6 +188,12 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode)
|
||||||
npcx_host_disable_access_interrupt();
|
npcx_host_disable_access_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore the connection between io pads that have leakage current and
|
||||||
|
* input buffer.
|
||||||
|
*/
|
||||||
|
npcx_power_restore_leak_io_pads();
|
||||||
|
|
||||||
/* Turn off system sleep mode. */
|
/* Turn off system sleep mode. */
|
||||||
npcx_clock_control_turn_off_system_sleep();
|
npcx_clock_control_turn_off_system_sleep();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue