diff --git a/drivers/gpio/gpio_mspm0.c b/drivers/gpio/gpio_mspm0.c index bc95845865f06..7ac165aaf73fe 100644 --- a/drivers/gpio/gpio_mspm0.c +++ b/drivers/gpio/gpio_mspm0.c @@ -158,6 +158,8 @@ static int gpio_mspm0_pin_configure(const struct device *port, gpio_flags_t flags) { const struct gpio_mspm0_config *config = port->config; + DL_GPIO_WAKEUP wakeup = DL_GPIO_WAKEUP_DISABLE; + /* determine pull up resistor value based on flags */ DL_GPIO_RESISTOR pull_res; @@ -169,14 +171,25 @@ static int gpio_mspm0_pin_configure(const struct device *port, pull_res = DL_GPIO_RESISTOR_NONE; } + if (flags & GPIO_INT_WAKEUP) { + if (flags & GPIO_ACTIVE_LOW) { + wakeup = DL_GPIO_WAKEUP_ON_0; + } else { + wakeup = DL_GPIO_WAKEUP_ON_1; + } + } + /* Config pin based on flags */ switch (flags & (GPIO_INPUT | GPIO_OUTPUT)) { case GPIO_INPUT: + if (wakeup != DL_GPIO_WAKEUP_DISABLE) { + DL_GPIO_enableFastWakePins(config->base, BIT(pin)); + } DL_GPIO_initDigitalInputFeatures(config->pincm_lut[pin], DL_GPIO_INVERSION_DISABLE, pull_res, DL_GPIO_HYSTERESIS_DISABLE, - DL_GPIO_WAKEUP_DISABLE); + wakeup); DL_GPIO_disableOutput(config->base, BIT(pin)); break; case GPIO_OUTPUT: @@ -198,6 +211,9 @@ static int gpio_mspm0_pin_configure(const struct device *port, DL_GPIO_enableOutput(config->base, BIT(pin)); break; case GPIO_DISCONNECTED: + if (wakeup != DL_GPIO_WAKEUP_DISABLE) { + DL_GPIO_disableWakeUp(config->pincm_lut[pin]); + } DL_GPIO_disableOutput(config->base, BIT(pin)); break; default: diff --git a/dts/arm/ti/mspm0/g/mspm0g.dtsi b/dts/arm/ti/mspm0/g/mspm0g.dtsi index d599264866148..d7951ffa9edcd 100644 --- a/dts/arm/ti/mspm0/g/mspm0g.dtsi +++ b/dts/arm/ti/mspm0/g/mspm0g.dtsi @@ -106,3 +106,38 @@ }; }; }; + +&run1 { + exit-latency-us = <2>; /* 1.5us */ + min-residency-us = <5000>; +}; + +&run2 { + exit-latency-us = <3>; /* 2.1us */ + min-residency-us = <5000>; +}; + +&stop0 { + exit-latency-us = <13>; /* 12.1us */ + min-residency-us = <7500>; +}; + +&stop1 { + exit-latency-us = <14>; /* 13.5us */ + min-residency-us = <7500>; +}; + +&stop2 { + exit-latency-us = <13>; /* 12.9us */ + min-residency-us = <7500>; +}; + +&stdby0 { + exit-latency-us = <16>; /* 15.2us */ + min-residency-us = <10000>; +}; + +&stdby1 { + exit-latency-us = <16>; /* 15.2us */ + min-residency-us = <10000>; +}; diff --git a/dts/arm/ti/mspm0/l/mspm0l.dtsi b/dts/arm/ti/mspm0/l/mspm0l.dtsi index 9cf266adc8023..33c2e0ea626b6 100644 --- a/dts/arm/ti/mspm0/l/mspm0l.dtsi +++ b/dts/arm/ti/mspm0/l/mspm0l.dtsi @@ -17,3 +17,43 @@ #gpio-cells = <2>; }; }; + +&run0 { + exit-latency-us = <2>; /* 1.5us */ + min-residency-us = <5000>; +}; + +&run1 { + exit-latency-us = <3>; /* 2.1us */ + min-residency-us = <5000>; +}; + +&run2 { + exit-latency-us = <3>; /* 2.5us */ + min-residency-us = <5000>; +}; + +&stop0 { + exit-latency-us = <13>; /* 12.5us */ + min-residency-us = <7500>; +}; + +&stop1 { + exit-latency-us = <15>; /* 14.6us */ + min-residency-us = <7500>; +}; + +&stop2 { + exit-latency-us = <14>; /* 13.5us */ + min-residency-us = <7500>; +}; + +&stdby0 { + exit-latency-us = <16>; /* 15.7us */ + min-residency-us = <10000>; +}; + +&stdby1 { + exit-latency-us = <16>; /* 15.7us */ + min-residency-us = <10000>; +}; diff --git a/dts/arm/ti/mspm0/mspm0.dtsi b/dts/arm/ti/mspm0/mspm0.dtsi index 3cb4047b210e4..c74dda4d6257f 100644 --- a/dts/arm/ti/mspm0/mspm0.dtsi +++ b/dts/arm/ti/mspm0/mspm0.dtsi @@ -20,6 +20,59 @@ reg = <0>; #address-cells = <1>; #size-cells = <1>; + cpu-power-states = <&run0 &run1 &run2 + &stop0 &stop1 &stop2 + &stdby0 &stdby1>; + }; + + power-states { + run0: runsleep0 { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + substate-id = <1>; + }; + + run1: runsleep1 { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + substate-id = <2>; + }; + + run2: runsleep2 { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + substate-id = <3>; + }; + + stop0: stop0 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + substate-id = <1>; + }; + + stop1: stop1 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + substate-id = <2>; + }; + + stop2: stop2 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + substate-id = <3>; + }; + + stdby0: standby0 { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + substate-id = <1>; + }; + + stdby1: standby1 { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + substate-id = <2>; + }; }; }; diff --git a/soc/ti/mspm0/Kconfig b/soc/ti/mspm0/Kconfig index 3c1293fb9eb0f..13e17cdbdfd7e 100644 --- a/soc/ti/mspm0/Kconfig +++ b/soc/ti/mspm0/Kconfig @@ -15,4 +15,8 @@ config MSPM0_PERIPH_STARTUP_DELAY int default 8 +config HWINFO + bool + default y if POWEROFF + endif # SOC_FAMILY_TI_MSPM0 diff --git a/soc/ti/mspm0/common/CMakeLists.txt b/soc/ti/mspm0/common/CMakeLists.txt index 956e8a013950c..b2dccf18da16b 100644 --- a/soc/ti/mspm0/common/CMakeLists.txt +++ b/soc/ti/mspm0/common/CMakeLists.txt @@ -2,3 +2,6 @@ zephyr_sources(soc.c) zephyr_include_directories(.) + +zephyr_sources_ifdef(CONFIG_PM power.c) +zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) diff --git a/soc/ti/mspm0/common/power.c b/soc/ti/mspm0/common/power.c new file mode 100644 index 0000000000000..46332db67ec34 --- /dev/null +++ b/soc/ti/mspm0/common/power.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2025 Linumiz GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +static void set_mode_run(uint8_t state) +{ + switch (state) { + case DL_SYSCTL_POWER_POLICY_RUN_SLEEP0: + DL_SYSCTL_setPowerPolicyRUN0SLEEP0(); + break; + case DL_SYSCTL_POWER_POLICY_RUN_SLEEP1: + DL_SYSCTL_setPowerPolicyRUN1SLEEP1(); + break; + case DL_SYSCTL_POWER_POLICY_RUN_SLEEP2: + DL_SYSCTL_setPowerPolicyRUN2SLEEP2(); + break; + } +} + +static void set_mode_stop(uint8_t state) +{ + switch (state) { + case DL_SYSCTL_POWER_POLICY_STOP0: + DL_SYSCTL_setPowerPolicySTOP0(); + break; + case DL_SYSCTL_POWER_POLICY_STOP1: + DL_SYSCTL_setPowerPolicySTOP1(); + break; + case DL_SYSCTL_POWER_POLICY_STOP2: + DL_SYSCTL_setPowerPolicySTOP2(); + break; + } +} + +static void set_mode_standby(uint8_t state) +{ + switch (state) { + case DL_SYSCTL_POWER_POLICY_STANDBY0: + DL_SYSCTL_setPowerPolicySTANDBY0(); + break; + case DL_SYSCTL_POWER_POLICY_STANDBY1: + DL_SYSCTL_setPowerPolicySTANDBY1(); + break; + } +} + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + switch (state) { + case PM_STATE_RUNTIME_IDLE: + set_mode_run(substate_id); + break; + case PM_STATE_SUSPEND_TO_IDLE: + set_mode_stop(substate_id); + break; + case PM_STATE_STANDBY: + set_mode_standby(substate_id); + break; + default: + LOG_DBG("Unsupported power state %u", state); + return; + } + + __WFI(); +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + DL_SYSCTL_setPowerPolicyRUN0SLEEP0(); + irq_unlock(0); +} diff --git a/soc/ti/mspm0/common/poweroff.c b/soc/ti/mspm0/common/poweroff.c new file mode 100644 index 0000000000000..c98676f3f54c5 --- /dev/null +++ b/soc/ti/mspm0/common/poweroff.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Linumiz GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +void z_sys_poweroff(void) +{ + DL_SYSCTL_setPowerPolicySHUTDOWN(); + __WFI(); + + CODE_UNREACHABLE; +} + +static int ti_mspm0_poweroff_init(void) +{ + int ret; + uint32_t rst_cause; + + ret = hwinfo_get_reset_cause(&rst_cause); + if (ret != 0) { + return ret; + } + + if (RESET_LOW_POWER_WAKE == rst_cause) { + DL_SYSCTL_releaseShutdownIO(); + } + + return 0; +} + +SYS_INIT(ti_mspm0_poweroff_init, POST_KERNEL, 0); diff --git a/soc/ti/mspm0/mspm0g/Kconfig b/soc/ti/mspm0/mspm0g/Kconfig index 8a0241246d41c..49148c8f34a6a 100644 --- a/soc/ti/mspm0/mspm0g/Kconfig +++ b/soc/ti/mspm0/mspm0g/Kconfig @@ -13,5 +13,7 @@ config SOC_SERIES_MSPM0G select BUILD_OUTPUT_BIN select BUILD_OUTPUT_HEX select HAS_MSPM0_SDK + select HAS_PM + select HAS_POWEROFF select CLOCK_CONTROL select SOC_EARLY_INIT_HOOK diff --git a/soc/ti/mspm0/mspm0l/Kconfig b/soc/ti/mspm0/mspm0l/Kconfig index 9693c0d5186d2..7a566a530e55f 100644 --- a/soc/ti/mspm0/mspm0l/Kconfig +++ b/soc/ti/mspm0/mspm0l/Kconfig @@ -12,6 +12,8 @@ config SOC_SERIES_MSPM0L select BUILD_OUTPUT_BIN select BUILD_OUTPUT_HEX select HAS_MSPM0_SDK + select HAS_PM + select HAS_POWEROFF select CLOCK_CONTROL select SOC_EARLY_INIT_HOOK diff --git a/west.yml b/west.yml index a564256794447..6275936279012 100644 --- a/west.yml +++ b/west.yml @@ -260,7 +260,7 @@ manifest: groups: - hal - name: hal_ti - revision: 391f7cb740b59c077ddd49411f043161597b10aa + revision: d0628446c830c25522bd1999234a77b4841016fa path: modules/hal/ti groups: - hal