@@ -83,9 +83,6 @@ void nrf_poweroff(void)
8383#endif
8484 common_suspend ();
8585
86- /* Disable all owned compare channels except the one used for wakeup from system-off. */
87- z_nrf_grtc_timer_disable_owned_cc_channels (z_nrf_grtc_timer_wakeup_channel_get ());
88-
8986 /* Indicate that we are ready for system off. */
9087 nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_SYSTEMOFFREADY );
9188
@@ -140,6 +137,34 @@ static void s2idle_exit(uint8_t substate_id)
140137 }
141138}
142139
140+ #if defined(CONFIG_SOC_NRF54H20_CPURAD )
141+
142+ static void s2idle_ready_for_soft_off_enter (void )
143+ {
144+ #if !defined(CONFIG_SOC_NRF54H20_CPURAD )
145+ soc_lrcconf_poweron_request (& soc_node , NRF_LRCCONF_POWER_MAIN );
146+ #endif
147+ common_suspend ();
148+ nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_SYSTEMOFFREADY );
149+
150+ __set_BASEPRI (0 );
151+ __ISB ();
152+ __DSB ();
153+ __WFI ();
154+ }
155+
156+ static void s2idle_ready_for_soft_off_exit (void )
157+ {
158+ nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_SYSTEMOFFNOTREADY );
159+
160+ nrf_power_up_cache ();
161+ common_resume ();
162+ #if !defined(CONFIG_SOC_NRF54H20_CPURAD )
163+ soc_lrcconf_poweron_release (& soc_node , NRF_LRCCONF_POWER_MAIN );
164+ #endif
165+ }
166+ #endif
167+
143168#if defined(CONFIG_PM_S2RAM )
144169/* Resume domain after local suspend to RAM. */
145170static void s2ram_exit (void )
@@ -151,6 +176,17 @@ static void s2ram_exit(void)
151176#endif
152177}
153178
179+ static void s2ram_ready_for_soft_off_exit (void )
180+ {
181+ nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_SYSTEMOFFNOTREADY );
182+
183+ common_resume ();
184+ #if !defined(CONFIG_SOC_NRF54H20_CPURAD )
185+ /* Re-enable domain retention. */
186+ nrf_lrcconf_retain_set (NRF_LRCCONF010 , NRF_LRCCONF_POWER_DOMAIN_0 , true);
187+ #endif
188+ }
189+
154190/* Function called during local domain suspend to RAM. */
155191static int sys_suspend_to_ram (void )
156192{
@@ -178,6 +214,35 @@ static int sys_suspend_to_ram(void)
178214 return - EBUSY ;
179215}
180216
217+ /* Function called during local domain suspend to RAM with soft off readiness. */
218+ static int sys_suspend_to_ram_ready_for_soft_off (void )
219+ {
220+ /* Set intormation which is used on domain wakeup to determine if resume from RAM shall
221+ * be performed.
222+ */
223+ nrf_resetinfo_resetreas_local_set (NRF_RESETINFO ,
224+ NRF_RESETINFO_RESETREAS_LOCAL_UNRETAINED_MASK );
225+ nrf_resetinfo_restore_valid_set (NRF_RESETINFO , true);
226+
227+ #if !defined(CONFIG_SOC_NRF54H20_CPURAD )
228+ /* Disable retention */
229+ nrf_lrcconf_retain_set (NRF_LRCCONF010 , NRF_LRCCONF_POWER_DOMAIN_0 , false);
230+ #endif
231+ common_suspend ();
232+
233+ nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_SYSTEMOFFREADY );
234+
235+ __set_BASEPRI (0 );
236+ __ISB ();
237+ __DSB ();
238+ __WFI ();
239+ /*
240+ * We might reach this point is k_cpu_idle returns (there is a pre sleep hook that
241+ * can abort sleeping.
242+ */
243+ return - EBUSY ;
244+ }
245+
181246static void s2ram_enter (void )
182247{
183248 /*
@@ -188,6 +253,17 @@ static void s2ram_enter(void)
188253 return ;
189254 }
190255}
256+
257+ static void s2ram_ready_for_soft_off_enter (void )
258+ {
259+ /*
260+ * Save the CPU context (including the return address),set the SRAM
261+ * marker and power off the system.
262+ */
263+ if (soc_s2ram_suspend (sys_suspend_to_ram_ready_for_soft_off )) {
264+ return ;
265+ }
266+ }
191267#endif /* defined(CONFIG_PM_S2RAM) */
192268
193269void pm_state_set (enum pm_state state , uint8_t substate_id )
@@ -201,6 +277,17 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
201277 sys_trace_idle_exit ();
202278 __enable_irq ();
203279 }
280+ #if defined(CONFIG_SOC_NRF54H20_CPURAD ) && defined(CONFIG_POWEROFF )
281+ else if (state == PM_STATE_SOFT_OFF ) {
282+ __disable_irq ();
283+ sys_trace_idle ();
284+ s2idle_ready_for_soft_off_enter ();
285+ /* On resuming or error we return exactly *HERE* */
286+ s2idle_ready_for_soft_off_exit ();
287+ sys_trace_idle_exit ();
288+ __enable_irq ();
289+ }
290+ #endif
204291#if defined(CONFIG_PM_S2RAM )
205292 else if (state == PM_STATE_SUSPEND_TO_RAM ) {
206293 __disable_irq ();
@@ -211,6 +298,17 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
211298 sys_trace_idle_exit ();
212299 __enable_irq ();
213300 }
301+ #if defined(CONFIG_POWEROFF )
302+ else if (state == PM_STATE_SOFT_OFF ) {
303+ __disable_irq ();
304+ sys_trace_idle ();
305+ s2ram_ready_for_soft_off_enter ();
306+ /* On resuming or error we return exactly *HERE* */
307+ s2ram_ready_for_soft_off_exit ();
308+ sys_trace_idle_exit ();
309+ __enable_irq ();
310+ }
311+ #endif
214312#endif
215313 else {
216314 k_cpu_idle ();
0 commit comments