soc: nordic: Add LRCCONF management
Due to the possibility of simultaneous accesess to LRCCONF registers, additional management is required. Signed-off-by: Adam Kondraciuk <adam.kondraciuk@nordicsemi.no>
This commit is contained in:
parent
d5262b2113
commit
9b252855fd
9 changed files with 220 additions and 117 deletions
|
@ -12,6 +12,9 @@ if(CONFIG_ARM)
|
|||
endif()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c)
|
||||
if(CONFIG_ARM)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRF_PLATFORM_HALTIUM soc_lrcconf.c)
|
||||
endif()
|
||||
|
||||
if((CONFIG_SOC_SERIES_NRF54HX OR CONFIG_SOC_SERIES_NRF92X) AND CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS)
|
||||
zephyr_library_sources(nrf54hx_nrf92x_mpu_regions.c)
|
||||
|
|
62
soc/nordic/common/soc_lrcconf.c
Normal file
62
soc/nordic/common/soc_lrcconf.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <soc_lrcconf.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
static struct k_spinlock lock;
|
||||
static sys_slist_t poweron_main_list;
|
||||
static sys_slist_t poweron_active_list;
|
||||
|
||||
void soc_lrcconf_poweron_request(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain)
|
||||
{
|
||||
__ASSERT(is_power_of_two(domain), "Only one bit can be set for the domain parameter");
|
||||
|
||||
sys_slist_t *poweron_list;
|
||||
|
||||
if (domain == NRF_LRCCONF_POWER_MAIN) {
|
||||
poweron_list = &poweron_main_list;
|
||||
} else if (domain == NRF_LRCCONF_POWER_DOMAIN_0) {
|
||||
poweron_list = &poweron_active_list;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
K_SPINLOCK(&lock) {
|
||||
if (sys_slist_len(poweron_list) == 0) {
|
||||
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, domain, true);
|
||||
}
|
||||
|
||||
sys_slist_find_and_remove(poweron_list, node);
|
||||
sys_slist_append(poweron_list, node);
|
||||
}
|
||||
}
|
||||
|
||||
void soc_lrcconf_poweron_release(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain)
|
||||
{
|
||||
__ASSERT(is_power_of_two(domain), "Only one bit can be set for the domain parameter");
|
||||
|
||||
sys_slist_t *poweron_list;
|
||||
|
||||
if (domain == NRF_LRCCONF_POWER_MAIN) {
|
||||
poweron_list = &poweron_main_list;
|
||||
} else if (domain == NRF_LRCCONF_POWER_DOMAIN_0) {
|
||||
poweron_list = &poweron_active_list;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
K_SPINLOCK(&lock) {
|
||||
if (!sys_slist_find_and_remove(poweron_list, node)) {
|
||||
K_SPINLOCK_BREAK;
|
||||
}
|
||||
|
||||
if (sys_slist_len(poweron_list) > 0) {
|
||||
K_SPINLOCK_BREAK;
|
||||
}
|
||||
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, domain, false);
|
||||
}
|
||||
}
|
34
soc/nordic/common/soc_lrcconf.h
Normal file
34
soc/nordic/common/soc_lrcconf.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file nRF SoC specific helpers for lrcconf management
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_NORDIC_COMMON_LRCCONF_H_
|
||||
#define ZEPHYR_SOC_NORDIC_COMMON_LRCCONF_H_
|
||||
|
||||
#include <hal/nrf_lrcconf.h>
|
||||
|
||||
/**
|
||||
* @brief Request lrcconf power domain
|
||||
*
|
||||
* @param node Pointer to the @ref sys_snode_t structure which is the ID of the
|
||||
* requesting module.
|
||||
* @param domain The mask that represents the power domain ID.
|
||||
*/
|
||||
void soc_lrcconf_poweron_request(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain);
|
||||
|
||||
/**
|
||||
* @brief Release lrcconf power domain
|
||||
*
|
||||
* @param node Pointer to the @ref sys_snode_t structure which is the ID of the
|
||||
* requesting module.
|
||||
* @param domain The mask that represents the power domain ID.
|
||||
*/
|
||||
void soc_lrcconf_poweron_release(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain);
|
||||
|
||||
#endif /* ZEPHYR_SOC_NORDIC_COMMON_LRCCONF_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue