soc: nordic: nrf54h: power: Enable cache as early as possible
Add nrf_cache_power_up and nrf_cache_power_down functions. In case of s2ram power up cache as early as possible, before restoring ARM core registers. It improves restore time from 180 us to 33 us. As a minor optimization nrf_memconf_ramblock_control_mask_enable_set is used which allows to control ram blocks for icache and dcache in a single register write. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
0270704bcb
commit
a36b154fd1
3 changed files with 46 additions and 29 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
#include <hal/nrf_resetinfo.h>
|
#include <hal/nrf_resetinfo.h>
|
||||||
#include "pm_s2ram.h"
|
#include "pm_s2ram.h"
|
||||||
|
#include "power.h"
|
||||||
|
|
||||||
#include <cmsis_core.h>
|
#include <cmsis_core.h>
|
||||||
|
|
||||||
|
@ -170,6 +171,8 @@ int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nrf_power_up_cache();
|
||||||
|
|
||||||
mpu_resume(&backup_data.mpu_context);
|
mpu_resume(&backup_data.mpu_context);
|
||||||
nvic_resume(&backup_data.nvic_context);
|
nvic_resume(&backup_data.nvic_context);
|
||||||
scb_resume(&backup_data.scb_context);
|
scb_resume(&backup_data.scb_context);
|
||||||
|
|
|
@ -18,42 +18,50 @@
|
||||||
|
|
||||||
extern sys_snode_t soc_node;
|
extern sys_snode_t soc_node;
|
||||||
|
|
||||||
|
static void nrf_power_down_cache(void)
|
||||||
|
{
|
||||||
|
static const uint32_t msk =
|
||||||
|
(IS_ENABLED(CONFIG_DCACHE) ? BIT(RAMBLOCK_CONTROL_BIT_DCACHE) : 0) |
|
||||||
|
(IS_ENABLED(CONFIG_ICACHE) ? BIT(RAMBLOCK_CONTROL_BIT_ICACHE) : 0);
|
||||||
|
|
||||||
|
if (msk == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Functions are non-empty only if cache is enabled.
|
||||||
|
* Data cache disabling include flushing.
|
||||||
|
*/
|
||||||
|
sys_cache_data_disable();
|
||||||
|
sys_cache_instr_disable();
|
||||||
|
nrf_memconf_ramblock_control_mask_enable_set(NRF_MEMCONF, RAMBLOCK_POWER_ID, msk, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nrf_power_up_cache(void)
|
||||||
|
{
|
||||||
|
static const uint32_t msk =
|
||||||
|
(IS_ENABLED(CONFIG_DCACHE) ? BIT(RAMBLOCK_CONTROL_BIT_DCACHE) : 0) |
|
||||||
|
(IS_ENABLED(CONFIG_ICACHE) ? BIT(RAMBLOCK_CONTROL_BIT_ICACHE) : 0);
|
||||||
|
|
||||||
|
if (msk == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf_memconf_ramblock_control_mask_enable_set(NRF_MEMCONF, RAMBLOCK_POWER_ID, msk, true);
|
||||||
|
sys_cache_instr_enable();
|
||||||
|
sys_cache_data_enable();
|
||||||
|
}
|
||||||
|
|
||||||
static void common_suspend(void)
|
static void common_suspend(void)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_DCACHE)) {
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
|
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
|
||||||
|
nrf_power_down_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void common_resume(void)
|
static void common_resume(void)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_ICACHE)) {
|
/* Common part does not include cache enabling. In case of s2ram it is done
|
||||||
/* Power up and re-enable ICACHE */
|
* as early as possible to speed up the process.
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
|
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +120,7 @@ static void s2idle_exit(uint8_t substate_id)
|
||||||
case 1: /* Substate for idle with cache retained - not implemented yet. */
|
case 1: /* Substate for idle with cache retained - not implemented yet. */
|
||||||
break;
|
break;
|
||||||
case 2: /* Substate for idle with cache disabled. */
|
case 2: /* Substate for idle with cache disabled. */
|
||||||
|
nrf_power_up_cache();
|
||||||
common_resume();
|
common_resume();
|
||||||
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
|
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
|
||||||
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN);
|
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN);
|
||||||
|
|
|
@ -17,4 +17,9 @@
|
||||||
*/
|
*/
|
||||||
void nrf_poweroff(void);
|
void nrf_poweroff(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power up and enable instruction and data cache.
|
||||||
|
*/
|
||||||
|
void nrf_power_up_cache(void);
|
||||||
|
|
||||||
#endif /* _ZEPHYR_SOC_ARM_NORDIC_NRF_POWER_H_ */
|
#endif /* _ZEPHYR_SOC_ARM_NORDIC_NRF_POWER_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue