From cab3f6d95476d2d9b0e156dd40b3e1edf05b8cd9 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Mon, 1 Dec 2025 11:26:25 +0800 Subject: [PATCH 1/3] soc: nxp: mcxw2xx: Enable the power management Enabled modes: idle: SLEEP suspend: DEEP-SLEEP standby: POWER-DOWN with CPU retention OS Time Base: OSTIMER with 32K clock source Signed-off-by: Jason Yu --- dts/arm/nxp/nxp_mcxw23x_common.dtsi | 51 +++++ soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig | 43 ++++- soc/nxp/mcx/mcxw/mcxw2xx/power.c | 207 ++++++++++++++++++++- soc/nxp/mcx/mcxw/mcxw2xx/soc.c | 20 +- 4 files changed, 313 insertions(+), 8 deletions(-) diff --git a/dts/arm/nxp/nxp_mcxw23x_common.dtsi b/dts/arm/nxp/nxp_mcxw23x_common.dtsi index 1a32a00672a6b..8604526bec490 100644 --- a/dts/arm/nxp/nxp_mcxw23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw23x_common.dtsi @@ -32,12 +32,47 @@ reg = <0>; #address-cells = <1>; #size-cells = <1>; + cpu-power-states = <&idle &suspend &standby>; mpu: mpu@e000ed90 { compatible = "arm,armv8m-mpu"; reg = <0xe000ed90 0x40>; }; }; + + power-states { + /* Idle mode maps to Sleep mode. */ + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + min-residency-us = <60>; + exit-latency-us = <16>; + zephyr,pm-device-disabled; + }; + + /* Suspend mode maps to Deep Sleep mode. */ + suspend: suspend { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1300>; + exit-latency-us = <749>; + }; + + /* Standby mode maps to Power Down mode with CPU retention . */ + standby: standby { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <2000>; + exit-latency-us = <1345>; + }; + }; + }; + + /* For the resource which will be off and lose content. */ + standby_off_domain: standby-off-domain { + compatible = "power-domain-soc-state-change"; + #power-domain-cells = <0>; + onoff-power-states = <&standby>; }; sysclk: system-clock { @@ -175,6 +210,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer1: ctimer@9000 { @@ -187,6 +223,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer2: ctimer@28000 { @@ -199,6 +236,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer3: ctimer@29000 { @@ -211,6 +249,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer4: ctimer@2a000 { @@ -223,6 +262,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; sc_timer: pwm@85000 { @@ -232,6 +272,7 @@ status = "disabled"; clocks = <&syscon MCUX_SCTIMER_CLK>; prescaler = <2>; + zephyr,disabling-power-states = <&suspend &standby>; #pwm-cells = <3>; }; @@ -251,6 +292,7 @@ resets = <&reset NXP_SYSCON_RESET(1, 11)>; dmas = <&dma0 4 &dma0 5>; dma-names = "rx", "tx"; + zephyr,disabling-power-states = <&suspend &standby>; status = "disabled"; }; @@ -262,6 +304,8 @@ resets = <&reset NXP_SYSCON_RESET(1, 12)>; dmas = <&dma0 6 &dma0 7>; dma-names = "rx", "tx"; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; }; @@ -273,6 +317,8 @@ resets = <&reset NXP_SYSCON_RESET(1, 13)>; dmas = <&dma0 8 &dma0 9>; dma-names = "rx", "tx"; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; }; @@ -288,6 +334,8 @@ reg = <0x82000 0x1000>; interrupts = <1 1>; dma-channels = <23>; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; #dma-cells = <1>; }; @@ -297,6 +345,8 @@ reg = <0xa7000 0x1000>; interrupts = <58 1>; dma-channels = <10>; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; #dma-cells = <1>; }; @@ -329,6 +379,7 @@ resets = <&reset NXP_SYSCON_RESET(1, 0)>; #address-cells = <1>; #size-cells = <0>; + zephyr,disabling-power-states = <&suspend &standby>; mrt0_channel0: mrt0_channel@0 { compatible = "nxp,mrt-channel"; diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig index 992335c7044d5..f40676e5ae647 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig @@ -8,7 +8,8 @@ if SOC_SERIES_MCXW2XX # In case we need to switch to OS timer, then # define CONFIG_MCUX_OS_TIMER=y configdefault MCUX_OS_TIMER - default n + default y if PM + default n if !PM config CORTEX_M_SYSTICK default n if MCUX_OS_TIMER @@ -18,10 +19,15 @@ config NUM_IRQS DT_SYSCLK_PATH := $(dt_nodelabel_path,sysclk) -config SYS_CLOCK_HW_CYCLES_PER_SEC - default 1000000 if MCUX_OS_TIMER +configdefault SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 if MCUX_OS_TIMER && PM + default 1000000 if MCUX_OS_TIMER && !PM default $(dt_node_int_prop_int,$(DT_SYSCLK_PATH),clock-frequency) if CORTEX_M_SYSTICK +configdefault SYS_CLOCK_TICKS_PER_SEC + default 1024 if MCUX_OS_TIMER && PM + default 1000 if MCUX_OS_TIMER && !PM + # Set to the minimal size of data which can be written. config FLASH_FILL_BUFFER_SIZE default 512 @@ -45,4 +51,35 @@ config SYSTEM_WORKQUEUE_STACK_SIZE endif # BT +if PM + +# Enable PM_DEVICE for Suspend mode and Standby mode, +# because some devices can't work in these modes. +configdefault PM_DEVICE + default y if "$(dt_nodelabel_enabled,standby)" || "$(dt_nodelabel_enabled,suspend)" + +configdefault PM_POLICY_DEVICE_CONSTRAINTS + default y if PM_DEVICE + +configdefault IDLE_STACK_SIZE + default 640 + +configdefault TICKLESS_KERNEL + default y + +if BT +choice PM_POLICY + default PM_POLICY_CUSTOM +endchoice +endif # BT + +endif # PM + +if PM_DEVICE + +configdefault POWER_DOMAIN + default y + +endif # PM_DEVICE + endif # SOC_SERIES_MCXW2XX diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/power.c b/soc/nxp/mcx/mcxw/mcxw2xx/power.c index 9c92e8275e322..2f178b3bf6b3d 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/power.c +++ b/soc/nxp/mcx/mcxw/mcxw2xx/power.c @@ -5,24 +5,223 @@ */ #include +#include #include +#include +#include +#include +#include -void pm_state_set(enum pm_state state, uint8_t id) +#if CONFIG_PM_POLICY_CUSTOM +#include +#endif /* CONFIG_PM_POLICY_CUSTOM */ + +#ifdef CONFIG_BT +#include "ll_intf.h" +#endif /* CONFIG_BT */ + +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +/* Wakeup pin. */ +#if CONFIG_GPIO && DT_NODE_EXISTS(DT_NODELABEL(btn_wk)) +#define WAKEUP_PIN_ENABLE 1 +#else +#define WAKEUP_PIN_ENABLE 0 +#endif + +#if WAKEUP_PIN_ENABLE +#define WAKEUP_BUTTON_NODE DT_NODELABEL(btn_wk) +static const struct gpio_dt_spec wakeup_pin_dt = GPIO_DT_SPEC_GET(WAKEUP_BUTTON_NODE, gpios); +#endif /* WAKEUP_PIN_ENABLE */ + +#if defined(CONFIG_BT) && !defined(CONFIG_PM_POLICY_CUSTOM) +#error Select CONFIG_PM_POLICY_CUSTOM when CONFIG_BT is selected +#endif + +#if CONFIG_PM_POLICY_CUSTOM +__weak const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) +{ + uint8_t num_cpu_states; + const struct pm_state_info *cpu_states; + const struct pm_state_info *out_state = NULL; + +#ifdef CONFIG_PM_NEED_ALL_DEVICES_IDLE + if (pm_device_is_any_busy()) { + return NULL; + } +#endif + +#ifdef CONFIG_BT + if (bt_is_ready()) { + uint32_t remaining_time; + ble_stat_t stat; + + stat = BLEController_GetRemainingTimeForNextEventUnsafe(&remaining_time); + /* Is link layer busy? */ + if ((stat != SUCCESS) || (remaining_time == 0)) { + return NULL; + } + /* Any future activity? */ + if (remaining_time < 0xffffffff) { + ticks = MIN(ticks, k_us_to_ticks_floor32(remaining_time)); + } + } +#endif /* CONFIG_BT */ + + num_cpu_states = pm_state_cpu_get_all(cpu, &cpu_states); + + for (uint32_t i = 0; i < num_cpu_states; i++) { + const struct pm_state_info *state = &cpu_states[i]; + uint32_t min_residency_ticks = 0; + uint32_t min_residency_us = state->min_residency_us + state->exit_latency_us; + + /* If the input is zero, avoid 64-bit conversion from microseconds to ticks. */ + if (min_residency_us > 0) { + min_residency_ticks = k_us_to_ticks_ceil32(min_residency_us); + } + + if (ticks < min_residency_ticks) { + /* If current state has higher residency then use the previous state; */ + break; + } + + /* check if state is available. */ + if (!pm_policy_state_is_available(state->state, state->substate_id)) { + continue; + } + + out_state = state; + } + + return out_state; +} +#endif /* CONFIG_PM_POLICY_CUSTOM */ + +static void pm_get_lowpower_resource_list(uint32_t *exclude_from_pd, + uint64_t *wakeup_sources, + bool is_standby) +{ + *exclude_from_pd = kLOWPOWERCFG_DCDC_BYPASS; + *wakeup_sources = 0; + +#ifdef CONFIG_BT + /* BT needs 32kHz clock. */ + *exclude_from_pd |= (kLOWPOWERCFG_XTAL32K | kLOWPOWERCFG_BLE_WUP); +#endif + +#ifdef CONFIG_MCUX_OS_TIMER + /* OS_TIMER uses 32K clock as clock source, keep it running. */ + *exclude_from_pd |= kLOWPOWERCFG_XTAL32K; + *wakeup_sources |= kWAKEUP_OS_EVENT; +#endif + +#if WAKEUP_PIN_ENABLE + static const wakeup_irq_t pint_wakeup_sources[] = { + kWAKEUP_PIN_INT0, + kWAKEUP_PIN_INT1, + kWAKEUP_PIN_INT2, + kWAKEUP_PIN_INT3, + kWAKEUP_PIN_INT4, + kWAKEUP_PIN_INT5, + kWAKEUP_PIN_INT6, + kWAKEUP_PIN_INT7 + }; + + /* PINT doesn't work in standby mode. */ + if (!is_standby) { + int slot = nxp_pint_pin_get_slot_index(wakeup_pin_dt.pin); + + if (slot >= 0 && slot < ARRAY_SIZE(pint_wakeup_sources)) { + *wakeup_sources |= pint_wakeup_sources[slot]; + } + } +#endif +} + +__weak void pm_state_set(enum pm_state state, uint8_t id) { ARG_UNUSED(id); + uint32_t exclude_from_pd; + uint64_t wakeup_sources; + status_t status; + + /* Set PRIMASK */ + __disable_irq(); + /* Set BASEPRI to 0 */ + irq_unlock(0); switch (state) { case PM_STATE_RUNTIME_IDLE: - k_cpu_idle(); + POWER_EnterSleep(); + break; + + case PM_STATE_SUSPEND_TO_IDLE: + pm_get_lowpower_resource_list(&exclude_from_pd, &wakeup_sources, false); + status = POWER_EnterDeepSleep(exclude_from_pd, wakeup_sources); + if (status != kStatus_Success) { + LOG_ERR("Failed to enter deep sleep mode: %d", status); + } break; - default: + case PM_STATE_STANDBY: + pm_get_lowpower_resource_list(&exclude_from_pd, &wakeup_sources, true); + status = POWER_EnterPowerDown(exclude_from_pd, wakeup_sources, 1); + if (status != kStatus_Success) { + LOG_ERR("Failed to enter power down mode: %d", status); + } + break; + + default: + LOG_DBG("Unsupported power state %u", state); break; } } -void pm_state_exit_post_ops(enum pm_state state, uint8_t id) +__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t id) { ARG_UNUSED(state); ARG_UNUSED(id); + + /* Clear PRIMASK */ + __enable_irq(); +} + +#if WAKEUP_PIN_ENABLE +static void init_wakeup_gpio_pins(void) +{ + int ret; + + if (!device_is_ready(wakeup_pin_dt.port)) { + LOG_ERR("Wake-up GPIO device not ready"); + return; + } + + ret = gpio_pin_configure_dt(&wakeup_pin_dt, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("Error %d: failed to configure wakeup pin\n", ret); + return; + } + + ret = gpio_pin_interrupt_configure_dt(&wakeup_pin_dt, GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + LOG_ERR("Error %d: failed to configure wakeup pin interrupt\n", ret); + return; + } +} +#endif + +static int nxp_mcxw2xx_power_init(void) +{ +#if WAKEUP_PIN_ENABLE + init_wakeup_gpio_pins(); +#endif /* WAKEUP_PIN_ENABLE */ + + return 0; } + +void nxp_mcxw2xx_power_early_init(void) +{ + POWER_Init(); +} + +SYS_INIT(nxp_mcxw2xx_power_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/soc.c b/soc/nxp/mcx/mcxw/mcxw2xx/soc.c index e561ca8d7e78c..6b35ab5dbb8be 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/soc.c +++ b/soc/nxp/mcx/mcxw/mcxw2xx/soc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -28,10 +29,16 @@ #include #endif +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + /* System clock frequency */ extern uint32_t SystemCoreClock; extern void nxp_nbu_init(void); +#if CONFIG_PM +void nxp_mcxw2xx_power_early_init(void); +#endif /* CONFIG_PM */ + #define CTIMER_CLOCK_SOURCE(node_id) \ TO_CTIMER_CLOCK_SOURCE(DT_CLOCKS_CELL(node_id, name), DT_PROP(node_id, clk_source)) #define TO_CTIMER_CLOCK_SOURCE(inst, val) TO_CLOCK_ATTACH_ID(inst, val) @@ -98,10 +105,17 @@ __weak void clock_init(void) configure_32k_osc(); #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(os_timer), nxp_os_timer, okay) - /*!< OS event timer select FRO 1 MHz clock */ + /* + * OS event timer generally uses FRO 1 MHz clock. + * When power management is enabled, uses 32K clock for lower power. + */ PMC->OSTIMERr &= ~PMC_OSTIMER_OSTIMERCLKSEL_MASK; +#if CONFIG_PM + PMC->OSTIMERr |= OSTIMERCLKSEL_32768 << PMC_OSTIMER_OSTIMERCLKSEL_SHIFT; +#else PMC->OSTIMERr |= OSTIMERCLKSEL_FRO_1MHz << PMC_OSTIMER_OSTIMERCLKSEL_SHIFT; #endif +#endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(iap), nxp_iap_fmc55, okay) /* kCLOCK_Sysctl must be enabled for FLASH_CacheClear, @@ -132,6 +146,10 @@ void soc_early_init_hook(void) { z_arm_clear_faults(); +#if CONFIG_PM + nxp_mcxw2xx_power_early_init(); +#endif /* CONFIG_PM */ + /* Initialize FRO/system clock to 96 MHz */ clock_init(); From 706509d5e5f64877ece1ba39729624a9bbc1168f Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Mon, 17 Nov 2025 16:20:34 +0800 Subject: [PATCH 2/3] soc: nxp: mcxw2xx: Add poweroff support Add poweroff MCXW2xx SoCs, support btn_wk pin wakeup. Signed-off-by: Jason Yu --- soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt | 2 ++ soc/nxp/mcx/mcxw/mcxw2xx/Kconfig | 3 +++ soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c | 34 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt b/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt index 6b55a6def0569..1ad3b988cf4c1 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt +++ b/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt @@ -6,6 +6,8 @@ zephyr_sources(soc.c) zephyr_sources_ifdef(CONFIG_PM power.c) +zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) + zephyr_include_directories(./) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig index 7172ccebf93ba..210dbc43eb2e0 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig +++ b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig @@ -1,3 +1,6 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MCXW2XX + select HAS_POWEROFF diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c b/soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c new file mode 100644 index 0000000000000..31e250d262773 --- /dev/null +++ b/soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c @@ -0,0 +1,34 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#if CONFIG_GPIO && DT_NODE_EXISTS(DT_NODELABEL(btn_wk)) + +#if (DT_GPIO_FLAGS(DT_NODELABEL(btn_wk), gpios)) & GPIO_ACTIVE_LOW +#define POWEROFF_WAKEUP (kWAKEUP_PIN_ENABLE | \ + kWAKEUP_PIN_PUP_EN | \ + kWAKEUP_PIN_WAKEUP_LOW_LVL) +#else /* !GPIO_ACTIVE_LOW */ +#define POWEROFF_WAKEUP (kWAKEUP_PIN_ENABLE | \ + kWAKEUP_PIN_PDN_EN | \ + kWAKEUP_PIN_WAKEUP_HIGH_LVL) +#endif /* GPIO_ACTIVE_LOW */ + +#else +#define POWEROFF_WAKEUP kWAKEUP_PIN_DISABLE +#endif /* CONFIG_GPIO && DT_NODE_EXISTS(DT_NODELABEL(btn_wk)) */ + +void z_sys_poweroff(void) +{ + POWER_EnterPowerOff(0, POWEROFF_WAKEUP); + + CODE_UNREACHABLE; +} From f54a88bb0d22de5fde9cd8b5d01e8871e1ae3740 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Fri, 7 Nov 2025 10:46:18 +0800 Subject: [PATCH 3/3] boards: nxp: mcxw23: Add power management MCXW23 board Add mcxw23_evk and frdm_mcxw23 platforms to the power management test suite to validate power management functionality on MCXW23 hardware. Signed-off-by: Jason Yu --- boards/nxp/frdm_mcxw23/doc/index.rst | 8 ++++++++ boards/nxp/mcxw23_evk/doc/index.rst | 8 ++++++++ tests/subsys/pm/power_mgmt_soc/testcase.yaml | 2 ++ 3 files changed, 18 insertions(+) diff --git a/boards/nxp/frdm_mcxw23/doc/index.rst b/boards/nxp/frdm_mcxw23/doc/index.rst index eaf5ed522c2dd..dfb4e6fa56559 100644 --- a/boards/nxp/frdm_mcxw23/doc/index.rst +++ b/boards/nxp/frdm_mcxw23/doc/index.rst @@ -198,6 +198,14 @@ should see the following message in the terminal: *** Booting Zephyr OS build v4.2.0-2105-g48f2ffda26de *** Hello World! frdm_mcxw23/mcxw236 +Power Management +================ + +When Power Management is enabled :kconfig:option:`CONFIG_PM`, OSTIMER is used as +OS tick timer. + +Limitation: Wakeup pin can't be used as wakeup source in Standby mode. + .. include:: ../../common/board-footer.rst.inc .. _MCXW23 SoC Website: diff --git a/boards/nxp/mcxw23_evk/doc/index.rst b/boards/nxp/mcxw23_evk/doc/index.rst index 866dc06715f6b..49285337fe9bb 100644 --- a/boards/nxp/mcxw23_evk/doc/index.rst +++ b/boards/nxp/mcxw23_evk/doc/index.rst @@ -180,6 +180,14 @@ should see the following message in the terminal: *** Booting Zephyr OS build v4.2.0-2105-g9da1d56da9e7 *** Hello World! mcxw23_evk/mcxw236 +Power Management +================ + +When Power Management is enabled :kconfig:option:`CONFIG_PM`, OSTIMER is used as +OS tick timer. + +Limitation: Wakeup pin can't be used as wakeup source in Standby mode. + .. include:: ../../common/board-footer.rst.inc .. _MCXW23 SoC Website: diff --git a/tests/subsys/pm/power_mgmt_soc/testcase.yaml b/tests/subsys/pm/power_mgmt_soc/testcase.yaml index 7318358415160..7e0bc1dc345be 100644 --- a/tests/subsys/pm/power_mgmt_soc/testcase.yaml +++ b/tests/subsys/pm/power_mgmt_soc/testcase.yaml @@ -30,6 +30,8 @@ tests: - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 - frdm_mcxn236 + - mcxw23_evk + - frdm_mcxw23 tags: pm integration_platforms: - mec15xxevb_assy6853