soc: nxp: ke1xz: Add power management support
Implement power management with IDLE, STOP, PSTOP1, and PSTOP2 modes. - Add power state definitions with timing parameters - Implement pm_state_set() with proper SLEEPDEEP handling - Add XIP-safe WFI execution from RAM - Enable SMC driver and power mode protection - Remove forced timer Kconfig defaults Signed-off-by: Holt Sun <holt.sun@nxp.com>
This commit is contained in:
@@ -26,31 +26,40 @@
|
||||
compatible = "arm,cortex-m0+";
|
||||
clock-frequency = <DT_FREQ_M(48)>;
|
||||
reg = <0>;
|
||||
cpu-power-states = <&idle &stop &pstop1 &pstop2>;
|
||||
cpu-power-states = <&idle &pstop2 &pstop1 &stop>;
|
||||
};
|
||||
|
||||
power-states {
|
||||
idle: idle {
|
||||
compatible = "zephyr,power-state";
|
||||
power-state-name = "runtime-idle";
|
||||
min-residency-us = <10>;
|
||||
/* 0.7 µs rounded */
|
||||
exit-latency-us = <1>;
|
||||
};
|
||||
|
||||
stop: stop {
|
||||
compatible = "zephyr,power-state";
|
||||
power-state-name = "suspend-to-idle";
|
||||
substate-id = <0>;
|
||||
min-residency-us = <14>;
|
||||
exit-latency-us = <140>;
|
||||
};
|
||||
|
||||
pstop1: pstop1 {
|
||||
compatible = "zephyr,power-state";
|
||||
power-state-name = "suspend-to-idle";
|
||||
substate-id = <1>;
|
||||
min-residency-us = <13>;
|
||||
exit-latency-us = <130>;
|
||||
};
|
||||
|
||||
pstop2: pstop2 {
|
||||
compatible = "zephyr,power-state";
|
||||
power-state-name = "suspend-to-idle";
|
||||
substate-id = <2>;
|
||||
min-residency-us = <12>;
|
||||
exit-latency-us = <120>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -69,6 +69,7 @@ set_variable_ifdef(CONFIG_ENTROPY_MCUX_TRNG CONFIG_MCUX_COMPONENT_driver.trn
|
||||
set_variable_ifdef(CONFIG_ENTROPY_MCUX_CAAM CONFIG_MCUX_COMPONENT_driver.caam)
|
||||
set_variable_ifdef(CONFIG_ETH_NXP_ENET CONFIG_MCUX_COMPONENT_driver.enet)
|
||||
set_variable_ifdef(CONFIG_SOC_SERIES_KINETIS_K2X CONFIG_MCUX_COMPONENT_driver.smc)
|
||||
set_variable_ifdef(CONFIG_SOC_SERIES_KE1XZ CONFIG_MCUX_COMPONENT_driver.smc)
|
||||
set_variable_ifdef(CONFIG_I2C_MCUX CONFIG_MCUX_COMPONENT_driver.i2c)
|
||||
set_variable_ifdef(CONFIG_I2C_NXP_II2C CONFIG_MCUX_COMPONENT_driver.ii2c)
|
||||
set_variable_ifdef(CONFIG_I3C_MCUX CONFIG_MCUX_COMPONENT_driver.i3c)
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
# Kinetis KE1xZ series configuration options
|
||||
|
||||
# Copyright (c) 2019-2021 Vestas Wind Systems A/S
|
||||
# Copyright 2024 NXP
|
||||
# Copyright 2024-2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if SOC_SERIES_KE1XZ
|
||||
|
||||
config MCUX_LPTMR_TIMER
|
||||
default y if PM
|
||||
|
||||
config CORTEX_M_SYSTICK
|
||||
default n if MCUX_LPTMR_TIMER
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK
|
||||
default $(dt_node_int_prop_int,/soc/lptmr@40040000,clock-frequency) if MCUX_LPTMR_TIMER
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Vestas Wind Systems A/S
|
||||
* Copyright 2021, 2024 NXP
|
||||
* Copyright 2021, 2024-2025 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
LOG_MODULE_DECLARE(power, CONFIG_PM_LOG_LEVEL);
|
||||
|
||||
__ramfunc static void wait_for_flash_prefetch_and_idle(void)
|
||||
#ifdef CONFIG_XIP
|
||||
__ramfunc static void wait_for_flash_prefetch_and_wfi(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
@@ -20,27 +21,54 @@ __ramfunc static void wait_for_flash_prefetch_and_idle(void)
|
||||
arch_nop();
|
||||
}
|
||||
|
||||
k_cpu_idle();
|
||||
/*
|
||||
* Must execute WFI directly from RAM when XIP is enabled.
|
||||
* Calling k_cpu_idle() may jump back into flash.
|
||||
*/
|
||||
__DSB();
|
||||
__ISB();
|
||||
__WFI();
|
||||
}
|
||||
#endif /* CONFIG_XIP */
|
||||
|
||||
void pm_state_set(enum pm_state state, uint8_t substate_id)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_STATE_RUNTIME_IDLE:
|
||||
k_cpu_idle();
|
||||
/* Normal WAIT: WFI with SLEEPDEEP cleared. */
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
__DSB();
|
||||
__ISB();
|
||||
__WFI();
|
||||
irq_unlock(0);
|
||||
break;
|
||||
case PM_STATE_SUSPEND_TO_IDLE:
|
||||
/* Set partial stop mode and enable deep sleep */
|
||||
SMC->STOPCTRL = SMC_STOPCTRL_PSTOPO(substate_id);
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
if (IS_ENABLED(CONFIG_XIP)) {
|
||||
wait_for_flash_prefetch_and_idle();
|
||||
} else {
|
||||
k_cpu_idle();
|
||||
if (substate_id > 2U) {
|
||||
LOG_WRN("Unsupported substate-id %u, using 0", substate_id);
|
||||
substate_id = 0U;
|
||||
}
|
||||
/* Ensure STOPM is set to normal STOP (not VLPS/VLLS families), if present. */
|
||||
SMC->PMCTRL &= ~SMC_PMCTRL_STOPM_MASK;
|
||||
|
||||
#if (defined(FSL_FEATURE_SMC_HAS_PSTOPO) && FSL_FEATURE_SMC_HAS_PSTOPO)
|
||||
SMC->STOPCTRL = (SMC->STOPCTRL & ~SMC_STOPCTRL_PSTOPO_MASK) |
|
||||
SMC_STOPCTRL_PSTOPO(substate_id);
|
||||
#endif
|
||||
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
/* readback to complete bus writes */
|
||||
(void)SMC->PMCTRL;
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef CONFIG_XIP
|
||||
wait_for_flash_prefetch_and_wfi();
|
||||
#else
|
||||
__WFI();
|
||||
#endif
|
||||
if (SMC->PMCTRL & SMC_PMCTRL_STOPA_MASK) {
|
||||
LOG_DBG("partial stop aborted");
|
||||
}
|
||||
irq_unlock(0);
|
||||
break;
|
||||
default:
|
||||
LOG_WRN("Unsupported power state %u", state);
|
||||
@@ -54,7 +82,7 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
|
||||
|
||||
if (state == PM_STATE_SUSPEND_TO_IDLE) {
|
||||
/* Disable deep sleep upon exit */
|
||||
SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
}
|
||||
|
||||
irq_unlock(0);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <zephyr/init.h>
|
||||
#include <fsl_clock.h>
|
||||
#include <cmsis_core.h>
|
||||
#include "fsl_smc.h"
|
||||
|
||||
#define ASSERT_WITHIN_RANGE(val, min, max, str) BUILD_ASSERT(val >= min && val <= max, str)
|
||||
|
||||
@@ -186,6 +187,9 @@ void soc_early_init_hook(void)
|
||||
{
|
||||
/* Initialize system clocks and PLL */
|
||||
clk_init();
|
||||
#ifdef CONFIG_PM
|
||||
SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
|
||||
#endif /* CONFIG_PM */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOC_RESET_HOOK
|
||||
|
||||
Reference in New Issue
Block a user