soc: nordic: nrf54h: poweroff: Add support for s2ram
Add functions for local domain suspend to RAM. Add matching resume procedure. Add pm_s2ram function for determining source of reset. Add preserving NVIC and MPU state in retained RAM when CPU is powered off during S2RAM procedure. Signed-off-by: Adam Kondraciuk <adam.kondraciuk@nordicsemi.no>
This commit is contained in:
parent
1ef18bd97d
commit
ee9d23945f
9 changed files with 414 additions and 2 deletions
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X)
|
#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X)
|
||||||
#include <hal/nrf_power.h>
|
#include <hal/nrf_power.h>
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_NRF54HX)
|
||||||
|
#include <power.h>
|
||||||
#else
|
#else
|
||||||
#include <hal/nrf_regulators.h>
|
#include <hal/nrf_regulators.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,6 +18,8 @@ void z_sys_poweroff(void)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X)
|
#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X)
|
||||||
nrf_power_system_off(NRF_POWER);
|
nrf_power_system_off(NRF_POWER);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_NRF54HX)
|
||||||
|
nrf_poweroff();
|
||||||
#else
|
#else
|
||||||
nrf_regulators_system_off(NRF_REGULATORS);
|
nrf_regulators_system_off(NRF_REGULATORS);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,8 +3,13 @@
|
||||||
|
|
||||||
if(CONFIG_ARM)
|
if(CONFIG_ARM)
|
||||||
zephyr_library_sources(soc.c)
|
zephyr_library_sources(soc.c)
|
||||||
|
if(CONFIG_PM OR CONFIG_POWEROFF)
|
||||||
|
zephyr_library_sources(power.c)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_PM_S2RAM pm_s2ram.c)
|
||||||
|
|
||||||
zephyr_include_directories(.)
|
zephyr_include_directories(.)
|
||||||
|
|
||||||
# Ensure that image size aligns with 16 bytes so that MRAMC finalizes all writes
|
# Ensure that image size aligns with 16 bytes so that MRAMC finalizes all writes
|
||||||
|
|
|
@ -26,6 +26,8 @@ config SOC_NRF54H20_CPUAPP
|
||||||
select NRFS_HAS_MRAM_SERVICE
|
select NRFS_HAS_MRAM_SERVICE
|
||||||
select NRFS_HAS_TEMP_SERVICE
|
select NRFS_HAS_TEMP_SERVICE
|
||||||
select NRFS_HAS_VBUS_DETECTOR_SERVICE
|
select NRFS_HAS_VBUS_DETECTOR_SERVICE
|
||||||
|
select HAS_PM
|
||||||
|
select HAS_POWEROFF
|
||||||
|
|
||||||
config SOC_NRF54H20_CPURAD
|
config SOC_NRF54H20_CPURAD
|
||||||
select ARM
|
select ARM
|
||||||
|
@ -42,6 +44,8 @@ config SOC_NRF54H20_CPURAD
|
||||||
select NRFS_HAS_MRAM_SERVICE
|
select NRFS_HAS_MRAM_SERVICE
|
||||||
select NRFS_HAS_TEMP_SERVICE
|
select NRFS_HAS_TEMP_SERVICE
|
||||||
select HAS_NORDIC_DMM
|
select HAS_NORDIC_DMM
|
||||||
|
select HAS_PM
|
||||||
|
select HAS_POWEROFF
|
||||||
|
|
||||||
config SOC_NRF54H20_CPUPPR
|
config SOC_NRF54H20_CPUPPR
|
||||||
depends on RISCV_CORE_NORDIC_VPR
|
depends on RISCV_CORE_NORDIC_VPR
|
||||||
|
|
151
soc/nordic/nrf54h/pm_s2ram.c
Normal file
151
soc/nordic/nrf54h/pm_s2ram.c
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/arch/cpu.h>
|
||||||
|
#include <zephyr/arch/common/pm_s2ram.h>
|
||||||
|
#include <zephyr/linker/sections.h>
|
||||||
|
#include <zephyr/sys/util.h>
|
||||||
|
#include <hal/nrf_resetinfo.h>
|
||||||
|
#include "pm_s2ram.h"
|
||||||
|
|
||||||
|
#include <cmsis_core.h>
|
||||||
|
|
||||||
|
#define NVIC_MEMBER_SIZE(member) ARRAY_SIZE(((NVIC_Type *)0)->member)
|
||||||
|
|
||||||
|
/* Currently dynamic regions are only used in case of userspace or stack guard and
|
||||||
|
* stack guard is not used by default on Cortex-M33 because there is a dedicated
|
||||||
|
* mechanism for stack overflow detection. Unless those condition change we don't
|
||||||
|
* need to store MPU content, it can just be reinitialized on resuming.
|
||||||
|
*/
|
||||||
|
#define MPU_USE_DYNAMIC_REGIONS IS_ENABLED(CONFIG_USERSPACE) || IS_ENABLED(CONFIG_MPU_STACK_GUARD)
|
||||||
|
|
||||||
|
/* TODO: The num-mpu-regions property should be used. Needs to be added to dts bindings. */
|
||||||
|
#define MPU_MAX_NUM_REGIONS 16
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* NVIC components stored into RAM. */
|
||||||
|
uint32_t ISER[NVIC_MEMBER_SIZE(ISER)];
|
||||||
|
uint32_t ISPR[NVIC_MEMBER_SIZE(ISPR)];
|
||||||
|
uint8_t IPR[NVIC_MEMBER_SIZE(IPR)];
|
||||||
|
} _nvic_context_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t RNR;
|
||||||
|
uint32_t RBAR[MPU_MAX_NUM_REGIONS];
|
||||||
|
uint32_t RLAR[MPU_MAX_NUM_REGIONS];
|
||||||
|
uint32_t MAIR0;
|
||||||
|
uint32_t MAIR1;
|
||||||
|
uint32_t CTRL;
|
||||||
|
} _mpu_context_t;
|
||||||
|
|
||||||
|
struct backup {
|
||||||
|
_nvic_context_t nvic_context;
|
||||||
|
_mpu_context_t mpu_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
static __noinit struct backup backup_data;
|
||||||
|
|
||||||
|
extern void z_arm_configure_static_mpu_regions(void);
|
||||||
|
extern int z_arm_mpu_init(void);
|
||||||
|
|
||||||
|
/* MPU registers cannot be simply copied because content of RBARx RLARx registers
|
||||||
|
* depends on region which is selected by RNR register.
|
||||||
|
*/
|
||||||
|
static void mpu_suspend(_mpu_context_t *backup)
|
||||||
|
{
|
||||||
|
if (!MPU_USE_DYNAMIC_REGIONS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
backup->RNR = MPU->RNR;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < MPU_MAX_NUM_REGIONS; i++) {
|
||||||
|
MPU->RNR = i;
|
||||||
|
backup->RBAR[i] = MPU->RBAR;
|
||||||
|
backup->RLAR[i] = MPU->RLAR;
|
||||||
|
}
|
||||||
|
backup->MAIR0 = MPU->MAIR0;
|
||||||
|
backup->MAIR1 = MPU->MAIR1;
|
||||||
|
backup->CTRL = MPU->CTRL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mpu_resume(_mpu_context_t *backup)
|
||||||
|
{
|
||||||
|
if (!MPU_USE_DYNAMIC_REGIONS) {
|
||||||
|
z_arm_mpu_init();
|
||||||
|
z_arm_configure_static_mpu_regions();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rnr = backup->RNR;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < MPU_MAX_NUM_REGIONS; i++) {
|
||||||
|
MPU->RNR = i;
|
||||||
|
MPU->RBAR = backup->RBAR[i];
|
||||||
|
MPU->RLAR = backup->RLAR[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
MPU->MAIR0 = backup->MAIR0;
|
||||||
|
MPU->MAIR1 = backup->MAIR1;
|
||||||
|
MPU->RNR = rnr;
|
||||||
|
MPU->CTRL = backup->CTRL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvic_suspend(_nvic_context_t *backup)
|
||||||
|
{
|
||||||
|
memcpy(backup->ISER, (uint32_t *)NVIC->ISER, sizeof(NVIC->ISER));
|
||||||
|
memcpy(backup->ISPR, (uint32_t *)NVIC->ISPR, sizeof(NVIC->ISPR));
|
||||||
|
memcpy(backup->IPR, (uint32_t *)NVIC->IPR, sizeof(NVIC->IPR));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvic_resume(_nvic_context_t *backup)
|
||||||
|
{
|
||||||
|
memcpy((uint32_t *)NVIC->ISER, backup->ISER, sizeof(NVIC->ISER));
|
||||||
|
memcpy((uint32_t *)NVIC->ISPR, backup->ISPR, sizeof(NVIC->ISPR));
|
||||||
|
memcpy((uint32_t *)NVIC->IPR, backup->IPR, sizeof(NVIC->IPR));
|
||||||
|
}
|
||||||
|
|
||||||
|
int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
nvic_suspend(&backup_data.nvic_context);
|
||||||
|
mpu_suspend(&backup_data.mpu_context);
|
||||||
|
ret = arch_pm_s2ram_suspend(system_off);
|
||||||
|
if (ret < 0) {
|
||||||
|
__enable_irq();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpu_resume(&backup_data.mpu_context);
|
||||||
|
nvic_resume(&backup_data.nvic_context);
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pm_s2ram_mark_set(void)
|
||||||
|
{
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pm_s2ram_mark_check_and_clear(void)
|
||||||
|
{
|
||||||
|
bool unretained_wake;
|
||||||
|
bool restore_valid;
|
||||||
|
uint32_t reset_reason = nrf_resetinfo_resetreas_local_get(NRF_RESETINFO);
|
||||||
|
|
||||||
|
if (reset_reason != NRF_RESETINFO_RESETREAS_LOCAL_UNRETAINED_MASK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unretained_wake = reset_reason & NRF_RESETINFO_RESETREAS_LOCAL_UNRETAINED_MASK;
|
||||||
|
nrf_resetinfo_resetreas_local_set(NRF_RESETINFO, 0);
|
||||||
|
|
||||||
|
restore_valid = nrf_resetinfo_restore_valid_check(NRF_RESETINFO);
|
||||||
|
nrf_resetinfo_restore_valid_set(NRF_RESETINFO, false);
|
||||||
|
|
||||||
|
return (unretained_wake & restore_valid) ? true : false;
|
||||||
|
}
|
31
soc/nordic/nrf54h/pm_s2ram.h
Normal file
31
soc/nordic/nrf54h/pm_s2ram.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file Common pm_s2ram.h include for Nordic SoCs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ZEPHYR_SOC_ARM_NORDIC_NRF_PM_S2RAM_H_
|
||||||
|
#define _ZEPHYR_SOC_ARM_NORDIC_NRF_PM_S2RAM_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Save CPU state on suspend
|
||||||
|
*
|
||||||
|
* This function is used on suspend-to-RAM (S2RAM) to save the CPU state in
|
||||||
|
* (retained) RAM before powering the system off using the provided function.
|
||||||
|
* This function is usually called from the PM subsystem / hooks.
|
||||||
|
*
|
||||||
|
* The CPU state consist of internal registers and peripherals like
|
||||||
|
* interrupt controller, memory controllers, etc.
|
||||||
|
*
|
||||||
|
* @param system_off Function to power off the system.
|
||||||
|
*
|
||||||
|
* @retval 0 The CPU context was successfully saved and restored.
|
||||||
|
* @retval -EBUSY The system is busy and cannot be suspended at this time.
|
||||||
|
* @retval -errno Negative errno code in case of failure.
|
||||||
|
*/
|
||||||
|
int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off);
|
||||||
|
|
||||||
|
#endif /* _ZEPHYR_SOC_ARM_NORDIC_NRF_PM_S2RAM_H_ */
|
145
soc/nordic/nrf54h/power.c
Normal file
145
soc/nordic/nrf54h/power.c
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/sys/poweroff.h>
|
||||||
|
#include <zephyr/toolchain.h>
|
||||||
|
#include <zephyr/pm/policy.h>
|
||||||
|
#include <zephyr/arch/common/pm_s2ram.h>
|
||||||
|
#include <hal/nrf_resetinfo.h>
|
||||||
|
#include <hal/nrf_lrcconf.h>
|
||||||
|
#include <hal/nrf_memconf.h>
|
||||||
|
#include <zephyr/cache.h>
|
||||||
|
#include <power.h>
|
||||||
|
#include "pm_s2ram.h"
|
||||||
|
|
||||||
|
static void suspend_common(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Flush, disable and power down DCACHE */
|
||||||
|
sys_cache_data_flush_all();
|
||||||
|
sys_cache_data_disable();
|
||||||
|
nrf_memconf_ramblock_control_enable_set(NRF_MEMCONF, RAMBLOCK_POWER_ID,
|
||||||
|
RAMBLOCK_CONTROL_BIT_DCACHE, false);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_ICACHE)) {
|
||||||
|
/* Disable and power down ICACHE */
|
||||||
|
sys_cache_instr_disable();
|
||||||
|
nrf_memconf_ramblock_control_enable_set(NRF_MEMCONF, RAMBLOCK_POWER_ID,
|
||||||
|
RAMBLOCK_CONTROL_BIT_ICACHE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable retention */
|
||||||
|
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, false);
|
||||||
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nrf_poweroff(void)
|
||||||
|
{
|
||||||
|
nrf_resetinfo_resetreas_local_set(NRF_RESETINFO, 0);
|
||||||
|
nrf_resetinfo_restore_valid_set(NRF_RESETINFO, false);
|
||||||
|
|
||||||
|
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, false);
|
||||||
|
|
||||||
|
/* TODO: Move it around k_cpu_idle() implementation. */
|
||||||
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, false);
|
||||||
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, false);
|
||||||
|
|
||||||
|
suspend_common();
|
||||||
|
|
||||||
|
nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_SYSTEMOFFREADY);
|
||||||
|
|
||||||
|
__set_BASEPRI(0);
|
||||||
|
__ISB();
|
||||||
|
__DSB();
|
||||||
|
__WFI();
|
||||||
|
|
||||||
|
CODE_UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_PM_S2RAM)
|
||||||
|
/* Resume domain after local suspend to RAM. */
|
||||||
|
static void sys_resume(void)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_ICACHE)) {
|
||||||
|
/* Power up and re-enable ICACHE */
|
||||||
|
nrf_memconf_ramblock_control_enable_set(NRF_MEMCONF, RAMBLOCK_POWER_ID,
|
||||||
|
RAMBLOCK_CONTROL_BIT_ICACHE, true);
|
||||||
|
sys_cache_instr_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_DCACHE)) {
|
||||||
|
/* Power up and re-enable DCACHE */
|
||||||
|
nrf_memconf_ramblock_control_enable_set(NRF_MEMCONF, RAMBLOCK_POWER_ID,
|
||||||
|
RAMBLOCK_CONTROL_BIT_DCACHE, true);
|
||||||
|
sys_cache_data_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-enable domain retention. */
|
||||||
|
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true);
|
||||||
|
|
||||||
|
/* TODO: Move it around k_cpu_idle() implementation. */
|
||||||
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN,
|
||||||
|
!IS_ENABLED(CONFIG_SOC_NRF54H20_CPURAD));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function called during local domain suspend to RAM. */
|
||||||
|
static int sys_suspend_to_ram(void)
|
||||||
|
{
|
||||||
|
/* Set intormation which is used on domain wakeup to determine if resume from RAM shall
|
||||||
|
* be performed.
|
||||||
|
*/
|
||||||
|
nrf_resetinfo_resetreas_local_set(NRF_RESETINFO,
|
||||||
|
NRF_RESETINFO_RESETREAS_LOCAL_UNRETAINED_MASK);
|
||||||
|
nrf_resetinfo_restore_valid_set(NRF_RESETINFO, true);
|
||||||
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, false);
|
||||||
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, false);
|
||||||
|
|
||||||
|
suspend_common();
|
||||||
|
|
||||||
|
__set_BASEPRI(0);
|
||||||
|
__ISB();
|
||||||
|
__DSB();
|
||||||
|
__WFI();
|
||||||
|
/*
|
||||||
|
* We might reach this point is k_cpu_idle returns (there is a pre sleep hook that
|
||||||
|
* can abort sleeping.
|
||||||
|
*/
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_suspend_to_ram(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Save the CPU context (including the return address),set the SRAM
|
||||||
|
* marker and power off the system.
|
||||||
|
*/
|
||||||
|
if (soc_s2ram_suspend(sys_suspend_to_ram)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On resuming or error we return exactly *HERE*
|
||||||
|
*/
|
||||||
|
|
||||||
|
sys_resume();
|
||||||
|
}
|
||||||
|
#endif /* IS_ENABLED(CONFIG_PM_S2RAM) */
|
||||||
|
|
||||||
|
void pm_state_set(enum pm_state state, uint8_t substate_id)
|
||||||
|
{
|
||||||
|
if (state != PM_STATE_SUSPEND_TO_RAM) {
|
||||||
|
k_cpu_idle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if IS_ENABLED(CONFIG_PM_S2RAM)
|
||||||
|
do_suspend_to_ram();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
|
||||||
|
{
|
||||||
|
irq_unlock(0);
|
||||||
|
}
|
20
soc/nordic/nrf54h/power.h
Normal file
20
soc/nordic/nrf54h/power.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file Common power.h include for Nordic SoCs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ZEPHYR_SOC_ARM_NORDIC_NRF_POWER_H_
|
||||||
|
#define _ZEPHYR_SOC_ARM_NORDIC_NRF_POWER_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform a power off.
|
||||||
|
*
|
||||||
|
* This function performs a power off of the core.
|
||||||
|
*/
|
||||||
|
void nrf_poweroff(void);
|
||||||
|
|
||||||
|
#endif /* _ZEPHYR_SOC_ARM_NORDIC_NRF_POWER_H_ */
|
|
@ -13,6 +13,7 @@
|
||||||
#include <hal/nrf_hsfll.h>
|
#include <hal/nrf_hsfll.h>
|
||||||
#include <hal/nrf_lrcconf.h>
|
#include <hal/nrf_lrcconf.h>
|
||||||
#include <hal/nrf_spu.h>
|
#include <hal/nrf_spu.h>
|
||||||
|
#include <hal/nrf_memconf.h>
|
||||||
#include <soc/nrfx_coredep.h>
|
#include <soc/nrfx_coredep.h>
|
||||||
#include <dmm.h>
|
#include <dmm.h>
|
||||||
|
|
||||||
|
@ -47,11 +48,35 @@ static void power_domain_init(void)
|
||||||
* WFI the power domain will be correctly retained.
|
* WFI the power domain will be correctly retained.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, true);
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0,
|
||||||
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true);
|
!IS_ENABLED(CONFIG_SOC_NRF54H20_CPURAD));
|
||||||
|
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN,
|
||||||
|
!IS_ENABLED(CONFIG_SOC_NRF54H20_CPURAD));
|
||||||
|
|
||||||
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, true);
|
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, true);
|
||||||
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true);
|
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true);
|
||||||
|
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_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;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int trim_hsfll(void)
|
static int trim_hsfll(void)
|
||||||
|
|
|
@ -9,4 +9,31 @@
|
||||||
|
|
||||||
#include <soc_nrf_common.h>
|
#include <soc_nrf_common.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_SOC_NRF54H20_CPUAPP)
|
||||||
|
#define RAMBLOCK_CONTROL_BIT_ICACHE MEMCONF_POWER_CONTROL_MEM1_Pos
|
||||||
|
#define RAMBLOCK_CONTROL_BIT_DCACHE MEMCONF_POWER_CONTROL_MEM2_Pos
|
||||||
|
#define RAMBLOCK_POWER_ID 0
|
||||||
|
#define RAMBLOCK_CONTROL_OFF 0
|
||||||
|
#define RAMBLOCK_RET_MASK (MEMCONF_POWER_RET_MEM0_Msk)
|
||||||
|
#define RAMBLOCK_RET_BIT_ICACHE MEMCONF_POWER_RET_MEM1_Pos
|
||||||
|
#define RAMBLOCK_RET_BIT_DCACHE MEMCONF_POWER_RET_MEM2_Pos
|
||||||
|
#elif defined(CONFIG_SOC_NRF54H20_CPURAD)
|
||||||
|
#define RAMBLOCK_CONTROL_BIT_ICACHE MEMCONF_POWER_CONTROL_MEM6_Pos
|
||||||
|
#define RAMBLOCK_CONTROL_BIT_DCACHE MEMCONF_POWER_CONTROL_MEM7_Pos
|
||||||
|
#define RAMBLOCK_POWER_ID 0
|
||||||
|
#define RAMBLOCK_CONTROL_OFF 0
|
||||||
|
#define RAMBLOCK_RET_MASK \
|
||||||
|
(MEMCONF_POWER_RET_MEM0_Msk | MEMCONF_POWER_RET_MEM1_Msk | MEMCONF_POWER_RET_MEM2_Msk | \
|
||||||
|
MEMCONF_POWER_RET_MEM3_Msk | MEMCONF_POWER_RET_MEM4_Msk | MEMCONF_POWER_RET_MEM5_Msk | \
|
||||||
|
MEMCONF_POWER_RET_MEM8_Msk)
|
||||||
|
#define RAMBLOCK_RET2_MASK \
|
||||||
|
(MEMCONF_POWER_RET2_MEM0_Msk | MEMCONF_POWER_RET2_MEM1_Msk | MEMCONF_POWER_RET2_MEM2_Msk | \
|
||||||
|
MEMCONF_POWER_RET2_MEM3_Msk | MEMCONF_POWER_RET2_MEM4_Msk | MEMCONF_POWER_RET2_MEM5_Msk | \
|
||||||
|
MEMCONF_POWER_RET2_MEM8_Msk)
|
||||||
|
#define RAMBLOCK_RET_BIT_ICACHE MEMCONF_POWER_RET_MEM6_Pos
|
||||||
|
#define RAMBLOCK_RET_BIT_DCACHE MEMCONF_POWER_RET_MEM7_Pos
|
||||||
|
#define RAMBLOCK_RET2_BIT_ICACHE MEMCONF_POWER_RET2_MEM6_Pos
|
||||||
|
#define RAMBLOCK_RET2_BIT_DCACHE MEMCONF_POWER_RET2_MEM7_Pos
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ */
|
#endif /* SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue