From 74aec6e991456f7ad23347d3cd80222383c6ec0b Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 14 Nov 2024 17:55:50 +0530 Subject: [PATCH 01/12] [nrf fromtree] manifest: hal_nordic: Pull nRF Wi-Fi removal Pulls PR that removed nRF Wi-Fi. (cherry picked from commit e512151474ca964302de2e9f8d25ecf13e3bcb16) Signed-off-by: Chaitanya Tata --- we | 0 west.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 we diff --git a/we b/we new file mode 100644 index 00000000000..e69de29bb2d diff --git a/west.yml b/west.yml index 3e66f68d53c..14f53cc6462 100644 --- a/west.yml +++ b/west.yml @@ -188,7 +188,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 54bde38c6f6ffb3780b26ae728cf79426184384e + revision: ce87268bb5610b7e90acce3efa5c511e95aeeeae path: modules/hal/nordic groups: - hal From d382adff063f6d2baab9e86d39e85eb5e06e0f0d Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 26 Nov 2024 13:49:03 +0530 Subject: [PATCH 02/12] [nrf fromtree] root: Remove temp file Commit e512151474c("manifest: hal_nordic: Pull nRF Wi-Fi removal") mistakenly added a temporary local file. Signed-off-by: Chaitanya Tata (cherry picked from commit 7658adf75877e0bb53c4ce92619a797f1a3172e0) --- we | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 we diff --git a/we b/we deleted file mode 100644 index e69de29bb2d..00000000000 From 3e36aa50d37673a3c29046e19839e1df6a8bd062 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 21 Nov 2024 10:02:33 +0100 Subject: [PATCH 03/12] [nrf fromtree] manifest: hal_nordic: Update to latest Including not removing a workaround in the UART driver for bsim targets (cherry picked from commit 6c7b38f5fa1cb4d382a030762efbcfe587ea974d) Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 14f53cc6462..6e2e87c992d 100644 --- a/west.yml +++ b/west.yml @@ -188,7 +188,7 @@ manifest: groups: - hal - name: hal_nordic - revision: ce87268bb5610b7e90acce3efa5c511e95aeeeae + revision: 5fbccc3fa8341d0cd5a128bc94f23ee03b763239 path: modules/hal/nordic groups: - hal From fb63a607308471f0039fcc6eb273a1b9ffc29371 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Wed, 4 Dec 2024 14:18:17 +0100 Subject: [PATCH 04/12] [nrf fromtree] manifest: Update the hal_nordic revision to get the latest suit blob See https://github.com/zephyrproject-rtos/hal_nordic/pull/267 for additional details. (cherry picked from commit 96f2b2f4bb6556c279778614419475d886111004) Signed-off-by: Carles Cufi --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 6e2e87c992d..7ff65298332 100644 --- a/west.yml +++ b/west.yml @@ -188,7 +188,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 5fbccc3fa8341d0cd5a128bc94f23ee03b763239 + revision: e0e48c4ec75595767a286389e2fcda72b21363b0 path: modules/hal/nordic groups: - hal From 2522ec4cd303a285f3dc0a423bcf1942c4bc6111 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 26 Nov 2024 16:33:45 +0100 Subject: [PATCH 05/12] [nrf fromlist] manifest: hal_nordic: update to include nrfs services Update hal_nordic revision to include nrfs services: - GDPWR - GDFS Upstream PR #: 81735 Signed-off-by: Bjarki Arge Andreasen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 7ff65298332..6061b2c5a05 100644 --- a/west.yml +++ b/west.yml @@ -188,7 +188,7 @@ manifest: groups: - hal - name: hal_nordic - revision: e0e48c4ec75595767a286389e2fcda72b21363b0 + revision: fae15426c6b5a1f67362d508cf51b691ae5ab4b4 path: modules/hal/nordic groups: - hal From 7ab138ae73e2ac8ab995f7b1031ba90be2e5b41d Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 28 Nov 2024 09:49:42 +0100 Subject: [PATCH 06/12] [nrf fromlist] soc: nordic: nrf54h: gpd: align GPD domain names nRFs exposes now all power domains, following their actual name in the specification. Add support for all of them in the GPD service. Note that this is a breaking change: running this code requires a new SCFW as IDs have changed in nRFs and so SCFW. Upstream PR #: 81735 Signed-off-by: Gerard Marull-Paretas --- .../zephyr/dt-bindings/power/nordic-nrf-gpd.h | 10 ++--- soc/nordic/nrf54h/gpd/gpd.c | 42 +++++++++++++++++-- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h b/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h index 7f6952f6f0b..e4a5b83a304 100644 --- a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h +++ b/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h @@ -8,10 +8,10 @@ #define ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD /* numbers aligned to nrfs service identifiers */ -#define NRF_GPD_SLOW_MAIN 2U -#define NRF_GPD_SLOW_ACTIVE 1U -#define NRF_GPD_FAST_MAIN 3U -#define NRF_GPD_FAST_ACTIVE1 0U -#define NRF_GPD_FAST_ACTIVE0 4U +#define NRF_GPD_FAST_ACTIVE0 0U +#define NRF_GPD_FAST_ACTIVE1 1U +#define NRF_GPD_FAST_MAIN 2U +#define NRF_GPD_SLOW_ACTIVE 3U +#define NRF_GPD_SLOW_MAIN 4U #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD */ diff --git a/soc/nordic/nrf54h/gpd/gpd.c b/soc/nordic/nrf54h/gpd/gpd.c index a4d1889e53f..3cee31b700e 100644 --- a/soc/nordic/nrf54h/gpd/gpd.c +++ b/soc/nordic/nrf54h/gpd/gpd.c @@ -20,9 +20,11 @@ LOG_MODULE_REGISTER(gpd, CONFIG_SOC_LOG_LEVEL); /* enforce alignment between DT<->nrfs */ -BUILD_ASSERT(GDPWR_POWER_DOMAIN_ACTIVE_FAST == NRF_GPD_FAST_ACTIVE1); -BUILD_ASSERT(GDPWR_POWER_DOMAIN_ACTIVE_SLOW == NRF_GPD_SLOW_ACTIVE); -BUILD_ASSERT(GDPWR_POWER_DOMAIN_MAIN_SLOW == NRF_GPD_SLOW_MAIN); +BUILD_ASSERT(GDPWR_GD_FAST_ACTIVE_0 == NRF_GPD_FAST_ACTIVE0); +BUILD_ASSERT(GDPWR_GD_FAST_ACTIVE_1 == NRF_GPD_FAST_ACTIVE1); +BUILD_ASSERT(GDPWR_GD_FAST_MAIN == NRF_GPD_FAST_MAIN); +BUILD_ASSERT(GDPWR_GD_SLOW_ACTIVE == NRF_GPD_SLOW_ACTIVE); +BUILD_ASSERT(GDPWR_GD_SLOW_MAIN == NRF_GPD_SLOW_MAIN); struct gpd_onoff_manager { struct onoff_manager mgr; @@ -44,11 +46,21 @@ static void stop(struct onoff_manager *mgr, onoff_notify_fn notify); #define GPD_SERVICE_REQ_ERR BIT(3) static atomic_t gpd_service_status = ATOMIC_INIT(0); +static struct gpd_onoff_manager fast_active0 = { + .id = NRF_GPD_FAST_ACTIVE0, + .lock = Z_MUTEX_INITIALIZER(fast_active0.lock), + .sem = Z_SEM_INITIALIZER(fast_active0.sem, 0, 1), +}; static struct gpd_onoff_manager fast_active1 = { .id = NRF_GPD_FAST_ACTIVE1, .lock = Z_MUTEX_INITIALIZER(fast_active1.lock), .sem = Z_SEM_INITIALIZER(fast_active1.sem, 0, 1), }; +static struct gpd_onoff_manager fast_main = { + .id = NRF_GPD_FAST_MAIN, + .lock = Z_MUTEX_INITIALIZER(fast_main.lock), + .sem = Z_SEM_INITIALIZER(fast_main.sem, 0, 1), +}; static struct gpd_onoff_manager slow_active = { .id = NRF_GPD_SLOW_ACTIVE, .lock = Z_MUTEX_INITIALIZER(slow_active.lock), @@ -66,8 +78,12 @@ static const struct onoff_transitions transitions = static struct gpd_onoff_manager *get_mgr(uint8_t id) { switch (id) { + case NRF_GPD_FAST_ACTIVE0: + return &fast_active0; case NRF_GPD_FAST_ACTIVE1: return &fast_active1; + case NRF_GPD_FAST_MAIN: + return &fast_main; case NRF_GPD_SLOW_ACTIVE: return &slow_active; case NRF_GPD_SLOW_MAIN: @@ -286,11 +302,21 @@ static int nrf_gpd_pre_init(void) { int ret; + ret = onoff_manager_init(&fast_active0.mgr, &transitions); + if (ret < 0) { + return ret; + } + ret = onoff_manager_init(&fast_active1.mgr, &transitions); if (ret < 0) { return ret; } + ret = onoff_manager_init(&fast_main.mgr, &transitions); + if (ret < 0) { + return ret; + } + ret = onoff_manager_init(&slow_active.mgr, &transitions); if (ret < 0) { return ret; @@ -322,11 +348,21 @@ static int nrf_gpd_post_init(void) } /* submit GD requests now to align collected statuses */ + ret = nrf_gpd_sync(&fast_active0); + if (ret < 0) { + goto err; + } + ret = nrf_gpd_sync(&fast_active1); if (ret < 0) { goto err; } + ret = nrf_gpd_sync(&fast_main); + if (ret < 0) { + goto err; + } + ret = nrf_gpd_sync(&slow_active); if (ret < 0) { goto err; From a5edcf4cd9cf31a7a9161af1ed984099511d7b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pelikan?= Date: Mon, 18 Nov 2024 15:38:26 +0100 Subject: [PATCH 07/12] [nrf fromlist] modules: hal_nordic: nrfs: add GDFS Service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding the implementation for the GDFS service Upstream PR #: 81735 Signed-off-by: Paweł Pelikan --- modules/hal_nordic/nrfs/CMakeLists.txt | 1 + modules/hal_nordic/nrfs/Kconfig | 8 ++++++++ modules/hal_nordic/nrfs/nrfs_config.h | 4 ++++ soc/nordic/nrf54h/Kconfig | 2 ++ 4 files changed, 15 insertions(+) diff --git a/modules/hal_nordic/nrfs/CMakeLists.txt b/modules/hal_nordic/nrfs/CMakeLists.txt index f470eea00e9..41dfb61f864 100644 --- a/modules/hal_nordic/nrfs/CMakeLists.txt +++ b/modules/hal_nordic/nrfs/CMakeLists.txt @@ -31,6 +31,7 @@ if(CONFIG_NRFS) 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_ifdef(CONFIG_NRFS_GDFS_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_gdfs.c) zephyr_library_sources(${SRC_DIR}/internal/nrfs_dispatcher.c) add_subdirectory_ifdef(CONFIG_NRFS_DVFS_LOCAL_DOMAIN dvfs) diff --git a/modules/hal_nordic/nrfs/Kconfig b/modules/hal_nordic/nrfs/Kconfig index 8c5b61bb11f..cf40a64f592 100644 --- a/modules/hal_nordic/nrfs/Kconfig +++ b/modules/hal_nordic/nrfs/Kconfig @@ -19,6 +19,9 @@ config NRFS_HAS_DIAG_SERVICE config NRFS_HAS_DVFS_SERVICE bool +config NRFS_HAS_GDFS_SERVICE + bool + config NRFS_HAS_GDPWR_SERVICE bool @@ -117,6 +120,11 @@ config NRFS_GDPWR_SERVICE_ENABLED depends on NRFS_HAS_GDPWR_SERVICE default y +config NRFS_GDFS_SERVICE_ENABLED + bool "Global domain frequency scaling service" + depends on NRFS_HAS_GDFS_SERVICE + default y + endmenu rsource "backends/Kconfig" diff --git a/modules/hal_nordic/nrfs/nrfs_config.h b/modules/hal_nordic/nrfs/nrfs_config.h index a092adb7850..45e9e446b71 100644 --- a/modules/hal_nordic/nrfs/nrfs_config.h +++ b/modules/hal_nordic/nrfs/nrfs_config.h @@ -44,6 +44,10 @@ #define NRFS_GDPWR_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 diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 36979b554e0..d54ef99da8e 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -25,6 +25,7 @@ config SOC_NRF54H20_CPUAPP_COMMON select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select NRFS_HAS_CLOCK_SERVICE select NRFS_HAS_DVFS_SERVICE + select NRFS_HAS_GDFS_SERVICE select NRFS_HAS_GDPWR_SERVICE select NRFS_HAS_MRAM_SERVICE select NRFS_HAS_TEMP_SERVICE @@ -48,6 +49,7 @@ config SOC_NRF54H20_CPURAD_COMMON select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select NRFS_HAS_CLOCK_SERVICE + select NRFS_HAS_GDFS_SERVICE select NRFS_HAS_GDPWR_SERVICE select NRFS_HAS_MRAM_SERVICE select NRFS_HAS_TEMP_SERVICE From cea0d9dcd64774a9b6cb34787abc787628374ca0 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 21 Nov 2024 13:38:40 +0100 Subject: [PATCH 08/12] [nrf fromlist] dts: nordic: specify device model of global hsfll clock Add specific device model for global hsfll clock and update dts tree to use specific model. The clock is not fixed, and configurable at runtime to predefined frequencies specified by the platform. Upstream PR #: 81735 Signed-off-by: Bjarki Arge Andreasen --- .../clock/nordic,nrf-hsfll-global.yaml | 44 +++++++++++++++++++ dts/common/nordic/nrf54h20.dtsi | 8 +++- 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 dts/bindings/clock/nordic,nrf-hsfll-global.yaml diff --git a/dts/bindings/clock/nordic,nrf-hsfll-global.yaml b/dts/bindings/clock/nordic,nrf-hsfll-global.yaml new file mode 100644 index 00000000000..d743cd76679 --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-hsfll-global.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic Global HSFLL clock. + + The lowest supported clock frequency is the default + clock frequency. + + Example: + + global_hsfll: global_hsfll { + compatible = "nordic,nrf-hsfll-global"; + clocks = <&fll16>; + #clock-cells = <0>; + clock-frequency = <320000000>; + supported-clock-frequencies = <64000000 + 128000000 + 256000000 + 320000000>; + }; + +compatible: "nordic,nrf-hsfll-global" + +include: + - "base.yaml" + - "clock-controller.yaml" + +properties: + clocks: + required: true + + "#clock-cells": + const: 0 + + supported-clock-frequencies: + type: array + description: Supported clock frequencies in ascending order + + clock-frequency: + type: int + description: | + Optional fixed frequency specified if used in fixed + frequency mode. diff --git a/dts/common/nordic/nrf54h20.dtsi b/dts/common/nordic/nrf54h20.dtsi index 4ef0a05a302..8ca2357039f 100644 --- a/dts/common/nordic/nrf54h20.dtsi +++ b/dts/common/nordic/nrf54h20.dtsi @@ -180,10 +180,14 @@ }; hsfll120: hsfll120 { - compatible = "fixed-clock"; + compatible = "nordic,nrf-hsfll-global"; clocks = <&fll16m>; #clock-cells = <0>; - clock-frequency = ; + clock-frequency = <320000000>; + supported-clock-frequencies = <64000000 + 128000000 + 256000000 + 320000000>; }; lfclk: lfclk { From 0105b0deb86765cb896ed1abdc38c9977ffb24f5 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 2 Dec 2024 12:50:22 +0100 Subject: [PATCH 09/12] [nrf fromlist] dts: bindings: update nrf-hsfll to nrf-hsfll-local The nrf-hsfll was previously the only supported HSFLL clock, hence it was not namespaced fully. Since we added nrf-hsfll-global, we should add the namespace to nrf-hsfll as well. Updates drivers and devicetree uses of HSFLL as well. Upstream PR #: 81735 Signed-off-by: Bjarki Arge Andreasen --- drivers/clock_control/clock_control_nrf2_hsfll.c | 2 +- ...rdic,nrf-hsfll.yaml => nordic,nrf-hsfll-local.yaml} | 10 +++++----- dts/common/nordic/nrf54h20.dtsi | 4 ++-- dts/common/nordic/nrf9280.dtsi | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) rename dts/bindings/clock/{nordic,nrf-hsfll.yaml => nordic,nrf-hsfll-local.yaml} (83%) diff --git a/drivers/clock_control/clock_control_nrf2_hsfll.c b/drivers/clock_control/clock_control_nrf2_hsfll.c index 026edf9abbd..b0d0ff364b3 100644 --- a/drivers/clock_control/clock_control_nrf2_hsfll.c +++ b/drivers/clock_control/clock_control_nrf2_hsfll.c @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_nrf_hsfll +#define DT_DRV_COMPAT nordic_nrf_hsfll_local #include "clock_control_nrf2_common.h" #include diff --git a/dts/bindings/clock/nordic,nrf-hsfll.yaml b/dts/bindings/clock/nordic,nrf-hsfll-local.yaml similarity index 83% rename from dts/bindings/clock/nordic,nrf-hsfll.yaml rename to dts/bindings/clock/nordic,nrf-hsfll-local.yaml index f1077dbc4f0..01d0dd7aa3a 100644 --- a/dts/bindings/clock/nordic,nrf-hsfll.yaml +++ b/dts/bindings/clock/nordic,nrf-hsfll-local.yaml @@ -2,15 +2,15 @@ # SPDX-License-Identifier: Apache-2.0 description: | - Nordic nRF HSFLL + Nordic nRF local HSFLL - The HSFLL mixed-mode IP generates several clock frequencies in the range from - 64 MHz to 400 MHz (in steps of 16 MHz). + The local HSFLL mixed-mode IP generates several clock frequencies in the range + from 64 MHz to 400 MHz (in steps of 16 MHz). Usage example: hsfll: clock@deadbeef { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; reg = <0xdeadbeef 0x1000>; clocks = <&fll16m>; clock-frequency = ; @@ -22,7 +22,7 @@ description: | Required FICR entries are for VSUP, COARSE and FINE trim values. -compatible: "nordic,nrf-hsfll" +compatible: "nordic,nrf-hsfll-local" include: [base.yaml, fixed-clock.yaml, nordic-nrf-ficr-client.yaml] diff --git a/dts/common/nordic/nrf54h20.dtsi b/dts/common/nordic/nrf54h20.dtsi index 8ca2357039f..034813bc076 100644 --- a/dts/common/nordic/nrf54h20.dtsi +++ b/dts/common/nordic/nrf54h20.dtsi @@ -259,7 +259,7 @@ ranges = <0x0 0x52000000 0x1000000>; cpuapp_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; @@ -313,7 +313,7 @@ ranges = <0x0 0x53000000 0x1000000>; cpurad_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; diff --git a/dts/common/nordic/nrf9280.dtsi b/dts/common/nordic/nrf9280.dtsi index 4fd64cd10be..62b22b4fbc2 100644 --- a/dts/common/nordic/nrf9280.dtsi +++ b/dts/common/nordic/nrf9280.dtsi @@ -149,7 +149,7 @@ ranges = <0x0 0x52000000 0x1000000>; cpuapp_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; @@ -201,7 +201,7 @@ ranges = <0x0 0x53000000 0x1000000>; cpurad_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; From 37d128092d6eaa115fb6415aa8b48b15b87191d5 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 21 Nov 2024 13:53:47 +0100 Subject: [PATCH 10/12] [nrf fromlist] drivers: clock_control: nrf2: add support for global hfsll clock Add device driver support for global hsfll clock. Upstream PR #: 81735 Signed-off-by: Bjarki Arge Andreasen --- drivers/clock_control/CMakeLists.txt | 1 + drivers/clock_control/Kconfig.nrf | 27 ++ .../clock_control_nrf2_global_hsfll.c | 302 ++++++++++++++++++ .../clock_control/clock_control_nrf2_hsfll.c | 14 - 4 files changed, 330 insertions(+), 14 deletions(-) create mode 100644 drivers/clock_control/clock_control_nrf2_global_hsfll.c diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index ffc19a3b729..d3d1807d6cf 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -35,6 +35,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RENESAS_RA_CGC clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AMBIQ clock_control_ambiq.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_PWM clock_control_pwm.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RPI_PICO clock_control_rpi_pico.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL clock_control_nrf2_global_hsfll.c) if(CONFIG_CLOCK_CONTROL_NRF2) zephyr_library_sources(clock_control_nrf2_common.c) diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index f7b0de3db09..3965bb06e25 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -193,4 +193,31 @@ config CLOCK_CONTROL_NRF2_NRFS_CLOCK_TIMEOUT_MS int "Timeout waiting for nrfs clock service callback in milliseconds" default 1000 +config CLOCK_CONTROL_NRF2_GLOBAL_HSFLL + bool "Clock control for global HSFLL" + depends on NRFS_GDFS_SERVICE_ENABLED + default y + +if CLOCK_CONTROL_NRF2_GLOBAL_HSFLL + +config CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_TIMEOUT_MS + int "Frequency request timeout in milliseconds" + default 10000 + +config CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_REQ_LOW_FREQ + bool "Request LOW frequency on init" + default y + help + The GDFS service will default to HIGH frequency until it receives + a lower frequency request. The NRF2 clock controller drivers + expect the clock to be initialized to their lowest frequency, so + we need to send a request on init to align GDFS with the NRF2 + clock controller driver. + + This initial request can be disabled to prevent a potentially + unnecessary HIGH -> LOW -> HIGH cycle given some module will + request a HIGH frequency on init anyway. + +endif # CLOCK_CONTROL_NRF2_GLOBAL_HSFLL + endif # CLOCK_CONTROL_NRF2 diff --git a/drivers/clock_control/clock_control_nrf2_global_hsfll.c b/drivers/clock_control/clock_control_nrf2_global_hsfll.c new file mode 100644 index 00000000000..79005f427ae --- /dev/null +++ b/drivers/clock_control/clock_control_nrf2_global_hsfll.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_hsfll_global + +#include "clock_control_nrf2_common.h" +#include +#include +#include + +#include +LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +#define GLOBAL_HSFLL_CLOCK_FREQUENCIES \ + DT_INST_PROP(0, supported_clock_frequencies) + +#define GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(idx) \ + DT_INST_PROP_BY_IDX(0, supported_clock_frequencies, idx) + +#define GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE \ + DT_INST_PROP_LEN(0, supported_clock_frequencies) + +#define GLOBAL_HSFLL_FREQ_REQ_TIMEOUT \ + K_MSEC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_TIMEOUT_MS) + +#define GLOBAL_HSFLL_INIT_LOW_REQ \ + CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_REQ_LOW_FREQ + +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE == 4); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(0) == 64000000); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(1) == 128000000); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(2) == 256000000); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(3) == 320000000); +BUILD_ASSERT(GDFS_FREQ_COUNT == 4); +BUILD_ASSERT(GDFS_FREQ_HIGH == 0); +BUILD_ASSERT(GDFS_FREQ_MEDHIGH == 1); +BUILD_ASSERT(GDFS_FREQ_MEDLOW == 2); +BUILD_ASSERT(GDFS_FREQ_LOW == 3); + +struct global_hsfll_dev_config { + uint32_t clock_frequencies[GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE]; +}; + +struct global_hsfll_dev_data { + STRUCT_CLOCK_CONFIG(global_hsfll, GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE) clk_cfg; + const struct device *dev; + struct k_work evt_work; + nrfs_gdfs_evt_type_t evt; + struct k_work_delayable timeout_dwork; + +#if GLOBAL_HSFLL_INIT_LOW_REQ + struct k_sem evt_sem; +#endif /* GLOBAL_HSFLL_INIT_LOW_REQ */ +}; + +static uint32_t global_hsfll_get_max_clock_frequency(const struct device *dev) +{ + const struct global_hsfll_dev_config *dev_config = dev->config; + + return dev_config->clock_frequencies[ARRAY_SIZE(dev_config->clock_frequencies) - 1]; +} + +static struct onoff_manager *global_hsfll_find_mgr(const struct device *dev, + const struct nrf_clock_spec *spec) +{ + struct global_hsfll_dev_data *dev_data = dev->data; + const struct global_hsfll_dev_config *dev_config = dev->config; + uint32_t frequency; + + if (!spec) { + return &dev_data->clk_cfg.onoff[0].mgr; + } + + if (spec->accuracy || spec->precision) { + LOG_ERR("invalid specification of accuracy or precision"); + return NULL; + } + + frequency = spec->frequency == NRF_CLOCK_CONTROL_FREQUENCY_MAX + ? global_hsfll_get_max_clock_frequency(dev) + : spec->frequency; + + for (uint8_t i = 0; i < ARRAY_SIZE(dev_config->clock_frequencies); i++) { + if (dev_config->clock_frequencies[i] < frequency) { + continue; + } + + return &dev_data->clk_cfg.onoff[i].mgr; + } + + LOG_ERR("invalid frequency"); + return NULL; +} + +static int api_request_global_hsfll(const struct device *dev, + const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ + struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec); + + if (mgr) { + return onoff_request(mgr, cli); + } + + return -EINVAL; +} + +static int api_release_global_hsfll(const struct device *dev, + const struct nrf_clock_spec *spec) +{ + struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec); + + if (mgr) { + return onoff_release(mgr); + } + + return -EINVAL; +} + +static int api_cancel_or_release_global_hsfll(const struct device *dev, + const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ + struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec); + + if (mgr) { + return onoff_cancel_or_release(mgr, cli); + } + + return -EINVAL; +} + +static struct nrf_clock_control_driver_api driver_api = { + .std_api = { + .on = api_nosys_on_off, + .off = api_nosys_on_off, + }, + .request = api_request_global_hsfll, + .release = api_release_global_hsfll, + .cancel_or_release = api_cancel_or_release_global_hsfll, +}; + +static enum gdfs_frequency_setting global_hsfll_freq_idx_to_nrfs_freq(const struct device *dev, + uint8_t freq_idx) +{ + const struct global_hsfll_dev_config *dev_config = dev->config; + + return ARRAY_SIZE(dev_config->clock_frequencies) - 1 - freq_idx; +} + +static const char *global_hsfll_gdfs_freq_to_str(enum gdfs_frequency_setting freq) +{ + switch (freq) { + case GDFS_FREQ_HIGH: + return "GDFS_FREQ_HIGH"; + case GDFS_FREQ_MEDHIGH: + return "GDFS_FREQ_MEDHIGH"; + case GDFS_FREQ_MEDLOW: + return "GDFS_FREQ_MEDLOW"; + case GDFS_FREQ_LOW: + return "GDFS_FREQ_LOW"; + default: + break; + } + + return "UNKNOWN"; +} + +static void global_hsfll_work_handler(struct k_work *work) +{ + struct global_hsfll_dev_data *dev_data = + CONTAINER_OF(work, struct global_hsfll_dev_data, clk_cfg.work); + const struct device *dev = dev_data->dev; + uint8_t freq_idx; + enum gdfs_frequency_setting target_freq; + nrfs_err_t err; + + freq_idx = clock_config_update_begin(work); + target_freq = global_hsfll_freq_idx_to_nrfs_freq(dev, freq_idx); + + LOG_DBG("requesting %s", global_hsfll_gdfs_freq_to_str(target_freq)); + err = nrfs_gdfs_request_freq(target_freq, dev_data); + if (err != NRFS_SUCCESS) { + clock_config_update_end(&dev_data->clk_cfg, -EIO); + return; + } + + k_work_schedule(&dev_data->timeout_dwork, GLOBAL_HSFLL_FREQ_REQ_TIMEOUT); +} + +static void global_hsfll_evt_handler(struct k_work *work) +{ + struct global_hsfll_dev_data *dev_data = + CONTAINER_OF(work, struct global_hsfll_dev_data, evt_work); + int rc; + + k_work_cancel_delayable(&dev_data->timeout_dwork); + rc = dev_data->evt == NRFS_GDFS_EVT_FREQ_CONFIRMED ? 0 : -EIO; + clock_config_update_end(&dev_data->clk_cfg, rc); +} + +#if GLOBAL_HSFLL_INIT_LOW_REQ +static void global_hfsll_nrfs_gdfs_init_evt_handler(nrfs_gdfs_evt_t const *p_evt, void *context) +{ + struct global_hsfll_dev_data *dev_data = context; + + dev_data->evt = p_evt->type; + k_sem_give(&dev_data->evt_sem); +} +#endif /* GLOBAL_HSFLL_INIT_LOW_REQ */ + +static void global_hfsll_nrfs_gdfs_evt_handler(nrfs_gdfs_evt_t const *p_evt, void *context) +{ + struct global_hsfll_dev_data *dev_data = context; + + if (k_work_is_pending(&dev_data->evt_work)) { + return; + } + + dev_data->evt = p_evt->type; + k_work_submit(&dev_data->evt_work); +} + +static void global_hsfll_timeout_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct global_hsfll_dev_data *dev_data = + CONTAINER_OF(dwork, struct global_hsfll_dev_data, timeout_dwork); + + clock_config_update_end(&dev_data->clk_cfg, -ETIMEDOUT); +} + +static int global_hfsll_init(const struct device *dev) +{ + struct global_hsfll_dev_data *dev_data = dev->data; + nrfs_err_t err; + int rc; + + k_work_init_delayable(&dev_data->timeout_dwork, global_hsfll_timeout_handler); + k_work_init(&dev_data->evt_work, global_hsfll_evt_handler); + +#if GLOBAL_HSFLL_INIT_LOW_REQ + k_sem_init(&dev_data->evt_sem, 0, 1); + + err = nrfs_gdfs_init(global_hfsll_nrfs_gdfs_init_evt_handler); + if (err != NRFS_SUCCESS) { + return -EIO; + } + + LOG_DBG("initial request %s", global_hsfll_gdfs_freq_to_str(GDFS_FREQ_LOW)); + err = nrfs_gdfs_request_freq(GDFS_FREQ_LOW, dev_data); + if (err != NRFS_SUCCESS) { + return -EIO; + } + + rc = k_sem_take(&dev_data->evt_sem, GLOBAL_HSFLL_FREQ_REQ_TIMEOUT); + if (rc) { + return -EIO; + } + + if (dev_data->evt != NRFS_GDFS_EVT_FREQ_CONFIRMED) { + return -EIO; + } + + nrfs_gdfs_uninit(); +#endif /* GLOBAL_HSFLL_INIT_LOW_REQ */ + + rc = clock_config_init(&dev_data->clk_cfg, + ARRAY_SIZE(dev_data->clk_cfg.onoff), + global_hsfll_work_handler); + if (rc < 0) { + return rc; + } + + err = nrfs_gdfs_init(global_hfsll_nrfs_gdfs_evt_handler); + if (err != NRFS_SUCCESS) { + return -EIO; + } + + return 0; +} + +static struct global_hsfll_dev_data driver_data = { + .dev = DEVICE_DT_INST_GET(0), +}; + +static const struct global_hsfll_dev_config driver_config = { + GLOBAL_HSFLL_CLOCK_FREQUENCIES +}; + +DEVICE_DT_INST_DEFINE( + 0, + global_hfsll_init, + NULL, + &driver_data, + &driver_config, + POST_KERNEL, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, + &driver_api +); diff --git a/drivers/clock_control/clock_control_nrf2_hsfll.c b/drivers/clock_control/clock_control_nrf2_hsfll.c index b0d0ff364b3..58ad4a51ff5 100644 --- a/drivers/clock_control/clock_control_nrf2_hsfll.c +++ b/drivers/clock_control/clock_control_nrf2_hsfll.c @@ -8,7 +8,6 @@ #include "clock_control_nrf2_common.h" #include #include -#include #include LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); @@ -183,18 +182,6 @@ static int api_cancel_or_release_hsfll(const struct device *dev, #endif } -static int api_get_rate_hsfll(const struct device *dev, - clock_control_subsys_t sys, - uint32_t *rate) -{ - ARG_UNUSED(dev); - ARG_UNUSED(sys); - - *rate = nrf_hsfll_clkctrl_mult_get(NRF_HSFLL) * MHZ(16); - - return 0; -} - static int hsfll_init(const struct device *dev) { #ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN @@ -221,7 +208,6 @@ static struct nrf_clock_control_driver_api hsfll_drv_api = { .std_api = { .on = api_nosys_on_off, .off = api_nosys_on_off, - .get_rate = api_get_rate_hsfll, }, .request = api_request_hsfll, .release = api_release_hsfll, From c5816528f2e36bafb0edb53d740dbb739b8fc030 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 21 Nov 2024 21:46:22 +0100 Subject: [PATCH 11/12] [nrf fromlist] samples: boards: nordic: clock_control: support global hsfll Extend sample to support global hsfll clock control. Upstream PR #: 81735 Signed-off-by: Bjarki Arge Andreasen --- .../nordic/clock_control/configs/global_hsfll.conf | 6 ++++++ .../clock_control/configs/global_hsfll.overlay | 11 +++++++++++ samples/boards/nordic/clock_control/sample.yaml | 12 ++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 samples/boards/nordic/clock_control/configs/global_hsfll.conf create mode 100644 samples/boards/nordic/clock_control/configs/global_hsfll.overlay diff --git a/samples/boards/nordic/clock_control/configs/global_hsfll.conf b/samples/boards/nordic/clock_control/configs/global_hsfll.conf new file mode 100644 index 00000000000..53eebac30be --- /dev/null +++ b/samples/boards/nordic/clock_control/configs/global_hsfll.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CLOCK_CONTROL=y + +CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ=320000000 diff --git a/samples/boards/nordic/clock_control/configs/global_hsfll.overlay b/samples/boards/nordic/clock_control/configs/global_hsfll.overlay new file mode 100644 index 00000000000..24585f5a5c6 --- /dev/null +++ b/samples/boards/nordic/clock_control/configs/global_hsfll.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/{ + aliases { + sample-clock = &hsfll120; + }; +}; diff --git a/samples/boards/nordic/clock_control/sample.yaml b/samples/boards/nordic/clock_control/sample.yaml index dd2cfe86c41..820ad0de75f 100644 --- a/samples/boards/nordic/clock_control/sample.yaml +++ b/samples/boards/nordic/clock_control/sample.yaml @@ -29,3 +29,15 @@ tests: extra_args: - CONF_FILE="configs/cpuapp_hsfll.conf" - DTC_OVERLAY_FILE="configs/cpuapp_hsfll.overlay" + sample.boards.nrf.clock_control.global_hsfll: + filter: dt_nodelabel_enabled("hsfll120") + extra_args: + - CONF_FILE="configs/global_hsfll.conf" + - DTC_OVERLAY_FILE="configs/global_hsfll.overlay" + sample.boards.nrf.clock_control.global_hsfll.req_low_freq_n: + filter: dt_nodelabel_enabled("hsfll120") + extra_configs: + - CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_REQ_LOW_FREQ=n + extra_args: + - CONF_FILE="configs/global_hsfll.conf" + - DTC_OVERLAY_FILE="configs/global_hsfll.overlay" From 8eea788fc1833251e4bd5e0bf73e3f7987d19877 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 21 Nov 2024 21:54:21 +0100 Subject: [PATCH 12/12] [nrf fromlist] tests: drivers: clock_control: nrf: add global hsfll clock Extend test suite to test global HSFLL clock. Upstream PR #: 81735 Signed-off-by: Bjarki Arge Andreasen --- .../nrf_clock_control/src/main.c | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/tests/drivers/clock_control/nrf_clock_control/src/main.c b/tests/drivers/clock_control/nrf_clock_control/src/main.c index 60cb9549f3d..1f12969eb3d 100644 --- a/tests/drivers/clock_control/nrf_clock_control/src/main.c +++ b/tests/drivers/clock_control/nrf_clock_control/src/main.c @@ -104,6 +104,29 @@ static const struct test_clk_context cpurad_hsfll_test_clk_contexts[] = { }; #endif +const struct nrf_clock_spec test_clk_specs_global_hsfll[] = { + { + .frequency = MHZ(320), + }, + { + .frequency = MHZ(256), + }, + { + .frequency = MHZ(128), + }, + { + .frequency = MHZ(64), + }, +}; + +static const struct test_clk_context global_hsfll_test_clk_contexts[] = { + { + .clk_dev = DEVICE_DT_GET(DT_NODELABEL(hsfll120)), + .clk_specs = test_clk_specs_global_hsfll, + .clk_specs_size = ARRAY_SIZE(test_clk_specs_global_hsfll), + }, +}; + const struct nrf_clock_spec test_clk_specs_lfclk[] = { { .frequency = 32768, @@ -151,8 +174,10 @@ static void test_request_release_clock_spec(const struct device *clk_dev, zassert_ok(ret); zassert_ok(res); ret = clock_control_get_rate(clk_dev, NULL, &rate); - zassert_ok(ret); - zassert_equal(rate, clk_spec->frequency); + if (ret != -ENOSYS) { + zassert_ok(ret); + zassert_equal(rate, clk_spec->frequency); + } k_msleep(1000); ret = nrf_clock_control_release(clk_dev, clk_spec); zassert_equal(ret, ONOFF_STATE_ON); @@ -249,6 +274,13 @@ ZTEST(nrf2_clock_control, test_lfclk_control) test_clock_control_request(lfclk_test_clk_contexts, ARRAY_SIZE(lfclk_test_clk_contexts)); } +ZTEST(nrf2_clock_control, test_global_hsfll_control) +{ + TC_PRINT("Global HSFLL test\n"); + test_clock_control_request(global_hsfll_test_clk_contexts, + ARRAY_SIZE(global_hsfll_test_clk_contexts)); +} + ZTEST(nrf2_clock_control, test_safe_request_cancellation) { int ret = 0;