@@ -88,6 +88,69 @@ static int soc_init(void)
88
88
return ret ;
89
89
}
90
90
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
+
91
154
/*
92
155
* Because platform is using ARM SCMI, drivers like scmi, mbox etc. are
93
156
* initialized during PRE_KERNEL_1. Common init hooks is not able to use.
0 commit comments