Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,21 @@ zephyr_udc0: &usbhs {
status = "okay";
};

/* Trim this RAM block for making room on all run-time common S2RAM cpu context. */
/* Trim this RAM block for power management related features. */
&cpuapp_ram0 {
reg = <0x22000000 (DT_SIZE_K(32) - 56)>;
ranges = <0x0 0x22000000 (0x8000 - 0x38)>;
reg = <0x22000000 (DT_SIZE_K(32) - 256)>;
ranges = <0x0 0x22000000 (0x8000 - 0x100)>;
};

/ {
soc {
/* cache control functions - must be executed from local SRAM */
pm_ramfunc: cpuapp_s2ram@22007f00 {
compatible = "zephyr,memory-region", "mmio-sram";
reg = <0x22007f00 192>;
zephyr,memory-region = "PMLocalRamfunc";
};

/* temporary stack for S2RAM resume logic */
pm_s2ram_stack: cpuapp_s2ram_stack@22007fc8 {
compatible = "zephyr,memory-region", "mmio-sram";
Expand All @@ -366,7 +373,7 @@ zephyr_udc0: &usbhs {
};

/* run-time common S2RAM cpu context RAM */
pm_s2ram: cpuapp_s2ram@22007fe0 {
pm_s2ram: cpuapp_s2ram@22007fe0 {
compatible = "zephyr,memory-region", "mmio-sram";
reg = <0x22007fe0 32>;
zephyr,memory-region = "pm_s2ram_context";
Expand Down
17 changes: 17 additions & 0 deletions boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,20 @@ slot1_partition: &cpurad_slot1_partition {
zephyr_udc0: &usbhs {
status = "disabled";
};

/* Trim this RAM block for power management related features. */
&cpurad_ram0 {
reg = <0x23000000 (DT_SIZE_K(192) - 192)>;
ranges = <0x0 0x23000000 (0x30000 - 0xC0)>;
};

/ {
soc {
/* cache control functions - must be executed from RAM */
pm_ramfunc: cpurad_s2ram@2302ff40 {
compatible = "zephyr,memory-region", "mmio-sram";
reg = <0x2302ff80 192>;
zephyr,memory-region = "PMLocalRamfunc";
};
};
};
12 changes: 9 additions & 3 deletions dts/vendor/nordic/nrf54h20.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
device_type = "cpu";
clocks = <&cpuapp_hsfll>;
clock-frequency = <DT_FREQ_M(320)>;
cpu-power-states = <&idle_cache_disabled &s2ram>;
cpu-power-states = <&idle_cache_retained &idle_cache_disabled &s2ram>;
};

cpurad: cpu@3 {
Expand All @@ -40,7 +40,7 @@
device_type = "cpu";
clocks = <&cpurad_hsfll>;
clock-frequency = <DT_FREQ_M(256)>;
cpu-power-states = <&idle_cache_disabled>;
cpu-power-states = <&idle_cache_retained &idle_cache_disabled>;
};

cpuppr: cpu@d {
Expand Down Expand Up @@ -130,7 +130,13 @@

power-states {
// substate-id = <0>; is reserved for "idle", cache powered on
// substate-id = <1>; is reserved for "idle-cache-retained"
idle_cache_retained: idle_cache_retained {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-idle";
substate-id = <1>;
min-residency-us = <700>;
exit-latency-us = <5>;
};
idle_cache_disabled: idle_cache_disabled {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-idle";
Expand Down
5 changes: 5 additions & 0 deletions soc/nordic/nrf54h/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ if(CONFIG_ARM)
zephyr_library_sources(soc.c)
if(CONFIG_PM OR CONFIG_POWEROFF)
zephyr_library_sources(power.c)
zephyr_code_relocate(
FILES power.c
FILTER ".*\\.cache_retain_and_sleep"
LOCATION PMLocalRamfunc_TEXT
)
endif()
endif()

Expand Down
3 changes: 3 additions & 0 deletions soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ config SHELL_BACKEND_SERIAL
config POWER_DOMAIN
default y

config CODE_DATA_RELOCATION
default y if (PM || POWEROFF) && !MCUBOOT

endif # SOC_NRF54H20_CPUAPP
3 changes: 3 additions & 0 deletions soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ config PM
config POWER_DOMAIN
default y

config CODE_DATA_RELOCATION
default y if PM || POWEROFF

endif # SOC_NRF54H20_CPURAD
55 changes: 44 additions & 11 deletions soc/nordic/nrf54h/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <zephyr/arch/common/pm_s2ram.h>
#include <hal/nrf_resetinfo.h>
#include <hal/nrf_memconf.h>
#include <hal/nrf_cache.h>
#include <zephyr/cache.h>
#include <power.h>
#include <soc_lrcconf.h>
Expand Down Expand Up @@ -87,18 +88,48 @@
CODE_UNREACHABLE;
}

static void s2idle_enter(uint8_t substate_id)
#if CONFIG_MCUBOOT
static __ramfunc
#else
static __attribute__((__used__, noinline))
#endif
void cache_retain_and_sleep(void)
{
nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_SAVE);
nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_SAVE);
while (nrf_cache_busy_check(NRF_DCACHE) ||
nrf_cache_busy_check(NRF_ICACHE)) {

}

Check notice on line 103 in soc/nordic/nrf54h/power.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

soc/nordic/nrf54h/power.c:103 -static __attribute__((__used__, noinline)) -#endif -void cache_retain_and_sleep(void) +static + __attribute__((__used__, noinline)) +#endif + void + cache_retain_and_sleep(void) { nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_SAVE); nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_SAVE); - while (nrf_cache_busy_check(NRF_DCACHE) || - nrf_cache_busy_check(NRF_ICACHE)) { - + while (nrf_cache_busy_check(NRF_DCACHE) || nrf_cache_busy_check(NRF_ICACHE)) {

__set_BASEPRI(0);
__ISB();
__DSB();
__WFI();

nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_RESTORE);
nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_RESTORE);
while (nrf_cache_busy_check(NRF_DCACHE) ||
nrf_cache_busy_check(NRF_ICACHE)) {

}

Check notice on line 115 in soc/nordic/nrf54h/power.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

soc/nordic/nrf54h/power.c:115 - while (nrf_cache_busy_check(NRF_DCACHE) || - nrf_cache_busy_check(NRF_ICACHE)) { - + while (nrf_cache_busy_check(NRF_DCACHE) || nrf_cache_busy_check(NRF_ICACHE)) {
}

void s2idle_enter(uint8_t substate_id)
{
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_MAIN);
#endif
switch (substate_id) {
case 0:
/* Substate for idle with cache powered on - not implemented yet. */
break;
case 1: /* Substate for idle with cache retained - not implemented yet. */
break;
case 1: /* Substate for idle with cache retained. */
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
nrf_soc_memconf_retain_set(true);
cache_retain_and_sleep();
return;
case 2: /* Substate for idle with cache disabled. */
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_MAIN);
#endif
common_suspend();
break;
default: /* Unknown substate. */
Expand All @@ -117,17 +148,19 @@
case 0:
/* Substate for idle with cache powered on - not implemented yet. */
break;
case 1: /* Substate for idle with cache retained - not implemented yet. */
case 1: /* Substate for idle with cache retained. */
nrf_soc_memconf_retain_set(false);
break;
case 2: /* Substate for idle with cache disabled. */
nrf_power_up_cache();
common_resume();
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN);
#endif
break;
default: /* Unknown substate. */
return;
}
common_resume();
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN);
#endif
}

#if defined(CONFIG_PM_S2RAM)
Expand Down
42 changes: 23 additions & 19 deletions soc/nordic/nrf54h/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ sys_snode_t soc_node;
ADDRESS_DOMAIN_Msk | \
ADDRESS_BUS_Msk)))

void nrf_soc_memconf_retain_set(bool enable)
{
uint32_t ret_mask = BIT(RAMBLOCK_RET_BIT_ICACHE) | BIT(RAMBLOCK_RET_BIT_DCACHE);

nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, ret_mask, enable);
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, ret_mask, enable);

#if defined(RAMBLOCK_RET2_MASK)
ret_mask = 0;
#if defined(RAMBLOCK_RET2_BIT_ICACHE)
ret_mask |= BIT(RAMBLOCK_RET2_BIT_ICACHE);
#endif
#if defined(RAMBLOCK_RET2_BIT_DCACHE)
ret_mask |= BIT(RAMBLOCK_RET2_BIT_DCACHE);
#endif
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 0, ret_mask, enable);
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 1, ret_mask, enable);
#endif /* defined(RAMBLOCK_RET2_MASK) */
}

static void power_domain_init(void)
{
/*
Expand All @@ -76,28 +96,12 @@ static void power_domain_init(void)

soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, false);

nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_BIT_ICACHE, false);
nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_BIT_DCACHE, false);
nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_BIT_ICACHE, false);
nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_BIT_DCACHE, false);
#if defined(RAMBLOCK_RET2_BIT_ICACHE)
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_BIT_ICACHE, false);
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_BIT_ICACHE, false);
#endif
#if defined(RAMBLOCK_RET2_BIT_DCACHE)
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_BIT_DCACHE, false);
nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_BIT_DCACHE, false);
#endif
nrf_soc_memconf_retain_set(false);
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_MASK, true);
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_MASK, true);
#if defined(RAMBLOCK_RET2_MASK)
/*
* TODO: Use nrf_memconf_ramblock_ret2_mask_enable_set() function
* when will be provided by HAL.
*/
NRF_MEMCONF->POWER[0].RET2 = RAMBLOCK_RET2_MASK;
NRF_MEMCONF->POWER[1].RET2 = RAMBLOCK_RET2_MASK;
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_MASK, true);
nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_MASK, true);
#endif
}

Expand Down
7 changes: 7 additions & 0 deletions soc/nordic/nrf54h/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,11 @@
#define RAMBLOCK_RET2_BIT_DCACHE MEMCONF_POWER_RET2_MEM7_Pos
#endif

/**
* @brief Enable or disable the retention for cache RAM blocks.
*
* @param enable True if the retention is to be enabled, false otherwise.
*/
void nrf_soc_memconf_retain_set(bool enable);

#endif /* SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ */
Loading