From 3b30f649714f867ccaf90e84ef7b80e32bda1bc6 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 27 Nov 2024 22:00:47 +0100 Subject: [PATCH] soc: nordic: nrf54h20: restrict global hsfll freq Introduce feature which restricts the minimum global hsfll frequency. This feature is selected by default to preserve the behavior of the global hsfll before the clock control driver for it was introduced, which configured it as a fixed clock at 320MHz. Signed-off-by: Bjarki Arge Andreasen --- soc/nordic/nrf54h/CMakeLists.txt | 1 + soc/nordic/nrf54h/Kconfig | 33 ++++++++++++++++ soc/nordic/nrf54h/global_hsfll.c | 64 ++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 soc/nordic/nrf54h/global_hsfll.c diff --git a/soc/nordic/nrf54h/CMakeLists.txt b/soc/nordic/nrf54h/CMakeLists.txt index 7edc4d43ea12895..0b25692ea3531dd 100644 --- a/soc/nordic/nrf54h/CMakeLists.txt +++ b/soc/nordic/nrf54h/CMakeLists.txt @@ -9,6 +9,7 @@ if(CONFIG_ARM) endif() zephyr_library_sources_ifdef(CONFIG_PM_S2RAM pm_s2ram.c) +zephyr_library_sources_ifdef(CONFIG_SOC_NRF54H20_GLOBAL_HSFLL_RESTRICT_MIN_FREQ global_hsfll.c) zephyr_include_directories(.) diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index ca854121bf5bf3d..717146ddd4eab69 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -67,3 +67,36 @@ config SOC_NRF54H20_CPUFLPR select RISCV_CORE_NORDIC_VPR rsource "gpd/Kconfig" + +config SOC_NRF54H20_GLOBAL_HSFLL_RESTRICT_MIN_FREQ + bool "Restrict minimum global HSFLL clock frequency" + select NRFS + select NRFS_GDFS_SERVICE_ENABLED + select CLOCK_CONTROL + default y if SOC_NRF54H20_CPUAPP + +if SOC_NRF54H20_GLOBAL_HSFLL_RESTRICT_MIN_FREQ + +choice SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_CHOICE + prompt "Minimum global HSFLL clock frequency in MHz" + default SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_320_MHZ + +config SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_64_MHZ + bool "Restrict minimum global HSFLL clock frequency to 64MHz" + +config SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_128_MHZ + bool "Restrict minimum global HSFLL clock frequency to 128MHz" + +config SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_256_MHZ + bool "Restrict minimum global HSFLL clock frequency to 256MHz" + +config SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_320_MHZ + bool "Restrict minimum global HSFLL clock frequency to 320MHz" + +endchoice + +config SOC_NRF54H20_GLOBAL_HSFLL_TIMEOUT_MS + int "Global HSFLL timeout in milliseconds" + default 10000 + +endif # SOC_NRF54H20_RESTRICT_GLOBAL_HSFLL_FREQ diff --git a/soc/nordic/nrf54h/global_hsfll.c b/soc/nordic/nrf54h/global_hsfll.c new file mode 100644 index 000000000000000..ae155a7df4c5ae7 --- /dev/null +++ b/soc/nordic/nrf54h/global_hsfll.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +#if CONFIG_SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_64_MHZ +#define GLOBAL_HSFLL_MIN_FREQ_HZ 64000000 +#elif CONFIG_SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_128_MHZ +#define GLOBAL_HSFLL_MIN_FREQ_HZ 128000000 +#elif CONFIG_SOC_NRF54H20_GLOBAL_HSFLL_MIN_FREQ_256_MHZ +#define GLOBAL_HSFLL_MIN_FREQ_HZ 256000000 +#else +#define GLOBAL_HSFLL_MIN_FREQ_HZ 320000000 +#endif + +#define GLOBAL_HSFLL_REQUEST_TIMEOUT_US \ + (CONFIG_SOC_NRF54H20_GLOBAL_HSFLL_TIMEOUT_MS * USEC_PER_SEC) + +static struct onoff_client cli; +static const struct device *global_hsfll = DEVICE_DT_GET(DT_NODELABEL(hsfll120)); +static const struct nrf_clock_spec spec = { + .frequency = GLOBAL_HSFLL_MIN_FREQ_HZ, +}; + +static int nordicsemi_nrf54h_global_hsfll_init(void) +{ + int ret; + int res; + bool completed; + + sys_notify_init_spinwait(&cli.notify); + + ret = nrf_clock_control_request(global_hsfll, &spec, &cli); + if (ret) { + return ret; + } + + res = -EIO; + completed = WAIT_FOR(sys_notify_fetch_result(&cli.notify, &res) == 0, + GLOBAL_HSFLL_REQUEST_TIMEOUT_US, + k_msleep(1)); + + if (!completed) { + LOG_ERR("%s request timed out", "Restrict global HSFLL"); + return -EIO; + } + + if (res) { + LOG_ERR("%s request failed: (res=%i)", "Restrict global HSFLL", res); + return res; + } + + LOG_INF("%s to %uHz", "Restrict global HSFLL", GLOBAL_HSFLL_MIN_FREQ_HZ); + return 0; +} + +SYS_INIT(nordicsemi_nrf54h_global_hsfll_init, POST_KERNEL, 99);