Skip to content
Merged
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
19 changes: 16 additions & 3 deletions drivers/spi/spi_nrfx_spis.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ LOG_MODULE_REGISTER(spi_nrfx_spis, CONFIG_SPI_LOG_LEVEL);
#include <nrf/gpd.h>
#endif

#define SPIS_IS_FAST(idx) IS_EQ(idx, 120)

#define NRFX_SPIS_IS_FAST(unused, prefix, id, _) SPIS_IS_FAST(prefix##id)

#if NRFX_FOREACH_ENABLED(SPIS, NRFX_SPIS_IS_FAST, (+), (0), _)
/* If fast instances are used then system managed device PM cannot be used because
* it may call PM actions from locked context and fast SPIM PM actions can only be
* called from a thread context.
*/
BUILD_ASSERT(!IS_ENABLED(CONFIG_PM_DEVICE_SYSTEM_MANAGED));
#endif

struct spi_nrfx_data {
struct spi_context ctx;
const struct device *dev;
Expand Down Expand Up @@ -335,7 +347,7 @@ static void event_handler(const nrfx_spis_evt_t *p_event, void *p_context)
spi_context_complete(&dev_data->ctx, dev_data->dev,
p_event->rx_amount);

pm_device_runtime_put(dev_data->dev);
pm_device_runtime_put_async(dev_data->dev, K_NO_WAIT);
}
}

Expand Down Expand Up @@ -457,7 +469,7 @@ static int spi_nrfx_init(const struct device *dev)
* - Name-based HAL IRQ handlers, e.g. nrfx_spis_0_irq_handler
*/

#define SPIS_NODE(idx) COND_CODE_1(IS_EQ(idx, 120), (spis##idx), (spi##idx))
#define SPIS_NODE(idx) COND_CODE_1(SPIS_IS_FAST(idx), (spis##idx), (spi##idx))

#define SPIS(idx) DT_NODELABEL(SPIS_NODE(idx))

Expand Down Expand Up @@ -502,7 +514,8 @@ static int spi_nrfx_init(const struct device *dev)
BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIS(idx), wake_gpios) || \
!(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
"WAKE line must be configured as active high"); \
PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, 1); \
PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, \
COND_CODE_1(SPIS_IS_FAST(idx), (0), (PM_DEVICE_ISR_SAFE))); \
SPI_DEVICE_DT_DEFINE(SPIS(idx), \
spi_nrfx_init, \
PM_DEVICE_DT_GET(SPIS(idx)), \
Expand Down
4 changes: 2 additions & 2 deletions dts/common/nordic/nrf54h20.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@
power-state-name = "suspend-to-idle";
substate-id = <2>;
min-residency-us = <1000>;
exit-latency-us = <30>;
exit-latency-us = <7>;
};
s2ram: s2ram {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-ram";
min-residency-us = <2000>;
exit-latency-us = <260>;
exit-latency-us = <33>;
};
};
};
Expand Down
3 changes: 3 additions & 0 deletions soc/nordic/nrf54h/pm_s2ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <zephyr/sys/util.h>
#include <hal/nrf_resetinfo.h>
#include "pm_s2ram.h"
#include "power.h"

#include <cmsis_core.h>

Expand Down Expand Up @@ -166,6 +167,8 @@ int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off)
nvic_suspend(&backup_data.nvic_context);
mpu_suspend(&backup_data.mpu_context);
ret = arch_pm_s2ram_suspend(system_off);
/* Cache is powered down so power up is needed even if s2ram failed. */
nrf_power_up_cache();
if (ret < 0) {
return ret;
}
Expand Down
61 changes: 35 additions & 26 deletions soc/nordic/nrf54h/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,50 @@

extern sys_snode_t soc_node;

static void common_suspend(void)
static void nrf_power_down_cache(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);
}
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 (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);
if (msk == 0) {
return;
}

soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
/* 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);
}

static void common_resume(void)
void nrf_power_up_cache(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();
}
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 (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();
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)
{
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
nrf_power_down_cache();
}

static void common_resume(void)
{
/* Common part does not include cache enabling. In case of s2ram it is done
* as early as possible to speed up the process.
*/
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
}

Expand Down Expand Up @@ -112,6 +120,7 @@ static void s2idle_exit(uint8_t substate_id)
case 1: /* Substate for idle with cache retained - not implemented yet. */
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);
Expand Down
5 changes: 5 additions & 0 deletions soc/nordic/nrf54h/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@
*/
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_ */
Loading