Skip to content

Commit f5ebc13

Browse files
committed
soc: nxp: imx9: add basic pm process for i.MX95 M7
add basic pm_state_set and pm_state_exit_post_ops Signed-off-by: Yongxu Wang <[email protected]>
1 parent f4a96b6 commit f5ebc13

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

soc/nxp/imx/imx9/imx95/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ config SOC_MIMX9596_M7
1313
select SOC_LATE_INIT_HOOK
1414
select HAS_MCUX
1515
select HAS_MCUX_CACHE
16+
select HAS_PM
1617

1718
config SOC_MIMX9596_A55
1819
select ARM64

soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.m7

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,11 @@ config CACHE_MANAGEMENT
5050

5151
config ETH_NXP_IMX_MSGINTR
5252
default 2
53+
if PM
54+
# PM code that runs from the idle loop has a large
55+
# footprint. Hence increase the size when PM is enabled.
56+
config IDLE_STACK_SIZE
57+
default 640
58+
endif
5359

5460
endif # SOC_MIMX9596_M7

soc/nxp/imx/imx9/imx95/m7/soc.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,69 @@ static int soc_init(void)
8888
return ret;
8989
}
9090

91+
void pm_state_set(enum pm_state state, uint8_t substate_id)
92+
{
93+
struct scmi_cpu_sleep_mode_config cpu_cfg = {0};
94+
95+
/* iMX95 M7 core is based on ARMv7-M architecture. For this architecture,
96+
* the current implementation of arch_irq_lock of zephyr is based on BASEPRI,
97+
* which will only retain abnormal interrupts such as NMI,
98+
* and all other interrupts from the CPU(including systemtick) will be masked,
99+
* which makes the CORE unable to be woken up from WFI.
100+
* Set PRIMASK as workaround, Shield the CPU from responding to interrupts,
101+
* the CPU will not jump to the interrupt service routine (ISR).
102+
*/
103+
__disable_irq();
104+
/* Set BASEPRI to 0 */
105+
irq_unlock(0);
106+
107+
/* disabled system manager irq */
108+
irq_disable(DT_IRQN(DT_NODELABEL(mu5)));
109+
110+
switch (state) {
111+
case PM_STATE_RUNTIME_IDLE:
112+
cpu_cfg.cpu_id = CPU_IDX_M7P;
113+
cpu_cfg.sleep_mode = CPU_SLEEP_MODE_WAIT;
114+
scmi_cpu_sleep_mode_set(&cpu_cfg);
115+
__DSB();
116+
__WFI();
117+
break;
118+
case PM_STATE_SUSPEND_TO_IDLE:
119+
cpu_cfg.cpu_id = CPU_IDX_M7P;
120+
cpu_cfg.sleep_mode = CPU_SLEEP_MODE_STOP;
121+
scmi_cpu_sleep_mode_set(&cpu_cfg);
122+
__DSB();
123+
__WFI();
124+
break;
125+
case PM_STATE_STANDBY:
126+
cpu_cfg.cpu_id = CPU_IDX_M7P;
127+
cpu_cfg.sleep_mode = CPU_SLEEP_MODE_SUSPEND;
128+
scmi_cpu_sleep_mode_set(&cpu_cfg);
129+
__DSB();
130+
__WFI();
131+
break;
132+
default:
133+
break;
134+
}
135+
}
136+
137+
/* Handle SOC specific activity after Low Power Mode Exit */
138+
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
139+
{
140+
ARG_UNUSED(state);
141+
142+
struct scmi_cpu_sleep_mode_config cpu_cfg = {0};
143+
/* restore M7 core state into ACTIVE. */
144+
cpu_cfg.cpu_id = CPU_IDX_M7P;
145+
cpu_cfg.sleep_mode = CPU_SLEEP_MODE_RUN;
146+
scmi_cpu_sleep_mode_set(&cpu_cfg);
147+
148+
/* Clear PRIMASK */
149+
__enable_irq();
150+
/* restore system manager irq after M7 exit low power states. */
151+
irq_enable(DT_IRQN(DT_NODELABEL(mu5)));
152+
}
153+
91154
/*
92155
* Because platform is using ARM SCMI, drivers like scmi, mbox etc. are
93156
* initialized during PRE_KERNEL_1. Common init hooks is not able to use.

0 commit comments

Comments
 (0)