manifest: Adding nRF Services library
Adding nRF Services library to the hal-nordic repo Signed-off-by: Rafal Dyla <rafal.dyla@nordicsemi.no>
This commit is contained in:
parent
557ad8e45c
commit
13aa26eac2
18 changed files with 1368 additions and 2 deletions
|
@ -72,7 +72,7 @@
|
|||
shared_ram20_region: memory@2f88f000 {
|
||||
compatible = "nordic,owned-memory";
|
||||
reg = <0x2f88f000 DT_SIZE_K(4)>;
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
perm-read;
|
||||
perm-write;
|
||||
#address-cells = <1>;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
sw1 = &button1;
|
||||
sw2 = &button2;
|
||||
sw3 = &button3;
|
||||
ipc-to-cpusys = &cpuapp_cpusys_ipc;
|
||||
};
|
||||
|
||||
buttons {
|
||||
|
@ -117,6 +118,10 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&cpusys_vevif {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpusec_cpuapp_ipc {
|
||||
mbox-names = "tx", "rx";
|
||||
tx-region = <&cpuapp_cpusec_ipc_shm>;
|
||||
|
@ -133,6 +138,7 @@ ipc0: &cpuapp_cpurad_ipc {
|
|||
};
|
||||
|
||||
&cpuapp_cpusys_ipc {
|
||||
status = "okay";
|
||||
mbox-names = "rx", "tx";
|
||||
tx-region = <&cpuapp_cpusys_ipc_shm>;
|
||||
rx-region = <&cpusys_cpuapp_ipc_shm>;
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
zephyr,bt-hci-ipc = &ipc0;
|
||||
nordic,802154-spinel-ipc = &ipc0;
|
||||
};
|
||||
aliases {
|
||||
ipc-to-cpusys = &cpurad_cpusys_ipc;
|
||||
};
|
||||
};
|
||||
|
||||
&shared_ram3x_region {
|
||||
|
@ -51,6 +54,10 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&cpusys_vevif {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpusec_cpurad_ipc {
|
||||
mbox-names = "tx", "rx";
|
||||
tx-region = <&cpurad_cpusec_ipc_shm>;
|
||||
|
@ -67,6 +74,7 @@ ipc0: &cpuapp_cpurad_ipc {
|
|||
};
|
||||
|
||||
&cpurad_cpusys_ipc {
|
||||
status = "okay";
|
||||
mbox-names = "rx", "tx";
|
||||
tx-region = <&cpurad_cpusys_ipc_shm>;
|
||||
rx-region = <&cpusys_cpurad_ipc_shm>;
|
||||
|
|
|
@ -6,12 +6,13 @@ if (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION)
|
|||
endif (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION)
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_HAS_NRFX nrfx)
|
||||
add_subdirectory_ifdef(CONFIG_HAS_NRFS nrfs)
|
||||
|
||||
if(CONFIG_NRF_REGTOOL_GENERATE_UICR)
|
||||
list(APPEND nrf_regtool_components GENERATE:UICR)
|
||||
endif()
|
||||
if(DEFINED nrf_regtool_components)
|
||||
find_package(nrf-regtool 5.1.0
|
||||
find_package(nrf-regtool 5.2.0
|
||||
COMPONENTS ${nrf_regtool_components}
|
||||
PATHS ${CMAKE_CURRENT_LIST_DIR}/nrf-regtool
|
||||
NO_CMAKE_PATH
|
||||
|
|
|
@ -235,5 +235,6 @@ endif # NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION
|
|||
|
||||
endmenu # HAS_NORDIC_DRIVERS
|
||||
|
||||
rsource "nrfs/Kconfig"
|
||||
rsource "nrfx/Kconfig"
|
||||
rsource "Kconfig.nrf_regtool"
|
||||
|
|
41
modules/hal_nordic/nrfs/CMakeLists.txt
Normal file
41
modules/hal_nordic/nrfs/CMakeLists.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
if(CONFIG_NRFS)
|
||||
zephyr_library()
|
||||
if(NOT DEFINED NRFS_DIR)
|
||||
set(NRFS_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/nrfs CACHE PATH "nrfs directory")
|
||||
endif()
|
||||
|
||||
set(INC_DIR ${NRFS_DIR}/include)
|
||||
set(SRC_DIR ${NRFS_DIR}/src)
|
||||
set(HELPERS_DIR ${NRFS_DIR}/helpers)
|
||||
|
||||
zephyr_include_directories(${INC_DIR})
|
||||
zephyr_include_directories(${INC_DIR}/services)
|
||||
zephyr_include_directories(${HELPERS_DIR})
|
||||
zephyr_include_directories(.)
|
||||
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/backends)
|
||||
zephyr_include_directories_ifdef(CONFIG_NRFS_DVFS_LOCAL_DOMAIN ${CMAKE_CURRENT_SOURCE_DIR}/dvfs)
|
||||
|
||||
zephyr_library_sources(${HELPERS_DIR}/dvfs_oppoint.c)
|
||||
|
||||
if(CONFIG_NRFS_LOCAL_DOMAIN)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_CLOCK_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_clock.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_DIAG_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_diag.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_DVFS_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_dvfs.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_MRAM_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_mram.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_PMIC_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_pmic.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_RESET_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_reset.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_TEMP_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_temp.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_VBUS_DETECTOR_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_usb.c)
|
||||
zephyr_library_sources(${SRC_DIR}/internal/nrfs_dispatcher.c)
|
||||
add_subdirectory_ifdef(CONFIG_NRFS_DVFS_LOCAL_DOMAIN dvfs)
|
||||
|
||||
if(CONFIG_NRFS_DIAG_SERVICE_ENABLED)
|
||||
message(WARNING "This service is for Nordic Semiconductor INTERNAL purposes ONLY. Use it with caution due to risk of hardware damage!")
|
||||
endif()
|
||||
endif()
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_LOCAL_DOMAIN backends/nrfs_backend_ipc_service.c)
|
||||
endif()
|
116
modules/hal_nordic/nrfs/Kconfig
Normal file
116
modules/hal_nordic/nrfs/Kconfig
Normal file
|
@ -0,0 +1,116 @@
|
|||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config HAS_NRFS
|
||||
bool
|
||||
|
||||
menu "nRF Services"
|
||||
depends on HAS_NRFS
|
||||
|
||||
config NRFS_HAS_CLOCK_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_CONST_LATENCY_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_DIAG_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_DVFS_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_MRAM_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_PMIC_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_RESET_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_TEMP_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS_HAS_VBUS_DETECTOR_SERVICE
|
||||
bool
|
||||
|
||||
config NRFS
|
||||
bool "nRF Services Support"
|
||||
select NRFS_LOCAL_DOMAIN if (SOC_NRF54H20_CPUAPP || SOC_NRF54H20_CPURAD)
|
||||
depends on HAS_NRFS
|
||||
help
|
||||
This option enables the nRF Services library.
|
||||
|
||||
if NRFS
|
||||
|
||||
config NRFS_LOCAL_DOMAIN
|
||||
bool "nRF Services Local Domain Support"
|
||||
depends on $(dt_alias_enabled,ipc-to-cpusys)
|
||||
select IPC_SERVICE
|
||||
select MBOX
|
||||
select EVENTS
|
||||
select REBOOT
|
||||
help
|
||||
This option enables the nRF Services Local Domain libraries.
|
||||
|
||||
config NRFS_DVFS_LOCAL_DOMAIN
|
||||
bool "Local domain that supports DVFS"
|
||||
depends on NRFS_LOCAL_DOMAIN
|
||||
depends on NRFS_DVFS_SERVICE_ENABLED
|
||||
default y if NRFS_DVFS_SERVICE_ENABLED
|
||||
|
||||
menu "Enabled Services"
|
||||
|
||||
module = NRFS
|
||||
module-str = nRF-Services
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
config NRFS_RESET_SERVICE_ENABLED
|
||||
bool "Reset service"
|
||||
depends on NRFS_HAS_RESET_SERVICE
|
||||
|
||||
config NRFS_MRAM_SERVICE_ENABLED
|
||||
bool "MRAM latency service"
|
||||
depends on NRFS_HAS_MRAM_SERVICE
|
||||
|
||||
config NRFS_TEMP_SERVICE_ENABLED
|
||||
bool "Temperature service"
|
||||
depends on NRFS_HAS_TEMP_SERVICE
|
||||
default y
|
||||
|
||||
config NRFS_VBUS_DETECTOR_SERVICE_ENABLED
|
||||
bool "VBUS detector for the USB peripheral"
|
||||
depends on NRFS_HAS_VBUS_DETECTOR_SERVICE
|
||||
default y
|
||||
|
||||
config NRFS_CONST_LATENCY_SERVICE_ENABLED
|
||||
bool "DPPI constant latency service"
|
||||
depends on NRFS_HAS_CONST_LATENCY_SERVICE
|
||||
default y
|
||||
|
||||
config NRFS_PMIC_SERVICE_ENABLED
|
||||
bool "PMIC service"
|
||||
depends on NRFS_HAS_PMIC_SERVICE
|
||||
|
||||
config NRFS_DVFS_SERVICE_ENABLED
|
||||
bool "DVFS service"
|
||||
depends on NRFS_HAS_DVFS_SERVICE
|
||||
default y if SOC_NRF54H20_CPUAPP
|
||||
|
||||
config NRFS_DIAG_SERVICE_ENABLED
|
||||
bool "System Diagnostics service (only for development purposes)"
|
||||
depends on NRFS_HAS_DIAG_SERVICE
|
||||
|
||||
config NRFS_CLOCK_SERVICE_ENABLED
|
||||
bool "Clock service"
|
||||
depends on NRFS_HAS_CLOCK_SERVICE
|
||||
default y
|
||||
endmenu
|
||||
|
||||
rsource "backends/Kconfig"
|
||||
if NRFS_DVFS_LOCAL_DOMAIN
|
||||
rsource "dvfs/Kconfig"
|
||||
endif # NRFS_DVFS_LOCAL_DOMAIN
|
||||
|
||||
endif # NRFS
|
||||
endmenu
|
28
modules/hal_nordic/nrfs/backends/Kconfig
Normal file
28
modules/hal_nordic/nrfs/backends/Kconfig
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
menu "NRFS backend settings"
|
||||
|
||||
module = NRFS_BACKEND
|
||||
module-str = NRFS backend
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
config NRFS_BACKEND_IPC_SERVICE_INIT_PRIO
|
||||
int "Initialization priority for NRFS IPC backend"
|
||||
default 51
|
||||
help
|
||||
This should be higher than priority of other drivers/subsystems
|
||||
used by NRFS backend. For example MBOX_INIT_PRIORITY which is 50.
|
||||
|
||||
config NRFS_MAX_BACKEND_PACKET_SIZE
|
||||
int "Maximum IPC data packet size in bytes"
|
||||
range 8 128
|
||||
default 32
|
||||
|
||||
config NRFS_BACKEND_TX_MSG_QUEUE_SIZE
|
||||
int "Size of TX buffer message queue size"
|
||||
range 1 16
|
||||
default 8
|
||||
|
||||
endmenu
|
226
modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c
Normal file
226
modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "nrfs_backend_ipc_service.h"
|
||||
|
||||
#include <internal/nrfs_backend.h>
|
||||
#include <internal/nrfs_dispatcher.h>
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/reboot.h>
|
||||
#include <zephyr/sys_clock.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/init.h>
|
||||
|
||||
LOG_MODULE_REGISTER(NRFS_BACKEND, CONFIG_NRFS_BACKEND_LOG_LEVEL);
|
||||
|
||||
#define MAX_PACKET_DATA_SIZE (CONFIG_NRFS_MAX_BACKEND_PACKET_SIZE)
|
||||
|
||||
K_MSGQ_DEFINE(ipc_transmit_msgq, sizeof(struct ipc_data_packet),
|
||||
CONFIG_NRFS_BACKEND_TX_MSG_QUEUE_SIZE, 4);
|
||||
|
||||
static struct k_work backend_send_work;
|
||||
|
||||
static struct ipc_data_packet rx_data;
|
||||
static struct ipc_data_packet tx_data;
|
||||
|
||||
static void ipc_sysctrl_ept_bound(void *priv);
|
||||
static void ipc_sysctrl_ept_recv(const void *data, size_t size, void *priv);
|
||||
|
||||
static K_EVENT_DEFINE(ipc_connected_event);
|
||||
|
||||
#define IPC_INIT_DONE_EVENT (0x01)
|
||||
|
||||
struct ipc_channel_config {
|
||||
const struct device *ipc_instance;
|
||||
struct ipc_ept_cfg *endpoint_config;
|
||||
struct ipc_ept ipc_ept;
|
||||
atomic_t status;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static struct ipc_ept_cfg ipc_sysctrl_ept_cfg = {
|
||||
.name = "ipc_to_sysctrl",
|
||||
.cb = {
|
||||
.bound = ipc_sysctrl_ept_bound,
|
||||
.received = ipc_sysctrl_ept_recv,
|
||||
},
|
||||
};
|
||||
|
||||
static struct ipc_channel_config ipc_cpusys_channel_config = {
|
||||
.ipc_instance = DEVICE_DT_GET(DT_ALIAS(ipc_to_cpusys)),
|
||||
.endpoint_config = &ipc_sysctrl_ept_cfg,
|
||||
.status = ATOMIC_INIT(NOT_CONNECTED),
|
||||
.enabled = true
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief nrfs backend error handler
|
||||
*
|
||||
* @param error_id The id of an error to handle.
|
||||
* @param error additional error code if needed, if not needed use 0.
|
||||
* @param fatal true if fatal error and needs special handling
|
||||
*/
|
||||
__weak void nrfs_backend_error_handler(enum nrfs_backend_error error_id, int error, bool fatal)
|
||||
{
|
||||
switch (error_id) {
|
||||
case NRFS_ERROR_EPT_RECEIVE_DATA_TOO_LONG:
|
||||
LOG_ERR("Received data is too long. Config error.");
|
||||
break;
|
||||
|
||||
case NRFS_ERROR_NO_DATA_RECEIVED:
|
||||
LOG_ERR("No data in received message!");
|
||||
break;
|
||||
|
||||
case NRFS_ERROR_IPC_OPEN_INSTANCE:
|
||||
LOG_ERR("IPC open instance failure with error: %d", error);
|
||||
break;
|
||||
|
||||
case NRFS_ERROR_IPC_REGISTER_ENDPOINT:
|
||||
LOG_ERR("IPC register endpoint failure with error: %d", error);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_ERR("Undefined error id: %d, error cause: %d", error_id, error);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fatal) {
|
||||
nrfs_backend_fatal_error_handler(error_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void ipc_sysctrl_ept_bound(void *priv)
|
||||
{
|
||||
LOG_INF("Bound to sysctrl.");
|
||||
k_event_post(&ipc_connected_event, IPC_INIT_DONE_EVENT);
|
||||
atomic_set(&ipc_cpusys_channel_config.status, CONNECTED);
|
||||
}
|
||||
|
||||
static void ipc_sysctrl_ept_recv(const void *data, size_t size, void *priv)
|
||||
{
|
||||
__ASSERT(size <= MAX_PACKET_DATA_SIZE, "Received data is too long. Config error.");
|
||||
if (size <= MAX_PACKET_DATA_SIZE) {
|
||||
rx_data.channel_id = IPC_CPUSYS_CHANNEL_ID;
|
||||
rx_data.size = size;
|
||||
if (data) {
|
||||
memcpy(rx_data.data, (uint8_t *)data, size);
|
||||
nrfs_dispatcher_notify(&rx_data.data, rx_data.size);
|
||||
} else {
|
||||
nrfs_backend_error_handler(NRFS_ERROR_NO_DATA_RECEIVED, 0, false);
|
||||
}
|
||||
} else {
|
||||
nrfs_backend_error_handler(NRFS_ERROR_EPT_RECEIVE_DATA_TOO_LONG, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void nrfs_backend_send_work(struct k_work *item)
|
||||
{
|
||||
static struct ipc_data_packet data_to_send;
|
||||
|
||||
LOG_DBG("Sending data from workqueue");
|
||||
while (k_msgq_get(&ipc_transmit_msgq, &data_to_send, K_NO_WAIT) == 0) {
|
||||
ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, &tx_data.data, tx_data.size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize ipc channel
|
||||
*
|
||||
* @return -EINVAL when instance configuration is invalid.
|
||||
* @return -EIO when no backend is registered.
|
||||
* @return -EALREADY when the instance is already opened (or being opened).
|
||||
* @return -EBUSY when the instance is busy.
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int ipc_channel_init(void)
|
||||
{
|
||||
struct ipc_channel_config *ch_cfg;
|
||||
int ret = 0;
|
||||
|
||||
k_work_init(&backend_send_work, nrfs_backend_send_work);
|
||||
ch_cfg = &ipc_cpusys_channel_config;
|
||||
|
||||
ret = ipc_service_open_instance(ch_cfg->ipc_instance);
|
||||
if ((ret < 0) && (ret != -EALREADY)) {
|
||||
nrfs_backend_error_handler(NRFS_ERROR_IPC_OPEN_INSTANCE, ret, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LOG_INF("ipc_service_open_instance() done.");
|
||||
|
||||
ret = ipc_service_register_endpoint(ch_cfg->ipc_instance,
|
||||
&ch_cfg->ipc_ept,
|
||||
ch_cfg->endpoint_config);
|
||||
if (ret < 0) {
|
||||
nrfs_backend_error_handler(NRFS_ERROR_IPC_REGISTER_ENDPOINT, ret, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LOG_INF("ipc_service_register_endpoint() done.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
nrfs_err_t nrfs_backend_send(void *message, size_t size)
|
||||
{
|
||||
return nrfs_backend_send_ex(message, size, K_NO_WAIT, false);
|
||||
}
|
||||
|
||||
nrfs_err_t nrfs_backend_send_ex(void *message, size_t size, k_timeout_t timeout, bool high_prio)
|
||||
{
|
||||
if (atomic_get(&ipc_cpusys_channel_config.status) != CONNECTED) {
|
||||
LOG_WRN("Backend not yet connected to sysctrl");
|
||||
return NRFS_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (size <= MAX_PACKET_DATA_SIZE) {
|
||||
int err;
|
||||
|
||||
tx_data.channel_id = IPC_CPUSYS_CHANNEL_ID;
|
||||
tx_data.size = size;
|
||||
memcpy(tx_data.data, (uint8_t *)message, size);
|
||||
|
||||
err = k_msgq_put(&ipc_transmit_msgq, &tx_data, timeout);
|
||||
if (err) {
|
||||
return NRFS_ERR_IPC;
|
||||
}
|
||||
|
||||
err = k_work_submit(&backend_send_work);
|
||||
|
||||
return err >= 0 ? 0 : NRFS_ERR_IPC;
|
||||
}
|
||||
|
||||
LOG_ERR("Trying to send %d bytes where max is %d.", size, MAX_PACKET_DATA_SIZE);
|
||||
|
||||
return NRFS_ERR_IPC;
|
||||
}
|
||||
|
||||
bool nrfs_backend_connected(void)
|
||||
{
|
||||
return atomic_get(&ipc_cpusys_channel_config.status) == CONNECTED;
|
||||
}
|
||||
|
||||
int nrfs_backend_wait_for_connection(k_timeout_t timeout)
|
||||
{
|
||||
uint32_t events;
|
||||
|
||||
if (nrfs_backend_connected()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
events = k_event_wait(&ipc_connected_event, IPC_INIT_DONE_EVENT, false, timeout);
|
||||
|
||||
return (events == IPC_INIT_DONE_EVENT ? 0 : (-EAGAIN));
|
||||
}
|
||||
|
||||
__weak void nrfs_backend_fatal_error_handler(enum nrfs_backend_error error_id)
|
||||
{
|
||||
LOG_ERR("Fatal error: %d rebooting...", error_id);
|
||||
sys_reboot(SYS_REBOOT_WARM);
|
||||
}
|
||||
|
||||
SYS_INIT(ipc_channel_init, POST_KERNEL, CONFIG_NRFS_BACKEND_IPC_SERVICE_INIT_PRIO);
|
93
modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.h
Normal file
93
modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef NRFS_BACKEND_IPC_SERVICE_H
|
||||
#define NRFS_BACKEND_IPC_SERVICE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <nrfs_common.h>
|
||||
#include <zephyr/ipc/ipc_service.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct __packed ipc_data_packet {
|
||||
uint16_t channel_id;
|
||||
uint16_t size;
|
||||
uint8_t data[CONFIG_NRFS_MAX_BACKEND_PACKET_SIZE];
|
||||
};
|
||||
|
||||
enum ipc_channel_status {
|
||||
NOT_CONNECTED = 0,
|
||||
CONNECTED = 1
|
||||
};
|
||||
|
||||
enum nrfs_backend_error {
|
||||
NRFS_ERROR_EPT_RECEIVE_QUEUE_ERROR = 0,
|
||||
NRFS_ERROR_EPT_RECEIVE_DATA_TOO_LONG,
|
||||
NRFS_ERROR_IPC_CHANNEL_INIT,
|
||||
NRFS_ERROR_SEND_DATA,
|
||||
NRFS_ERROR_NO_DATA_RECEIVED,
|
||||
NRFS_ERROR_IPC_OPEN_INSTANCE,
|
||||
NRFS_ERROR_IPC_REGISTER_ENDPOINT,
|
||||
NRFS_ERROR_BACKEND_NOT_CONNECTED,
|
||||
NRFS_ERROR_COUNT
|
||||
};
|
||||
|
||||
#define IPC_CPUSYS_CHANNEL_ID 0x5C
|
||||
|
||||
/**
|
||||
* @brief function to check if backend is connected to sysctrl
|
||||
*
|
||||
* @return true Backend connected.
|
||||
* @return false Backend not connected.
|
||||
*/
|
||||
bool nrfs_backend_connected(void);
|
||||
|
||||
/**
|
||||
* @brief this function will block until connection or timeout expires
|
||||
*
|
||||
* @param timeout
|
||||
*
|
||||
* @return 0 Connection done.
|
||||
* @return -EAGAIN Waiting period timed out.
|
||||
*/
|
||||
int nrfs_backend_wait_for_connection(k_timeout_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Extended function for sending a message over the chosen transport backend.
|
||||
*
|
||||
* This function is used by services to send requests to the System Controller.
|
||||
*
|
||||
* @param[in] message Pointer to the message payload.
|
||||
* @param[in] size Message payload size.
|
||||
* @param[in] timeout Non-negative waiting period to add the message,
|
||||
* or one of the special values K_NO_WAIT and K_FOREVER.
|
||||
* @param[in] high_prio True if message should be sent with higher priority.
|
||||
*
|
||||
* @retval NRFS_SUCCESS Message sent successfully.
|
||||
* @retval NRFS_ERR_IPC Backend returned error during message sending.
|
||||
*/
|
||||
nrfs_err_t nrfs_backend_send_ex(void *message, size_t size, k_timeout_t timeout, bool high_prio);
|
||||
|
||||
/**
|
||||
* @brief Fatal error handler for unrecoverable errors
|
||||
*
|
||||
* This is weak function so it can be overridden if needed.
|
||||
* Error is considered fatal when there is no option to send message to sysctrl
|
||||
* even after retry. Communication with sysctrl is crucial for system to work properly.
|
||||
*
|
||||
* @param error_id parameter to identify error.
|
||||
*/
|
||||
void nrfs_backend_fatal_error_handler(enum nrfs_backend_error error_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRFS_BACKEND_IPC_SERVICE_H */
|
5
modules/hal_nordic/nrfs/dvfs/CMakeLists.txt
Normal file
5
modules/hal_nordic/nrfs/dvfs/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_NRFS_DVFS_LOCAL_DOMAIN ld_dvfs.c
|
||||
ld_dvfs_handler.c)
|
40
modules/hal_nordic/nrfs/dvfs/Kconfig
Normal file
40
modules/hal_nordic/nrfs/dvfs/Kconfig
Normal file
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
menu "Local domain DVFS library"
|
||||
|
||||
module = LOCAL_DOMAIN_DVFS_LIB
|
||||
module-str = Local domain DVFS library
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
config NRFS_LOCAL_DOMAIN_DVFS_TEST
|
||||
bool "Local domain DVFS test"
|
||||
help
|
||||
Disable hw registers interaction for testing.
|
||||
|
||||
config NRFS_LOCAL_DOMAIN_DVFS_SCALE_DOWN_AFTER_INIT
|
||||
bool "Local domain scale down after init"
|
||||
help
|
||||
Request lowest oppoint after DVFS initialization.
|
||||
|
||||
config NRFS_LOCAL_DOMAIN_DOWNSCALE_SAFETY_TIMEOUT_US
|
||||
int "Voltage downscale procedure safety timeout in us"
|
||||
range 1 10000000
|
||||
default 1000000 if (NRFS_LOCAL_DOMAIN_DVFS_TEST || LOG)
|
||||
default 1500
|
||||
|
||||
config NRFS_LOCAL_DOMAIN_DVFS_HANDLER_TASK_STACK_SIZE
|
||||
int "Stack size used for DVFS handling task"
|
||||
range 256 2048
|
||||
default 1024 if LOG
|
||||
default 512
|
||||
|
||||
config NRFS_LOCAL_DOMAIN_DVFS_HANDLER_TASK_PRIORITY
|
||||
int "Priority of DVFS handling task"
|
||||
range -16 NUM_PREEMPT_PRIORITIES
|
||||
default 0
|
||||
|
||||
endmenu
|
354
modules/hal_nordic/nrfs/dvfs/ld_dvfs.c
Normal file
354
modules/hal_nordic/nrfs/dvfs/ld_dvfs.c
Normal file
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "ld_dvfs.h"
|
||||
|
||||
#include <hal/nrf_hsfll.h>
|
||||
#include <hal/nrf_ramc.h>
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(LD_DVFS_LIB, CONFIG_LOCAL_DOMAIN_DVFS_LIB_LOG_LEVEL);
|
||||
|
||||
#define TRANSIENT_ZBB_ABB_SLOT 0
|
||||
#define CURR_TARG_ABB_SLOT 1
|
||||
#define LD_ABB_CLR_ZBB 0
|
||||
/* TODO: this values needs to be provided by HW team */
|
||||
/* for now reset value will be used */
|
||||
#define LD_ABB_CTRL4_NORMAL_OPERATION 0x10800UL
|
||||
#define LD_ABB_CTRL4_TRANSITION_OPERATION 0x10800UL
|
||||
|
||||
/*
|
||||
* wait max 500ms with 10us intervals for hsfll freq change event
|
||||
*/
|
||||
#define HSFLL_FREQ_CHANGE_MAX_DELAY_MS 500UL
|
||||
#define HSFLL_FREQ_CHANGE_CHECK_INTERVAL_US 10
|
||||
#define HSFLL_FREQ_CHANGE_CHECK_MAX_ATTEMPTS \
|
||||
((HSFLL_FREQ_CHANGE_MAX_DELAY_MS) * (USEC_PER_MSEC) / (HSFLL_FREQ_CHANGE_CHECK_INTERVAL_US))
|
||||
|
||||
#define ABB_STATUS_CHANGE_MAX_DELAY_MS 5000UL
|
||||
#define ABB_STATUS_CHANGE_CHECK_INTERVAL_US 10
|
||||
#define ABB_STATUS_CHANGE_CHECK_MAX_ATTEMPTS \
|
||||
((ABB_STATUS_CHANGE_MAX_DELAY_MS) * (USEC_PER_MSEC) / (ABB_STATUS_CHANGE_CHECK_INTERVAL_US))
|
||||
|
||||
void ld_dvfs_init(void)
|
||||
{
|
||||
#if defined(NRF_SECURE)
|
||||
|
||||
const struct dvfs_oppoint_data *opp_data = get_dvfs_oppoint_data(DVFS_FREQ_HIGH);
|
||||
|
||||
#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST)
|
||||
LOG_DBG("%s", __func__);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_ringo);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_lockrange);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_pvtmoncycles);
|
||||
|
||||
/*For app core.*/
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_ringo);
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_lockrange);
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_pvtmoncycles);
|
||||
#else
|
||||
/* TODO: Change to NRFX Hal function when available. */
|
||||
NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT] = opp_data->abb_ringo;
|
||||
NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT] = opp_data->abb_lockrange;
|
||||
NRF_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT] = opp_data->abb_pvtmoncycles;
|
||||
|
||||
NRF_APPLICATION_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT] = opp_data->abb_ringo;
|
||||
NRF_APPLICATION_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT] = opp_data->abb_lockrange;
|
||||
NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT] = opp_data->abb_pvtmoncycles;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void ld_dvfs_clear_zbb(void)
|
||||
{
|
||||
#if defined(NRF_SECURE)
|
||||
#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST)
|
||||
LOG_DBG("%s", __func__);
|
||||
LOG_DBG("REGW: NRF_ABB->CONFIG.CTRL1.MODE 0x%x, V: 0x%x",
|
||||
(uint32_t)&NRF_ABB->CONFIG.CTRL1,
|
||||
LD_ABB_CLR_ZBB);
|
||||
#else
|
||||
/* TODO: Change to NRFX Hal function when available. */
|
||||
NRF_ABB->CONFIG.CTRL1 &= ~(ABB_CONFIG_CTRL1_MODE_Msk);
|
||||
NRF_APPLICATION_ABB->CONFIG.CTRL1 &= ~(ABB_CONFIG_CTRL1_MODE_Msk);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(NRF_SECURE)
|
||||
|
||||
#define DOWNSCALE_SAFETY_TIMEOUT (K_USEC(CONFIG_NRFS_LOCAL_DOMAIN_DOWNSCALE_SAFETY_TIMEOUT_US))
|
||||
|
||||
atomic_t increased_power_consumption;
|
||||
|
||||
/**
|
||||
* @brief Secure domain needs to check if downscale is done in defined time
|
||||
* window. This is needed to avoid battery drain if dvfs procedure
|
||||
* takes to much time (some failure?).
|
||||
*/
|
||||
__weak void ld_dvfs_secure_downscale_timeout(struct k_timer *timer)
|
||||
{
|
||||
ARG_UNUSED(timer);
|
||||
|
||||
LOG_ERR("Downscale timeout expired, reset board.");
|
||||
atomic_set(&increased_power_consumption, 0);
|
||||
}
|
||||
|
||||
K_TIMER_DEFINE(dvfs_downscale_secure_timer, ld_dvfs_secure_downscale_timeout, NULL);
|
||||
|
||||
/**
|
||||
* @brief Secure domain starts increased power consumption, needed by dvfs sequence.
|
||||
* This function can be reimplemented in other module if needed.
|
||||
*/
|
||||
__weak void ld_dvfs_secure_start_increased_power_consumption(void)
|
||||
{
|
||||
LOG_INF("Start increased power consumption for DVFS sequence and start safety timer.");
|
||||
k_timer_start(&dvfs_downscale_secure_timer, DOWNSCALE_SAFETY_TIMEOUT, K_NO_WAIT);
|
||||
atomic_set(&increased_power_consumption, 1);
|
||||
|
||||
volatile uint8_t idle_counter = 0;
|
||||
|
||||
while (atomic_get(&increased_power_consumption)) {
|
||||
if (idle_counter < 100) {
|
||||
k_yield();
|
||||
idle_counter++;
|
||||
} else {
|
||||
idle_counter = 0;
|
||||
k_usleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Secure domain stops increased power consumption at the end of downscale.
|
||||
* This function can be reimplemented in other module if needed.
|
||||
*/
|
||||
__weak void ld_dvfs_secure_stop_increased_power_consumption(void)
|
||||
{
|
||||
LOG_INF("Stop increased power consumption for DVFS sequence.");
|
||||
k_timer_stop(&dvfs_downscale_secure_timer);
|
||||
atomic_set(&increased_power_consumption, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ld_dvfs_configure_abb_for_transition(enum dvfs_frequency_setting transient_opp,
|
||||
enum dvfs_frequency_setting curr_targ_opp)
|
||||
{
|
||||
#if defined(NRF_SECURE)
|
||||
const struct dvfs_oppoint_data *opp_data = get_dvfs_oppoint_data(transient_opp);
|
||||
|
||||
#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST)
|
||||
LOG_DBG("%s", __func__);
|
||||
LOG_DBG("transient_opp: %d, curr_targ_opp: %d", transient_opp, curr_targ_opp);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x",
|
||||
TRANSIENT_ZBB_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.RINGO[TRANSIENT_ZBB_ABB_SLOT],
|
||||
opp_data->abb_ringo);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x",
|
||||
TRANSIENT_ZBB_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.LOCKRANGE[TRANSIENT_ZBB_ABB_SLOT],
|
||||
opp_data->abb_lockrange);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x",
|
||||
TRANSIENT_ZBB_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.PVTMONCYCLES[TRANSIENT_ZBB_ABB_SLOT],
|
||||
opp_data->abb_pvtmoncycles);
|
||||
|
||||
/* For app core.*/
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x",
|
||||
TRANSIENT_ZBB_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.RINGO[TRANSIENT_ZBB_ABB_SLOT],
|
||||
opp_data->abb_ringo);
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x",
|
||||
TRANSIENT_ZBB_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.LOCKRANGE[TRANSIENT_ZBB_ABB_SLOT],
|
||||
opp_data->abb_lockrange);
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x",
|
||||
TRANSIENT_ZBB_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[TRANSIENT_ZBB_ABB_SLOT],
|
||||
opp_data->abb_pvtmoncycles);
|
||||
#else
|
||||
|
||||
NRF_ABB->TRIM.RINGO[TRANSIENT_ZBB_ABB_SLOT] = opp_data->abb_ringo;
|
||||
NRF_ABB->TRIM.LOCKRANGE[TRANSIENT_ZBB_ABB_SLOT] = opp_data->abb_lockrange;
|
||||
NRF_ABB->TRIM.PVTMONCYCLES[TRANSIENT_ZBB_ABB_SLOT] = opp_data->abb_pvtmoncycles;
|
||||
|
||||
NRF_APPLICATION_ABB->TRIM.RINGO[TRANSIENT_ZBB_ABB_SLOT] = opp_data->abb_ringo;
|
||||
NRF_APPLICATION_ABB->TRIM.LOCKRANGE[TRANSIENT_ZBB_ABB_SLOT] = opp_data->abb_lockrange;
|
||||
NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[TRANSIENT_ZBB_ABB_SLOT] = opp_data->abb_pvtmoncycles;
|
||||
#endif
|
||||
opp_data = get_dvfs_oppoint_data(curr_targ_opp);
|
||||
|
||||
#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST)
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_ringo);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_lockrange);
|
||||
LOG_DBG("REGW: NRF_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_pvtmoncycles);
|
||||
|
||||
LOG_DBG("REGW: TODO: NRF_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx",
|
||||
(uint32_t)&NRF_ABB->CONFIG.CTRL4,
|
||||
LD_ABB_CTRL4_TRANSITION_OPERATION);
|
||||
|
||||
/* For app core */
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_ringo);
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_lockrange);
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x",
|
||||
CURR_TARG_ABB_SLOT,
|
||||
(uint32_t)&NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT],
|
||||
opp_data->abb_pvtmoncycles);
|
||||
|
||||
LOG_DBG("REGW: TODO: NRF_APPLICATION_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx",
|
||||
(uint32_t)&NRF_APPLICATION_ABB->CONFIG.CTRL4,
|
||||
LD_ABB_CTRL4_TRANSITION_OPERATION);
|
||||
#else
|
||||
NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT] = opp_data->abb_ringo;
|
||||
NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT] = opp_data->abb_lockrange;
|
||||
NRF_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT] = opp_data->abb_pvtmoncycles;
|
||||
|
||||
NRF_ABB->CONFIG.CTRL4 = LD_ABB_CTRL4_TRANSITION_OPERATION;
|
||||
|
||||
NRF_APPLICATION_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT] = opp_data->abb_ringo;
|
||||
NRF_APPLICATION_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT] = opp_data->abb_lockrange;
|
||||
NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT] = opp_data->abb_pvtmoncycles;
|
||||
|
||||
NRF_APPLICATION_ABB->CONFIG.CTRL4 = LD_ABB_CTRL4_TRANSITION_OPERATION;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t ld_dvfs_configure_hsfll(enum dvfs_frequency_setting oppoint)
|
||||
{
|
||||
nrf_hsfll_trim_t hsfll_trim = {};
|
||||
|
||||
if (oppoint >= DVFS_FREQ_COUNT) {
|
||||
LOG_ERR("Not valid oppoint %d", oppoint);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
uint8_t freq_trim = get_dvfs_oppoint_data(oppoint)->new_f_trim_entry;
|
||||
|
||||
#ifdef CONFIG_SOC_NRF54H20_CPUAPP
|
||||
hsfll_trim.vsup = NRF_FICR->TRIM.APPLICATION.HSFLL.TRIM.VSUP;
|
||||
hsfll_trim.coarse = NRF_FICR->TRIM.APPLICATION.HSFLL.TRIM.COARSE[freq_trim];
|
||||
hsfll_trim.fine = NRF_FICR->TRIM.APPLICATION.HSFLL.TRIM.FINE[freq_trim];
|
||||
#else
|
||||
hsfll_trim.vsup = NRF_FICR->TRIM.SECURE.HSFLL.TRIM.VSUP;
|
||||
hsfll_trim.coarse = NRF_FICR->TRIM.SECURE.HSFLL.TRIM.COARSE[freq_trim];
|
||||
hsfll_trim.fine = NRF_FICR->TRIM.SECURE.HSFLL.TRIM.FINE[freq_trim];
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST)
|
||||
LOG_DBG("%s oppoint: %d", __func__, oppoint);
|
||||
LOG_DBG("REGW: NRF_HSFLL->MIRROR 0x%x, V: 0x%x", (uint32_t)&NRF_HSFLL->MIRROR, 1);
|
||||
LOG_DBG("REGW: NRF_HSFLL->TRIM.COARSE 0x%x, V: 0x%x",
|
||||
(uint32_t)&NRF_HSFLL->TRIM.COARSE,
|
||||
hsfll_trim.coarse);
|
||||
LOG_DBG("REGW: NRF_HSFLL->TRIM.FINE 0x%x, V: 0x%x",
|
||||
(uint32_t)&NRF_HSFLL->TRIM.FINE,
|
||||
hsfll_trim.fine);
|
||||
LOG_DBG("REGW: NRF_HSFLL->MIRROR 0x%x, V: 0x%x", (uint32_t)&NRF_HSFLL->MIRROR, 0);
|
||||
|
||||
LOG_DBG("REGW: NRF_HSFLL->CLOCKCTRL.MULT 0x%x, V: 0x%x",
|
||||
(uint32_t)&NRF_HSFLL->CLOCKCTRL.MULT,
|
||||
get_dvfs_oppoint_data(oppoint)->new_f_mult);
|
||||
|
||||
LOG_DBG("REGW: NRF_HSFLL->NRF_HSFLL_TASK_FREQ_CHANGE 0x%x, V: 0x%x",
|
||||
(uint32_t)NRF_HSFLL + NRF_HSFLL_TASK_FREQ_CHANGE,
|
||||
0x1);
|
||||
return 0;
|
||||
#else
|
||||
|
||||
nrf_hsfll_trim_set(NRF_HSFLL, &hsfll_trim);
|
||||
nrf_barrier_w();
|
||||
|
||||
nrf_hsfll_clkctrl_mult_set(NRF_HSFLL, get_dvfs_oppoint_data(oppoint)->new_f_mult);
|
||||
nrf_hsfll_task_trigger(NRF_HSFLL, NRF_HSFLL_TASK_FREQ_CHANGE);
|
||||
/* Trigger hsfll task one more time, SEE PAC-4078 */
|
||||
nrf_hsfll_task_trigger(NRF_HSFLL, NRF_HSFLL_TASK_FREQ_CHANGE);
|
||||
|
||||
bool hsfll_freq_changed = false;
|
||||
|
||||
NRFX_WAIT_FOR(nrf_hsfll_event_check(NRF_HSFLL, NRF_HSFLL_EVENT_FREQ_CHANGED),
|
||||
HSFLL_FREQ_CHANGE_CHECK_MAX_ATTEMPTS,
|
||||
HSFLL_FREQ_CHANGE_CHECK_INTERVAL_US,
|
||||
hsfll_freq_changed);
|
||||
|
||||
if (hsfll_freq_changed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ld_dvfs_scaling_background_process(bool downscaling)
|
||||
{
|
||||
#if defined(NRF_SECURE)
|
||||
if (NRF_DOMAIN == NRF_DOMAIN_SECURE) {
|
||||
if (downscaling) {
|
||||
ld_dvfs_secure_start_increased_power_consumption();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ld_dvfs_scaling_finish(bool downscaling)
|
||||
{
|
||||
#if defined(NRF_SECURE)
|
||||
#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST)
|
||||
LOG_DBG("%s", __func__);
|
||||
LOG_DBG("REGW: NRF_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx",
|
||||
(uint32_t)&NRF_ABB->CONFIG.CTRL4,
|
||||
LD_ABB_CTRL4_NORMAL_OPERATION);
|
||||
LOG_DBG("REGW: NRF_APPLICATION_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx",
|
||||
(uint32_t)&NRF_APPLICATION_ABB->CONFIG.CTRL4,
|
||||
LD_ABB_CTRL4_NORMAL_OPERATION);
|
||||
#else
|
||||
NRF_ABB->CONFIG.CTRL4 = LD_ABB_CTRL4_NORMAL_OPERATION;
|
||||
NRF_APPLICATION_ABB->CONFIG.CTRL4 = LD_ABB_CTRL4_NORMAL_OPERATION;
|
||||
#endif
|
||||
|
||||
if (NRF_DOMAIN == NRF_DOMAIN_SECURE) {
|
||||
if (downscaling) {
|
||||
ld_dvfs_secure_stop_increased_power_consumption();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
66
modules/hal_nordic/nrfs/dvfs/ld_dvfs.h
Normal file
66
modules/hal_nordic/nrfs/dvfs/ld_dvfs.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef LD_DVFS_H
|
||||
#define LD_DVFS_H
|
||||
|
||||
#include <dvfs_oppoint.h>
|
||||
#include <nrfs_common.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function for initializing the Dynamic Voltage and Frequency Scaling service
|
||||
* from LD perspective..
|
||||
*
|
||||
*/
|
||||
void ld_dvfs_init(void);
|
||||
|
||||
/**
|
||||
* @brief Function for clearing the zero bias
|
||||
*
|
||||
*/
|
||||
void ld_dvfs_clear_zbb(void);
|
||||
|
||||
/**
|
||||
* @brief Configure ABB registers to transition process.
|
||||
*
|
||||
* @param transient_opp current operation point
|
||||
* @param curr_targ_opp target operation point
|
||||
*/
|
||||
void ld_dvfs_configure_abb_for_transition(enum dvfs_frequency_setting transient_opp,
|
||||
enum dvfs_frequency_setting curr_targ_opp);
|
||||
|
||||
/**
|
||||
* @brief Configure hsfll depending on selected oppoint
|
||||
*
|
||||
* @param enum oppoint target operation point
|
||||
* @return 0 value indicates no error.
|
||||
* @return -EINVAL invalid oppoint or domain.
|
||||
* @return -ETIMEDOUT frequency change took more than HSFLL_FREQ_CHANGE_MAX_DELAY_MS
|
||||
*/
|
||||
int32_t ld_dvfs_configure_hsfll(enum dvfs_frequency_setting oppoint);
|
||||
|
||||
/**
|
||||
* @brief Background process during scaling.
|
||||
*
|
||||
* @param downscaling indicates if down-scaling is running
|
||||
*/
|
||||
void ld_dvfs_scaling_background_process(bool downscaling);
|
||||
|
||||
/**
|
||||
* @brief Last step for local domain in downscale procedure
|
||||
*
|
||||
* @param downscaling indicates if down-scaling is running
|
||||
*/
|
||||
void ld_dvfs_scaling_finish(bool downscaling);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LD_DVFS_H */
|
292
modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c
Normal file
292
modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c
Normal file
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "ld_dvfs_handler.h"
|
||||
#include "ld_dvfs.h"
|
||||
|
||||
#include <hal/nrf_hsfll.h>
|
||||
#include <nrfs_dvfs.h>
|
||||
#include <nrfs_backend_ipc_service.h>
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(LD_DVFS_LIB, CONFIG_LOCAL_DOMAIN_DVFS_LIB_LOG_LEVEL);
|
||||
|
||||
static K_SEM_DEFINE(dvfs_service_sync_sem, 0, 1);
|
||||
static K_SEM_DEFINE(dvfs_service_idle_sem, 0, 1);
|
||||
|
||||
#define DVFS_SERV_HDL_INIT_DONE_BIT_POS (0)
|
||||
#define DVFS_SERV_HDL_FREQ_CHANGE_IN_PROGRESS_BIT_POS (1)
|
||||
|
||||
static atomic_t dvfs_service_handler_state_bits;
|
||||
static enum dvfs_frequency_setting current_freq_setting;
|
||||
|
||||
static void dvfs_service_handler_set_state_bit(uint32_t bit_pos)
|
||||
{
|
||||
atomic_set_bit(&dvfs_service_handler_state_bits, bit_pos);
|
||||
}
|
||||
|
||||
static void dvfs_service_handler_clear_state_bit(uint32_t bit_pos)
|
||||
{
|
||||
atomic_clear_bit(&dvfs_service_handler_state_bits, bit_pos);
|
||||
}
|
||||
|
||||
static bool dvfs_service_handler_get_state_bit(uint32_t bit_pos)
|
||||
{
|
||||
return atomic_test_bit(&dvfs_service_handler_state_bits, bit_pos);
|
||||
}
|
||||
|
||||
static bool dvfs_service_handler_init_done(void)
|
||||
{
|
||||
return dvfs_service_handler_get_state_bit(DVFS_SERV_HDL_INIT_DONE_BIT_POS);
|
||||
}
|
||||
|
||||
static bool dvfs_service_handler_freq_change_in_progress(void)
|
||||
{
|
||||
return dvfs_service_handler_get_state_bit(DVFS_SERV_HDL_FREQ_CHANGE_IN_PROGRESS_BIT_POS);
|
||||
}
|
||||
|
||||
static void dvfs_service_handler_nrfs_error_check(nrfs_err_t err)
|
||||
{
|
||||
if (err != NRFS_SUCCESS) {
|
||||
LOG_ERR("Failed with nrfs error: %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
static void dvfs_service_handler_error(int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
LOG_ERR("Failed with error: %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t *get_next_context(void)
|
||||
{
|
||||
static uint32_t ctx;
|
||||
|
||||
ctx++;
|
||||
return &ctx;
|
||||
}
|
||||
|
||||
static bool dvfs_service_handler_freq_setting_allowed(enum dvfs_frequency_setting freq_setting)
|
||||
{
|
||||
if (freq_setting == DVFS_FREQ_HIGH || freq_setting == DVFS_FREQ_MEDLOW ||
|
||||
freq_setting == DVFS_FREQ_LOW) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static enum dvfs_frequency_setting dvfs_service_handler_get_current_oppoint(void)
|
||||
{
|
||||
LOG_INF("Current LD freq setting: %d", current_freq_setting);
|
||||
return current_freq_setting;
|
||||
}
|
||||
|
||||
/* Function to check if current operation is down-scaling */
|
||||
static bool dvfs_service_handler_is_downscaling(enum dvfs_frequency_setting target_freq_setting)
|
||||
{
|
||||
if (dvfs_service_handler_freq_setting_allowed(target_freq_setting)) {
|
||||
LOG_DBG("Checking if downscaling %s",
|
||||
(dvfs_service_handler_get_current_oppoint() < target_freq_setting) ? "YES" :
|
||||
"NO");
|
||||
return dvfs_service_handler_get_current_oppoint() < target_freq_setting;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Function handling steps for scaling preparation. */
|
||||
static void dvfs_service_handler_prepare_to_scale(enum dvfs_frequency_setting oppoint_freq)
|
||||
{
|
||||
LOG_INF("Prepare to scale, oppoint freq %d", oppoint_freq);
|
||||
enum dvfs_frequency_setting new_oppoint = oppoint_freq;
|
||||
enum dvfs_frequency_setting current_oppoint = dvfs_service_handler_get_current_oppoint();
|
||||
|
||||
if (new_oppoint == current_oppoint) {
|
||||
LOG_INF("New oppoint is same as previous, no change");
|
||||
} else {
|
||||
ld_dvfs_configure_abb_for_transition(current_oppoint, new_oppoint);
|
||||
|
||||
if (dvfs_service_handler_is_downscaling(new_oppoint)) {
|
||||
int32_t err = ld_dvfs_configure_hsfll(new_oppoint);
|
||||
|
||||
if (err != 0) {
|
||||
dvfs_service_handler_error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do background job during scaling process (e.g. increased power consumption during down-scale). */
|
||||
static void dvfs_service_handler_scaling_background_job(enum dvfs_frequency_setting oppoint_freq)
|
||||
{
|
||||
LOG_INF("Perform scaling background job if needed.");
|
||||
if (dvfs_service_handler_is_downscaling(oppoint_freq)) {
|
||||
k_sem_give(&dvfs_service_idle_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform scaling finnish procedure. */
|
||||
static void dvfs_service_handler_scaling_finish(enum dvfs_frequency_setting oppoint_freq)
|
||||
{
|
||||
LOG_INF("Scaling finnish oppoint freq %d", oppoint_freq);
|
||||
ld_dvfs_scaling_finish(dvfs_service_handler_is_downscaling(oppoint_freq));
|
||||
if (!dvfs_service_handler_is_downscaling(oppoint_freq)) {
|
||||
int32_t err = ld_dvfs_configure_hsfll(oppoint_freq);
|
||||
|
||||
if (err != 0) {
|
||||
dvfs_service_handler_error(err);
|
||||
}
|
||||
}
|
||||
current_freq_setting = oppoint_freq;
|
||||
}
|
||||
|
||||
/* Function to set hsfll to highest frequency when switched to ABB. */
|
||||
static void dvfs_service_handler_set_initial_hsfll_config(void)
|
||||
{
|
||||
int32_t err = ld_dvfs_configure_hsfll(DVFS_FREQ_HIGH);
|
||||
|
||||
current_freq_setting = DVFS_FREQ_HIGH;
|
||||
if (err != 0) {
|
||||
dvfs_service_handler_error(err);
|
||||
}
|
||||
}
|
||||
|
||||
/* DVFS event handler callback function.*/
|
||||
static void nrfs_dvfs_evt_handler(nrfs_dvfs_evt_t const *p_evt, void *context)
|
||||
{
|
||||
LOG_INF("%s", __func__);
|
||||
switch (p_evt->type) {
|
||||
case NRFS_DVFS_EVT_INIT_PREPARATION:
|
||||
LOG_INF("DVFS handler EVT_INIT_PREPARATION");
|
||||
#if defined(NRF_SECURE)
|
||||
ld_dvfs_clear_zbb();
|
||||
dvfs_service_handler_nrfs_error_check(
|
||||
nrfs_dvfs_init_complete_request(get_next_context()));
|
||||
LOG_INF("DVFS handler EVT_INIT_PREPARATION handled");
|
||||
#else
|
||||
LOG_ERR("DVFS handler - unexpected EVT_INIT_PREPARATION");
|
||||
#endif
|
||||
break;
|
||||
case NRFS_DVFS_EVT_INIT_DONE:
|
||||
LOG_INF("DVFS handler EVT_INIT_DONE");
|
||||
dvfs_service_handler_set_initial_hsfll_config();
|
||||
dvfs_service_handler_set_state_bit(DVFS_SERV_HDL_INIT_DONE_BIT_POS);
|
||||
k_sem_give(&dvfs_service_sync_sem);
|
||||
LOG_INF("DVFS handler EVT_INIT_DONE handled");
|
||||
break;
|
||||
case NRFS_DVFS_EVT_OPPOINT_REQ_CONFIRMED:
|
||||
/* Optional confirmation from sysctrl, wait for oppoint.*/
|
||||
LOG_INF("DVFS handler EVT_OPPOINT_REQ_CONFIRMED");
|
||||
break;
|
||||
case NRFS_DVFS_EVT_OPPOINT_SCALING_PREPARE:
|
||||
/*Target oppoint will be received here.*/
|
||||
LOG_INF("DVFS handler EVT_OPPOINT_SCALING_PREPARE");
|
||||
#if !defined(NRF_SECURE)
|
||||
if (dvfs_service_handler_is_downscaling(p_evt->freq)) {
|
||||
#endif
|
||||
dvfs_service_handler_prepare_to_scale(p_evt->freq);
|
||||
dvfs_service_handler_nrfs_error_check(
|
||||
nrfs_dvfs_ready_to_scale(get_next_context()));
|
||||
dvfs_service_handler_scaling_background_job(p_evt->freq);
|
||||
LOG_INF("DVFS handler EVT_OPPOINT_SCALING_PREPARE handled");
|
||||
#if !defined(NRF_SECURE)
|
||||
current_freq_setting = p_evt->freq;
|
||||
} else {
|
||||
LOG_ERR("DVFS handler - unexpected EVT_OPPOINT_SCALING_PREPARE");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case NRFS_DVFS_EVT_OPPOINT_SCALING_DONE:
|
||||
LOG_INF("DVFS handler EVT_OPPOINT_SCALING_DONE");
|
||||
dvfs_service_handler_clear_state_bit(DVFS_SERV_HDL_FREQ_CHANGE_IN_PROGRESS_BIT_POS);
|
||||
dvfs_service_handler_scaling_finish(p_evt->freq);
|
||||
LOG_INF("DVFS handler EVT_OPPOINT_SCALING_DONE handled");
|
||||
break;
|
||||
case NRFS_DVFS_EVT_REJECT:
|
||||
LOG_ERR("DVFS handler - request rejected");
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("DVFS handler - unexpected event: 0x%x", p_evt->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Task to handle dvfs init procedure. */
|
||||
static void dvfs_service_handler_task(void *dummy0, void *dummy1, void *dummy2)
|
||||
{
|
||||
ARG_UNUSED(dummy0);
|
||||
ARG_UNUSED(dummy1);
|
||||
ARG_UNUSED(dummy2);
|
||||
|
||||
LOG_INF("Trim ABB for default voltage.");
|
||||
ld_dvfs_init();
|
||||
|
||||
LOG_INF("Waiting for backend init");
|
||||
/* Wait for ipc initialization */
|
||||
nrfs_backend_wait_for_connection(K_FOREVER);
|
||||
|
||||
nrfs_err_t status;
|
||||
|
||||
LOG_INF("nrfs_dvfs_init");
|
||||
status = nrfs_dvfs_init(nrfs_dvfs_evt_handler);
|
||||
dvfs_service_handler_nrfs_error_check(status);
|
||||
|
||||
LOG_INF("nrfs_dvfs_init_prepare_request");
|
||||
status = nrfs_dvfs_init_prepare_request(get_next_context());
|
||||
dvfs_service_handler_nrfs_error_check(status);
|
||||
|
||||
/* Wait for init*/
|
||||
k_sem_take(&dvfs_service_sync_sem, K_FOREVER);
|
||||
|
||||
LOG_INF("DVFS init done.");
|
||||
|
||||
#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_SCALE_DOWN_AFTER_INIT)
|
||||
LOG_INF("Requesting lowest frequency oppoint.");
|
||||
dvfs_service_handler_change_freq_setting(DVFS_FREQ_LOW);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
k_sem_take(&dvfs_service_idle_sem, K_FOREVER);
|
||||
/* perform background processing */
|
||||
ld_dvfs_scaling_background_process(true);
|
||||
}
|
||||
}
|
||||
|
||||
K_THREAD_DEFINE(dvfs_service_handler_task_id,
|
||||
CONFIG_NRFS_LOCAL_DOMAIN_DVFS_HANDLER_TASK_STACK_SIZE,
|
||||
dvfs_service_handler_task,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_NRFS_LOCAL_DOMAIN_DVFS_HANDLER_TASK_PRIORITY,
|
||||
0,
|
||||
0);
|
||||
|
||||
int32_t dvfs_service_handler_change_freq_setting(enum dvfs_frequency_setting freq_setting)
|
||||
{
|
||||
if (!dvfs_service_handler_init_done()) {
|
||||
LOG_INF("Init not done!");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (dvfs_service_handler_freq_change_in_progress()) {
|
||||
LOG_INF("Frequency change in progress.");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!dvfs_service_handler_freq_setting_allowed(freq_setting)) {
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
nrfs_err_t status = nrfs_dvfs_oppoint_request(freq_setting, get_next_context());
|
||||
|
||||
dvfs_service_handler_nrfs_error_check(status);
|
||||
|
||||
return status;
|
||||
}
|
33
modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.h
Normal file
33
modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef LD_DVFS_HANDLER_H
|
||||
#define LD_DVFS_HANDLER_H
|
||||
|
||||
#include <dvfs_oppoint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function to request LD frequency change.
|
||||
*
|
||||
* @param frequency requested frequency setting from enum dvfs_frequency_setting.
|
||||
* @return EBUSY Frequency change in progress.
|
||||
* @return EAGAIN DVFS init in progress.
|
||||
* @return ENXIO Not supported frequency settings.
|
||||
* @return NRFS_SUCCESS Request sent successfully.
|
||||
* @return NRFS_ERR_INVALID_STATE Service is uninitialized.
|
||||
* @return NRFS_ERR_IPC Backend returned error during request sending.
|
||||
*/
|
||||
int32_t dvfs_service_handler_change_freq_setting(enum dvfs_frequency_setting freq_setting);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LD_DVFS_HANDLER_H */
|
47
modules/hal_nordic/nrfs/nrfs_config.h
Normal file
47
modules/hal_nordic/nrfs/nrfs_config.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef NRFS_CONFIG_H
|
||||
#define NRFS_CONFIG_H
|
||||
|
||||
|
||||
#ifdef CONFIG_NRFS_TEMP_SERVICE_ENABLED
|
||||
#define NRFS_TEMP_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NRFS_MRAM_SERVICE_ENABLED
|
||||
#define NRFS_MRAM_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NRFS_RESET_SERVICE_ENABLED
|
||||
#define NRFS_RESET_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NRFS_VBUS_DETECTOR_SERVICE_ENABLED
|
||||
#define NRFS_VBUS_DETECTOR_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NRFS_PMIC_SERVICE_ENABLED
|
||||
#define NRFS_PMIC_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NRFS_DVFS_SERVICE_ENABLED
|
||||
#define NRFS_DVFS_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NRFS_DIAG_SERVICE_ENABLED
|
||||
#define NRFS_DIAG_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NRFS_CLOCK_SERVICE_ENABLED
|
||||
#define NRFS_CLOCK_SERVICE_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_POSIX
|
||||
#define NRFS_UNIT_TESTS_ENABLED
|
||||
#endif
|
||||
|
||||
#endif /* NRFS_CONFIG_H */
|
|
@ -4,6 +4,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SOC_SERIES_NRF54HX
|
||||
select HAS_NRFS
|
||||
select HAS_NRFX
|
||||
select HAS_NORDIC_DRIVERS
|
||||
|
||||
|
@ -18,6 +19,11 @@ config SOC_NRF54H20_CPUAPP
|
|||
select CPU_HAS_FPU
|
||||
select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS
|
||||
select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE
|
||||
select NRFS_HAS_CLOCK_SERVICE
|
||||
select NRFS_HAS_DVFS_SERVICE
|
||||
select NRFS_HAS_MRAM_SERVICE
|
||||
select NRFS_HAS_TEMP_SERVICE
|
||||
select NRFS_HAS_VBUS_DETECTOR_SERVICE
|
||||
|
||||
config SOC_NRF54H20_CPURAD
|
||||
select ARM
|
||||
|
@ -30,6 +36,9 @@ config SOC_NRF54H20_CPURAD
|
|||
select CPU_HAS_FPU
|
||||
select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS
|
||||
select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE
|
||||
select NRFS_HAS_CLOCK_SERVICE
|
||||
select NRFS_HAS_MRAM_SERVICE
|
||||
select NRFS_HAS_TEMP_SERVICE
|
||||
|
||||
config SOC_NRF54H20_CPUPPR
|
||||
depends on RISCV_CORE_NORDIC_VPR
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue