Skip to content

Commit 6e33c76

Browse files
[nrf fromlist] soc: nordic: nrf54h: Implement idle with cache retained state
Add new idle state with cache retention enabled. Upstream PR #: 95474 Signed-off-by: Adam Kondraciuk <[email protected]>
1 parent d792280 commit 6e33c76

File tree

9 files changed

+116
-36
lines changed

9 files changed

+116
-36
lines changed

boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,21 @@ zephyr_udc0: &usbhs {
341341
status = "okay";
342342
};
343343

344-
/* Trim this RAM block for making room on all run-time common S2RAM cpu context. */
344+
/* Trim this RAM block for power management related features. */
345345
&cpuapp_ram0 {
346-
reg = <0x22000000 (DT_SIZE_K(32) - 52)>;
347-
ranges = <0x0 0x22000000 (0x8000 - 0x34)>;
346+
reg = <0x22000000 (DT_SIZE_K(32) - 52 - 128)>;
347+
ranges = <0x0 0x22000000 (0x8000 - 0x34 - 0x80)>;
348348
};
349349

350350
/ {
351351
soc {
352+
/* cache control functions - must be executed from local SRAM */
353+
pm_ramfunc: cpuapp_s2ram@22007f5c {
354+
compatible = "zephyr,memory-region", "mmio-sram";
355+
reg = <0x22007f5c 128>;
356+
zephyr,memory-region = "PMLocalRamfunc";
357+
};
358+
352359
/* temporary stack for S2RAM resume logic */
353360
pm_s2ram_stack: cpuapp_s2ram_stack@22007fcc {
354361
compatible = "zephyr,memory-region", "mmio-sram";

boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,20 @@ slot1_partition: &cpurad_slot1_partition {
121121
zephyr_udc0: &usbhs {
122122
status = "disabled";
123123
};
124+
125+
/* Trim this RAM block for power management related features. */
126+
&cpurad_ram0 {
127+
reg = <0x23000000 (DT_SIZE_K(192) - 128)>;
128+
ranges = <0x0 0x23000000 (0x30000 - 0x80)>;
129+
};
130+
131+
/ {
132+
soc {
133+
/* cache control functions - must be executed from RAM */
134+
pm_ramfunc: cpurad_s2ram@2302ff80 {
135+
compatible = "zephyr,memory-region", "mmio-sram";
136+
reg = <0x2302ff80 128>;
137+
zephyr,memory-region = "PMLocalRamfunc";
138+
};
139+
};
140+
};

dts/vendor/nordic/nrf54h20.dtsi

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
device_type = "cpu";
3232
clocks = <&cpuapp_hsfll>;
3333
clock-frequency = <DT_FREQ_M(320)>;
34-
cpu-power-states = <&idle_cache_disabled &s2ram>;
34+
cpu-power-states = <&idle_cache_retained &idle_cache_disabled &s2ram>;
3535
};
3636

3737
cpurad: cpu@3 {
@@ -40,7 +40,7 @@
4040
device_type = "cpu";
4141
clocks = <&cpurad_hsfll>;
4242
clock-frequency = <DT_FREQ_M(256)>;
43-
cpu-power-states = <&idle_cache_disabled>;
43+
cpu-power-states = <&idle_cache_retained &idle_cache_disabled>;
4444
};
4545

4646
cpuppr: cpu@d {
@@ -130,7 +130,13 @@
130130

131131
power-states {
132132
// substate-id = <0>; is reserved for "idle", cache powered on
133-
// substate-id = <1>; is reserved for "idle-cache-retained"
133+
idle_cache_retained: idle_cache_retained {
134+
compatible = "zephyr,power-state";
135+
power-state-name = "suspend-to-idle";
136+
substate-id = <1>;
137+
min-residency-us = <700>;
138+
exit-latency-us = <5>;
139+
};
134140
idle_cache_disabled: idle_cache_disabled {
135141
compatible = "zephyr,power-state";
136142
power-state-name = "suspend-to-idle";

soc/nordic/nrf54h/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ if(CONFIG_ARM)
55
zephyr_library_sources(soc.c)
66
if(CONFIG_PM OR CONFIG_POWEROFF)
77
zephyr_library_sources(power.c)
8+
zephyr_code_relocate(
9+
FILES power.c
10+
FILTER ".*\\.cache_retain_and_sleep"
11+
LOCATION PMLocalRamfunc_TEXT
12+
)
813
endif()
914
endif()
1015

soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ config SHELL_BACKEND_SERIAL
1414
config POWER_DOMAIN
1515
default y
1616

17+
config CODE_DATA_RELOCATION
18+
default y if PM || POWEROFF
19+
1720
endif # SOC_NRF54H20_CPUAPP

soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ config PM
1414
config POWER_DOMAIN
1515
default y
1616

17+
config CODE_DATA_RELOCATION
18+
default y if PM || POWEROFF
19+
1720
endif # SOC_NRF54H20_CPURAD

soc/nordic/nrf54h/power.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <zephyr/arch/common/pm_s2ram.h>
1111
#include <hal/nrf_resetinfo.h>
1212
#include <hal/nrf_memconf.h>
13+
#include <hal/nrf_cache.h>
1314
#include <zephyr/cache.h>
1415
#include <power.h>
1516
#include <soc_lrcconf.h>
@@ -87,18 +88,43 @@ void nrf_poweroff(void)
8788
CODE_UNREACHABLE;
8889
}
8990

90-
static void s2idle_enter(uint8_t substate_id)
91+
static __attribute__((__used__, noinline)) void cache_retain_and_sleep(void)
9192
{
93+
nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_SAVE);
94+
nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_SAVE);
95+
while (nrf_cache_busy_check(NRF_DCACHE) ||
96+
nrf_cache_busy_check(NRF_ICACHE)) {
97+
98+
}
99+
100+
__set_BASEPRI(0);
101+
__ISB();
102+
__DSB();
103+
__WFI();
104+
105+
nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_RESTORE);
106+
nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_RESTORE);
107+
while (nrf_cache_busy_check(NRF_DCACHE) ||
108+
nrf_cache_busy_check(NRF_ICACHE)) {
109+
110+
}
111+
}
112+
113+
void s2idle_enter(uint8_t substate_id)
114+
{
115+
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
116+
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_MAIN);
117+
#endif
92118
switch (substate_id) {
93119
case 0:
94120
/* Substate for idle with cache powered on - not implemented yet. */
95121
break;
96-
case 1: /* Substate for idle with cache retained - not implemented yet. */
97-
break;
122+
case 1: /* Substate for idle with cache retained. */
123+
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
124+
nrf_soc_memconf_retain_set(true);
125+
cache_retain_and_sleep();
126+
return;
98127
case 2: /* Substate for idle with cache disabled. */
99-
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
100-
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_MAIN);
101-
#endif
102128
common_suspend();
103129
break;
104130
default: /* Unknown substate. */
@@ -117,17 +143,19 @@ static void s2idle_exit(uint8_t substate_id)
117143
case 0:
118144
/* Substate for idle with cache powered on - not implemented yet. */
119145
break;
120-
case 1: /* Substate for idle with cache retained - not implemented yet. */
146+
case 1: /* Substate for idle with cache retained. */
147+
nrf_soc_memconf_retain_set(false);
121148
break;
122149
case 2: /* Substate for idle with cache disabled. */
123150
nrf_power_up_cache();
124-
common_resume();
125-
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
126-
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN);
127-
#endif
151+
break;
128152
default: /* Unknown substate. */
129153
return;
130154
}
155+
common_resume();
156+
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
157+
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN);
158+
#endif
131159
}
132160

133161
#if defined(CONFIG_PM_S2RAM)

soc/nordic/nrf54h/soc.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ sys_snode_t soc_node;
6161
ADDRESS_DOMAIN_Msk | \
6262
ADDRESS_BUS_Msk)))
6363

64+
void nrf_soc_memconf_retain_set(bool enable)
65+
{
66+
uint32_t ret_mask = BIT(RAMBLOCK_RET_BIT_ICACHE) | BIT(RAMBLOCK_RET_BIT_DCACHE);
67+
68+
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, ret_mask, enable);
69+
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, ret_mask, enable);
70+
71+
#if defined(RAMBLOCK_RET2_MASK)
72+
ret_mask = 0;
73+
#if defined(RAMBLOCK_RET2_BIT_ICACHE)
74+
ret_mask |= BIT(RAMBLOCK_RET2_BIT_ICACHE);
75+
#endif
76+
#if defined(RAMBLOCK_RET2_BIT_DCACHE)
77+
ret_mask |= BIT(RAMBLOCK_RET2_BIT_DCACHE);
78+
#endif
79+
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 0, ret_mask, enable);
80+
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 1, ret_mask, enable);
81+
#endif /* defined(RAMBLOCK_RET2_MASK) */
82+
}
83+
6484
static void power_domain_init(void)
6585
{
6686
/*
@@ -76,28 +96,12 @@ static void power_domain_init(void)
7696

7797
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
7898
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, false);
79-
80-
nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_BIT_ICACHE, false);
81-
nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_BIT_DCACHE, false);
82-
nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_BIT_ICACHE, false);
83-
nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_BIT_DCACHE, false);
84-
#if defined(RAMBLOCK_RET2_BIT_ICACHE)
85-
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_BIT_ICACHE, false);
86-
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_BIT_ICACHE, false);
87-
#endif
88-
#if defined(RAMBLOCK_RET2_BIT_DCACHE)
89-
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_BIT_DCACHE, false);
90-
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_BIT_DCACHE, false);
91-
#endif
99+
nrf_soc_memconf_retain_set(false);
92100
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_MASK, true);
93101
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_MASK, true);
94102
#if defined(RAMBLOCK_RET2_MASK)
95-
/*
96-
* TODO: Use nrf_memconf_ramblock_ret2_mask_enable_set() function
97-
* when will be provided by HAL.
98-
*/
99-
NRF_MEMCONF->POWER[0].RET2 = RAMBLOCK_RET2_MASK;
100-
NRF_MEMCONF->POWER[1].RET2 = RAMBLOCK_RET2_MASK;
103+
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_MASK, true);
104+
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_MASK, true);
101105
#endif
102106
}
103107

soc/nordic/nrf54h/soc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,11 @@
3636
#define RAMBLOCK_RET2_BIT_DCACHE MEMCONF_POWER_RET2_MEM7_Pos
3737
#endif
3838

39+
/**
40+
* @brief Enable or disable the retention for cache RAM blocks.
41+
*
42+
* @param enable True if the retention is to be enabled, false otherwise.
43+
*/
44+
void nrf_soc_memconf_retain_set(bool enable);
45+
3946
#endif /* SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ */

0 commit comments

Comments
 (0)