From 50c748ac35ddca2d4b21eed100dbb30fef1841d9 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 8 Jun 2025 08:11:20 +0900 Subject: [PATCH 1/9] [nrf fromtree] devicetree: Use `IS_EQ()` for `DT_SAME_NODE()` `DT_SAME_NODE()` is judged by `==` and cannot be used as a condition for `COND_CODE_1()`. Using `IS_EQ()` to make it possible for compile-time calculation. Signed-off-by: TOKITA Hiroshi (cherry picked from commit ba48d83bec18e9f2caf61979aadf9f8537086cee) --- include/zephyr/devicetree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 665c10c6805..870a1615207 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -690,7 +690,7 @@ * refer to the same node, and evaluates to 0 otherwise */ #define DT_SAME_NODE(node_id1, node_id2) \ - (DT_DEP_ORD(node_id1) == (DT_DEP_ORD(node_id2))) + IS_EQ(DT_DEP_ORD(node_id1), DT_DEP_ORD(node_id2)) /** * @brief Get a devicetree node's node labels as an array of strings From 93c6074d932a03b48a8b48cb7bf5ab53a442f3e0 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 2 Jul 2025 22:14:42 +0200 Subject: [PATCH 2/9] [nrf fromtree] drivers: power_domain: introduce nrfs gdpwr Introduce the NRFS GDPWR (Global Domain Power Request) device driver and devicetree binding. Signed-off-by: Bjarki Arge Andreasen (cherry picked from commit 0ec81c5fdf9de986199f535ab96067460dfeffc9) --- drivers/power_domain/CMakeLists.txt | 1 + drivers/power_domain/Kconfig | 2 + drivers/power_domain/Kconfig.nrfs_gdpwr | 17 ++ .../power_domain/power_domain_nrfs_gdpwr.c | 282 ++++++++++++++++++ .../power-domain/nordic,nrfs-gdpwr.yaml | 65 ++++ 5 files changed, 367 insertions(+) create mode 100644 drivers/power_domain/Kconfig.nrfs_gdpwr create mode 100644 drivers/power_domain/power_domain_nrfs_gdpwr.c create mode 100644 dts/bindings/power-domain/nordic,nrfs-gdpwr.yaml diff --git a/drivers/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index d459e0d88c3..4cef02dd6a1 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -7,4 +7,5 @@ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO power_domain_gpio.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO_MONITOR power_domain_gpio_monitor.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_adsp.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NXP_SCU power_domain_nxp_scu.c) +zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRFS_GDPWR power_domain_nrfs_gdpwr.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_SOC_PM_STATE power_domain_soc_state_change.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index 7bf5fe42470..967103da45e 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -99,4 +99,6 @@ config POWER_DOMAIN_SOC_PM_STATE Generic power domain control to turn on/off devices when the PM subsystem transitions in and out certain power states. +rsource "Kconfig.nrfs_gdpwr" + endif diff --git a/drivers/power_domain/Kconfig.nrfs_gdpwr b/drivers/power_domain/Kconfig.nrfs_gdpwr new file mode 100644 index 00000000000..bf9abd59aed --- /dev/null +++ b/drivers/power_domain/Kconfig.nrfs_gdpwr @@ -0,0 +1,17 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config POWER_DOMAIN_NRFS_GDPWR + bool "NRFS Global Domain Power Request driver" + depends on DT_HAS_NORDIC_NRFS_GDPWR_ENABLED + select NRFS + select NRFS_GDPWR_SERVICE_ENABLED + default y + +if POWER_DOMAIN_NRFS_GDPWR + +config POWER_DOMAIN_NRFS_GDPWR_TIMEOUT_MS + int "GDPWR request timeout in milliseconds" + default 500 + +endif # POWER_DOMAIN_NRFS_GDPWR diff --git a/drivers/power_domain/power_domain_nrfs_gdpwr.c b/drivers/power_domain/power_domain_nrfs_gdpwr.c new file mode 100644 index 00000000000..64e83f5774b --- /dev/null +++ b/drivers/power_domain/power_domain_nrfs_gdpwr.c @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrfs_gdpwr + +#include +#include +#include +#include + +#include +#include + +LOG_MODULE_REGISTER(nrfs_gdpwr, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +#define MANAGER_REQUEST_TIMEOUT K_MSEC(CONFIG_POWER_DOMAIN_NRFS_GDPWR_TIMEOUT_MS) + +static K_SEM_DEFINE(lock_sem, 1, 1); +static K_SEM_DEFINE(req_sem, 0, 1); +static nrfs_gdpwr_evt_type_t req_resp; +static const struct device *const domains[] = { + DT_INST_FOREACH_CHILD_SEP(0, DEVICE_DT_GET, (,)) +}; + +struct domain_data { + bool off; + bool synced; +}; + +struct domain_config { + gdpwr_power_domain_t domain; +}; + +static void manager_event_handler(nrfs_gdpwr_evt_t const *evt, void *context) +{ + ARG_UNUSED(context); + + req_resp = evt->type; + k_sem_give(&req_sem); +} + +static void manager_lock(void) +{ + if (k_is_pre_kernel()) { + return; + } + + (void)k_sem_take(&lock_sem, K_FOREVER); +} + +static void manager_unlock(void) +{ + if (k_is_pre_kernel()) { + return; + } + + k_sem_give(&lock_sem); +} + +static int manager_set_domain_locked(gdpwr_power_domain_t domain, bool on) +{ + nrfs_err_t err; + gdpwr_request_type_t req = on ? GDPWR_POWER_REQUEST_SET : GDPWR_POWER_REQUEST_CLEAR; + int ret; + + err = nrfs_gdpwr_power_request(domain, req, NULL); + if (err != NRFS_SUCCESS) { + LOG_ERR("%s %s", "nrfs gdpwr request", "failed"); + return -EIO; + } + + ret = k_sem_take(&req_sem, MANAGER_REQUEST_TIMEOUT); + if (ret < 0) { + LOG_ERR("%s %s", "nrfs gdpwr request", "timed out"); + return -ETIMEDOUT; + } + + if (req_resp != NRFS_GDPWR_REQ_APPLIED) { + LOG_ERR("%s %s", "nrfs gdpwr request", "rejected"); + return -EIO; + } + + return 0; +} + +static int manager_set_domain(const struct device *dev, bool on) +{ + struct domain_data *dev_data = dev->data; + const struct domain_config *dev_config = dev->config; + int ret; + + manager_lock(); + + if (dev_data->synced) { + /* NRFS GDPWR service is ready so we request domain change state */ + ret = manager_set_domain_locked(dev_config->domain, on); + } else { + /* + * NRFS GDPWR service is not ready so we track what the expected + * state of the power domain to be requested once the service + * is ready. + */ + ret = 0; + dev_data->off = !on; + } + + if (ret == 0) { + LOG_DBG("domain %s %ssynced and %s", + dev->name, + dev_data->synced ? "" : "un", + on ? "on" : "off"); + } + + manager_unlock(); + return ret; +} + +static int manager_sync_domain_locked(const struct device *dev) +{ + struct domain_data *dev_data = dev->data; + const struct domain_config *dev_config = dev->config; + + /* + * NRFS service is now ready. We will now synchronize the state + * of the power domain with the expected state we tracked with + * the struct domain_data off member. Following this, tracking + * the power domain state is handled by device PM, thus the + * struct domain_data off is no longer used. + */ + dev_data->synced = true; + + /* + * Power domains initialize ON so we only need to send a request + * if the expected state of the power domain is OFF. + */ + if (dev_data->off) { + return manager_set_domain_locked(dev_config->domain, false); + } + + return 0; +} + +static int manager_sync_domains_locked(void) +{ + int ret; + + ARRAY_FOR_EACH(domains, i) { + ret = manager_sync_domain_locked(domains[i]); + if (ret) { + break; + } + } + + return ret; +} + +static int manager_init(void) +{ + nrfs_err_t err; + int ret; + + err = nrfs_backend_wait_for_connection(K_FOREVER); + if (err != NRFS_SUCCESS) { + LOG_ERR("%s %s", "nrfs backend connection", "failed"); + return -EIO; + } + + err = nrfs_gdpwr_init(manager_event_handler); + if (err != NRFS_SUCCESS) { + LOG_ERR("%s %s", "nrfs gdpwr init", "failed"); + return -EIO; + } + + manager_lock(); + ret = manager_sync_domains_locked(); + manager_unlock(); + return ret; +} + +SYS_INIT(manager_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); + +#if IS_ENABLED(CONFIG_DEVICE_DEPS) && IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN) +static void domain_pm_notify_children(const struct device *dev, + enum pm_device_action action) +{ + pm_device_children_action_run(dev, action, NULL); +} +#else +static void domain_pm_notify_children(const struct device *dev, + enum pm_device_action action) +{ + ARG_UNUSED(dev); + ARG_UNUSED(action); +} +#endif + +static int domain_pm_suspend(const struct device *dev) +{ + int ret; + + domain_pm_notify_children(dev, PM_DEVICE_ACTION_TURN_OFF); + + ret = manager_set_domain(dev, false); + if (ret) { + domain_pm_notify_children(dev, PM_DEVICE_ACTION_TURN_ON); + } + + return ret; +} + +static int domain_pm_resume(const struct device *dev) +{ + int ret; + + ret = manager_set_domain(dev, true); + if (ret == 0) { + domain_pm_notify_children(dev, PM_DEVICE_ACTION_TURN_ON); + } + + return ret; +} + +static int domain_pm_action(const struct device *dev, enum pm_device_action action) +{ + int ret; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + ret = domain_pm_suspend(dev); + break; + + case PM_DEVICE_ACTION_RESUME: + ret = domain_pm_resume(dev); + break; + + case PM_DEVICE_ACTION_TURN_OFF: + case PM_DEVICE_ACTION_TURN_ON: + ret = -ENOTSUP; + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int domain_init(const struct device *dev) +{ + return pm_device_driver_init(dev, domain_pm_action); +} + +#define DOMAIN_NODE_SYMNAME(node, sym) \ + _CONCAT_4(domain, _, sym, DT_NODE_CHILD_IDX(node)) + +#define DOMAIN_NODE_TO_GDPWR_ENUM(node) \ + _CONCAT(GDPWR_GD_, DT_NODE_FULL_NAME_UPPER_TOKEN(node)) + +#define DOMAIN_DEFINE(node) \ + static struct domain_config DOMAIN_NODE_SYMNAME(node, data); \ + static const struct domain_config DOMAIN_NODE_SYMNAME(node, config) = { \ + .domain = DOMAIN_NODE_TO_GDPWR_ENUM(node), \ + }; \ + \ + PM_DEVICE_DT_DEFINE(node, domain_pm_action); \ + \ + DEVICE_DT_DEFINE( \ + node, \ + domain_init, \ + PM_DEVICE_DT_GET(node), \ + &DOMAIN_NODE_SYMNAME(node, data), \ + &DOMAIN_NODE_SYMNAME(node, config), \ + PRE_KERNEL_1, \ + 0, \ + NULL \ + ); + +DT_INST_FOREACH_CHILD(0, DOMAIN_DEFINE) diff --git a/dts/bindings/power-domain/nordic,nrfs-gdpwr.yaml b/dts/bindings/power-domain/nordic,nrfs-gdpwr.yaml new file mode 100644 index 00000000000..916db56f475 --- /dev/null +++ b/dts/bindings/power-domain/nordic,nrfs-gdpwr.yaml @@ -0,0 +1,65 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic NRFS Global Domain Power Request + + The NRFS Global Domain Power Request service manages + global power domains using NRFS. + + Each child node represents a global power domain, mapped + by name. The fast-active-0 child node is mapped to the + FAST_ACTIVE_0 global power domain. The nodelabel of each + child node is the node name prepended with "gdpwr", + using underscores. + + Example layout: + + gdpwr { + compatible = "nordic,nrfs-gdpwr"; + status = "disabled"; + + gdpwr_fast_active_0: fast-active-0 { + #power-domain-cells = <0>; + }; + + gdpwr_fast_active_1: fast-active-1 { + #power-domain-cells = <0>; + }; + + gdpwr_fast_main: fast-main { + #power-domain-cells = <0>; + }; + + gdpwr_slow_active: slow-active { + #power-domain-cells = <0>; + }; + + gdpwr_slow_main: slow-main { + #power-domain-cells = <0>; + }; + }; + + Example usage: + + uart120: uart@8e6000 { + compatible = "nordic,nrf-uarte"; + reg = <0x8e6000 0x1000>; + status = "disabled"; + power-domains = <&gdpwr_fast_active_1>; + }; + +compatible: "nordic,nrfs-gdpwr" + +include: base.yaml + +child-binding: + description: Nordic NRFS Global Power Domain + + properties: + "#power-domain-cells": + type: int + const: 0 + + zephyr,pm-device-runtime-auto: + type: boolean From 9f6115e43a9db2cfdb35395e3d7b848c7e61c3ef Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 2 Jul 2025 22:23:43 +0200 Subject: [PATCH 3/9] [nrf fromtree] drivers: power_domain: introduce nrf_gpio_pad_group Introduce the NRF GPIO Pad Group device driver and binding. The pad group device represents the GPIO pads (pins), contrary to a GPIO controller, which is one of the many devices which can be muxed to pads in the pad group. The pad group belong to a power domain, which is not neccesarily the same power domain as devices being muxed to the pads, like GPIO or UART. If no ACTIVE device is using any of the pads in the pad group, the pad groups power domain may be SUSPENDED. Before the pad groups power domain is SUSPENDED, pad config retention must be enabled to prevent the pads from loosing their state. That's what this device driver manages. Once retained, the pad configs and outputs are locked, even when their power domain is SUSPENDED. Signed-off-by: Bjarki Arge Andreasen (cherry picked from commit 3a8651ac826314f56c7aa25a7f7c0570985738e5) --- drivers/power_domain/CMakeLists.txt | 1 + drivers/power_domain/Kconfig | 1 + .../power_domain/Kconfig.nrf_gpio_pad_group | 7 ++ .../power_domain_nrf_gpio_pad_group.c | 82 +++++++++++++++++++ .../gpio/nordic,nrf-gpio-pad-group.yaml | 43 ++++++++++ 5 files changed, 134 insertions(+) create mode 100644 drivers/power_domain/Kconfig.nrf_gpio_pad_group create mode 100644 drivers/power_domain/power_domain_nrf_gpio_pad_group.c create mode 100644 dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml diff --git a/drivers/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index 4cef02dd6a1..9d508249f5e 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -8,4 +8,5 @@ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO_MONITOR power_domain_gpio_ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_adsp.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NXP_SCU power_domain_nxp_scu.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRFS_GDPWR power_domain_nrfs_gdpwr.c) +zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRF_GPIO_PAD_GROUP power_domain_nrf_gpio_pad_group.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_SOC_PM_STATE power_domain_soc_state_change.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index 967103da45e..90a10ca9406 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -100,5 +100,6 @@ config POWER_DOMAIN_SOC_PM_STATE PM subsystem transitions in and out certain power states. rsource "Kconfig.nrfs_gdpwr" +rsource "Kconfig.nrf_gpio_pad_group" endif diff --git a/drivers/power_domain/Kconfig.nrf_gpio_pad_group b/drivers/power_domain/Kconfig.nrf_gpio_pad_group new file mode 100644 index 00000000000..1b36c0cc7e0 --- /dev/null +++ b/drivers/power_domain/Kconfig.nrf_gpio_pad_group @@ -0,0 +1,7 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config POWER_DOMAIN_NRF_GPIO_PAD_GROUP + bool "NRFS Global Domain Power Request driver" + depends on DT_HAS_NORDIC_NRF_GPIO_PAD_GROUP_ENABLED + default y diff --git a/drivers/power_domain/power_domain_nrf_gpio_pad_group.c b/drivers/power_domain/power_domain_nrf_gpio_pad_group.c new file mode 100644 index 00000000000..8b4119312c1 --- /dev/null +++ b/drivers/power_domain/power_domain_nrf_gpio_pad_group.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_gpio_pad_group + +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(nrf_gpio_pad_group, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +struct nrf_port_retain_config { + NRF_GPIO_Type *regs; + uint32_t retain_mask; +}; + +static void nrf_port_retain_driver_turn_off(const struct device *dev) +{ + const struct nrf_port_retain_config *dev_config = dev->config; + + LOG_DBG("%s pads 0x%08x retain %s", dev->name, dev_config->retain_mask, "enable"); + nrf_gpio_port_retain_enable(dev_config->regs, dev_config->retain_mask); +} + +static void nrf_port_retain_driver_turn_on(const struct device *dev) +{ + const struct nrf_port_retain_config *dev_config = dev->config; + + LOG_DBG("%s pads 0x%08x retain %s", dev->name, dev_config->retain_mask, "disable"); + nrf_gpio_port_retain_disable(dev_config->regs, dev_config->retain_mask); +} + +static int nrf_port_retain_driver_pm_action(const struct device *dev, + enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_TURN_OFF: + nrf_port_retain_driver_turn_off(dev); + break; + + case PM_DEVICE_ACTION_TURN_ON: + nrf_port_retain_driver_turn_on(dev); + break; + + default: + break; + }; + + return 0; +} + +static int nrf_port_retain_driver_init(const struct device *dev) +{ + return pm_device_driver_init(dev, nrf_port_retain_driver_pm_action); +} + +#define NRF_GPIO_PAD_GROUP_DEFINE(inst) \ + static const struct nrf_port_retain_config _CONCAT(config, inst) = { \ + .regs = (NRF_GPIO_Type *)DT_REG_ADDR(DT_INST_PARENT(inst)), \ + .retain_mask = DT_PROP_OR(inst, retain_mask, UINT32_MAX), \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, nrf_port_retain_driver_pm_action); \ + \ + DEVICE_DT_INST_DEFINE( \ + inst, \ + nrf_port_retain_driver_init, \ + PM_DEVICE_DT_INST_GET(inst), \ + NULL, \ + &_CONCAT(config, inst), \ + PRE_KERNEL_1, \ + UTIL_INC(CONFIG_GPIO_INIT_PRIORITY), \ + NULL \ + ); + +DT_INST_FOREACH_STATUS_OKAY(NRF_GPIO_PAD_GROUP_DEFINE) diff --git a/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml b/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml new file mode 100644 index 00000000000..104277addd3 --- /dev/null +++ b/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml @@ -0,0 +1,43 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic nRF GPIO pad group. + + The GPIO pad group describes the pads (package + pins of the SoC) the GPIO controller manages. + + The pads may be in a different power domain than + the GPIO controller, and may require enabling + retention to preserve the GPIO configuration if + the power domain is suspended. + + The GPIO pad group is a child node of the GPIO + controller which manages the pad group, named + pad-group. The pad group's nodelabel is named + gpio_pad_group. + + Example layout: + + gpio0: gpio@938000 { + compatible = "nordic,nrf-gpio"; + + ... + + gpio_pad_group0: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + }; + }; + +compatible: "nordic,nrf-gpio-pad-group" + +include: base.yaml + +properties: + retain-mask: + type: int + description: | + Mask of pins which shall be retained if pad + group's power domain is powered off. From f8eb3c16beef77c3701a744711ea6ed4a347d3e6 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 3 Jul 2025 02:22:54 +0200 Subject: [PATCH 4/9] [nrf fromtree] soc: nordic: nrf54h: transition from gpd to zephyr pinctrl and pds Transition nrf54h away from the soc specific gpd (global power domain) driver which mixed power domains, pinctrl and gpio pin retention into a non scalable solution, forcing soc specific logic to bleed into nrf drivers. The new solution uses zephyrs PM_DEVICE based power domains to properly model the hardware layout of device and pin power domains, and moves pin retention logic out of drivers into pinctrl and gpio, which are the components which manage pins (pads). Signed-off-by: Bjarki Arge Andreasen (cherry picked from commit 2b0d1ae4d0be84f172f75289a2b07a2e050580ea) --- drivers/can/can_nrf.c | 11 - drivers/counter/counter_nrfx_timer.c | 22 +- drivers/gpio/gpio_nrfx.c | 75 ++--- drivers/pinctrl/pinctrl_nrf.c | 151 ++++++---- drivers/pwm/pwm_nrfx.c | 24 +- drivers/serial/uart_nrfx_uarte.c | 100 ++++--- drivers/spi/spi_nrfx_spim.c | 68 +++-- drivers/spi/spi_nrfx_spis.c | 29 +- dts/arm/nordic/nrf54h20_cpuapp.dtsi | 60 ++++ dts/arm/nordic/nrf54h20_cpurad.dtsi | 60 ++++ dts/vendor/nordic/nrf54h20.dtsi | 268 ++++++++++++------ soc/nordic/common/pinctrl_soc.h | 18 +- soc/nordic/common/soc_nrf_common.h | 46 +++ soc/nordic/nrf54h/Kconfig | 1 - soc/nordic/nrf54h/Kconfig.defconfig | 13 +- .../nrf54h/Kconfig.defconfig.nrf54h20_cpuapp | 3 + .../nrf54h/Kconfig.defconfig.nrf54h20_cpurad | 3 + .../boards/nrf54h20dk_nrf54h20_cpuapp.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpurad.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpuapp.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpurad.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpuapp.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpurad.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpuapp.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpurad.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpuapp.conf | 1 - .../boards/nrf54h20dk_nrf54h20_cpurad.conf | 1 - 27 files changed, 588 insertions(+), 374 deletions(-) delete mode 100644 tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpuapp.conf delete mode 100644 tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpurad.conf delete mode 100644 tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpuapp.conf delete mode 100644 tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpurad.conf delete mode 100644 tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpuapp.conf delete mode 100644 tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpurad.conf delete mode 100644 tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpuapp.conf delete mode 100644 tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf diff --git a/drivers/can/can_nrf.c b/drivers/can/can_nrf.c index f8c037835a8..606117b1948 100644 --- a/drivers/can/can_nrf.c +++ b/drivers/can/can_nrf.c @@ -17,10 +17,6 @@ #include #include -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif - /* nRF CAN wrapper offsets */ #define CAN_TASKS_START offsetof(NRF_CAN_Type, TASKS_START) #define CAN_EVENTS_CORE_0 offsetof(NRF_CAN_Type, EVENTS_CORE[0]) @@ -187,13 +183,6 @@ static int can_nrf_init(const struct device *dev) sys_write32(CAN_INTEN_CORE0_Msk | CAN_INTEN_CORE1_Msk, config->wrapper + CAN_INTEN); sys_write32(1U, config->wrapper + CAN_TASKS_START); -#ifdef CONFIG_SOC_NRF54H20_GPD - ret = nrf_gpd_retain_pins_set(config->pcfg, false); - if (ret < 0) { - return ret; - } -#endif - config->irq_configure(); ret = can_mcan_configure_mram(dev, config->mrba, config->mram); diff --git a/drivers/counter/counter_nrfx_timer.c b/drivers/counter/counter_nrfx_timer.c index 71f7f7edd33..a31d9672c76 100644 --- a/drivers/counter/counter_nrfx_timer.c +++ b/drivers/counter/counter_nrfx_timer.c @@ -35,23 +35,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL); #define MAYBE_CONST_CONFIG const #endif -#ifdef CONFIG_SOC_NRF54H20_GPD -#include - -#define NRF_CLOCKS_INSTANCE_IS_FAST(node) \ - COND_CODE_1(DT_NODE_HAS_PROP(node, power_domains), \ - (IS_EQ(DT_PHA(node, power_domains, id), NRF_GPD_FAST_ACTIVE1)), \ - (0)) - -/* Macro must resolve to literal 0 or 1 */ -#define INSTANCE_IS_FAST(idx) NRF_CLOCKS_INSTANCE_IS_FAST(DT_DRV_INST(idx)) - -#define INSTANCE_IS_FAST_OR(idx) INSTANCE_IS_FAST(idx) || - -#if (DT_INST_FOREACH_STATUS_OKAY(INSTANCE_IS_FAST_OR) 0) +#if NRF_DT_INST_ANY_IS_FAST #define COUNTER_ANY_FAST 1 #endif -#endif struct counter_nrfx_data { counter_top_callback_t top_cb; @@ -474,13 +460,13 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { * which is using nrfs (IPC) are initialized later. */ #define TIMER_INIT_LEVEL(idx) \ - COND_CODE_1(INSTANCE_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1)) + COND_CODE_1(NRF_DT_INST_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1)) /* Get initialization priority of an instance. Instances that requires clock control * which is using nrfs (IPC) are initialized later. */ #define TIMER_INIT_PRIO(idx) \ - COND_CODE_1(INSTANCE_IS_FAST(idx), \ + COND_CODE_1(NRF_DT_INST_IS_FAST(idx), \ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ (CONFIG_COUNTER_INIT_PRIORITY)) @@ -536,7 +522,7 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { }, \ .ch_data = counter##idx##_ch_data, \ .timer = (NRF_TIMER_Type *)DT_INST_REG_ADDR(idx), \ - IF_ENABLED(INSTANCE_IS_FAST(idx), \ + IF_ENABLED(NRF_DT_INST_IS_FAST(idx), \ (.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_DRV_INST(idx))), \ .clk_spec = { \ .frequency = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)), \ diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index f7c57156361..412d0a16d05 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -16,8 +16,10 @@ #include -#ifdef CONFIG_SOC_NRF54H20_GPD -#include +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_gpio_pad_group) +#define GPIO_HAS_PAD_GROUP 1 +#else +#define GPIO_HAS_PAD_GROUP 0 #endif #define GPIOTE_PHANDLE(id) DT_INST_PHANDLE(id, gpiote_instance) @@ -56,8 +58,8 @@ struct gpio_nrfx_cfg { #if defined(GPIOTE_FEATURE_FLAG) uint32_t flags; #endif -#ifdef CONFIG_SOC_NRF54H20_GPD - uint8_t pad_pd; +#if GPIO_HAS_PAD_GROUP + const struct device *pad_group; #endif }; @@ -87,30 +89,6 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) return NRF_GPIO_PIN_NOPULL; } -static void gpio_nrfx_gpd_retain_set(const struct device *port, uint32_t mask) -{ -#ifdef CONFIG_SOC_NRF54H20_GPD - const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - - nrf_gpio_port_retain_enable(cfg->port, mask); -#else - ARG_UNUSED(port); - ARG_UNUSED(mask); -#endif -} - -static void gpio_nrfx_gpd_retain_clear(const struct device *port, uint32_t mask) -{ -#ifdef CONFIG_SOC_NRF54H20_GPD - const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - - nrf_gpio_port_retain_disable(cfg->port, mask); -#else - ARG_UNUSED(port); - ARG_UNUSED(mask); -#endif -} - static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { @@ -122,6 +100,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); nrf_gpio_pin_pull_t pull = get_pull(flags); nrf_gpio_pin_drive_t drive; + int pm_ret; switch (flags & (NRF_GPIO_DRIVE_MSK | GPIO_OPEN_DRAIN)) { case NRF_GPIO_DRIVE_S0S1: @@ -157,8 +136,6 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, return ret; } - gpio_nrfx_gpd_retain_clear(port, BIT(pin)); - if (flags & GPIO_OUTPUT_INIT_HIGH) { nrf_gpio_port_out_set(cfg->port, BIT(pin)); } else if (flags & GPIO_OUTPUT_INIT_LOW) { @@ -246,8 +223,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, } end: - gpio_nrfx_gpd_retain_set(port, BIT(pin)); - int pm_ret = pm_device_runtime_put(port); + pm_ret = pm_device_runtime_put(port); return (ret != 0) ? ret : pm_ret; } @@ -349,10 +325,8 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port, return ret; } - gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_set(reg, set_mask); nrf_gpio_port_out_clear(reg, clear_mask); - gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } @@ -367,9 +341,7 @@ static int gpio_nrfx_port_set_bits_raw(const struct device *port, return ret; } - gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_set(reg, mask); - gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } @@ -384,9 +356,7 @@ static int gpio_nrfx_port_clear_bits_raw(const struct device *port, return ret; } - gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_clear(reg, mask); - gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } @@ -404,10 +374,8 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port, return ret; } - gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_set(reg, set_mask); nrf_gpio_port_out_clear(reg, clear_mask); - gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } @@ -614,14 +582,10 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin, static int gpio_nrfx_pm_suspend(const struct device *port) { -#ifdef CONFIG_SOC_NRF54H20_GPD +#if GPIO_HAS_PAD_GROUP const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - if (cfg->pad_pd != NRF_GPD_FAST_ACTIVE1) { - return 0; - } - - return nrf_gpd_release(NRF_GPD_FAST_ACTIVE1); + return pm_device_runtime_put(cfg->pad_group); #else ARG_UNUSED(port); return 0; @@ -630,14 +594,10 @@ static int gpio_nrfx_pm_suspend(const struct device *port) static int gpio_nrfx_pm_resume(const struct device *port) { -#ifdef CONFIG_SOC_NRF54H20_GPD +#if GPIO_HAS_PAD_GROUP const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - if (cfg->pad_pd != NRF_GPD_FAST_ACTIVE1) { - return 0; - } - - return nrf_gpd_request(NRF_GPD_FAST_ACTIVE1); + return pm_device_runtime_get(cfg->pad_group); #else ARG_UNUSED(port); return 0; @@ -727,12 +687,11 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = { "Please enable GPIOTE instance for used GPIO port!")), \ ()) -#ifdef CONFIG_SOC_NRF54H20_GPD -#define PAD_PD(inst) \ - .pad_pd = DT_INST_PHA_BY_NAME_OR(inst, power_domains, pad, id, \ - NRF_GPD_SLOW_MAIN), +#if GPIO_HAS_PAD_GROUP +#define GPIO_NRF_PAD_GROUP_INIT(id) \ + .pad_group = DEVICE_DT_GET(DT_INST_CHILD(id, pad_group)), #else -#define PAD_PD(inst) +#define GPIO_NRF_PAD_GROUP_INIT(id) #endif #define GPIO_NRF_DEVICE(id) \ @@ -753,7 +712,7 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = { (DT_PROP_OR(GPIOTE_PHANDLE(id), fixed_channels_supported, 0) ? \ GPIOTE_FLAG_FIXED_CHAN : 0),) \ ) \ - PAD_PD(id) \ + GPIO_NRF_PAD_GROUP_INIT(id) \ }; \ \ static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \ diff --git a/drivers/pinctrl/pinctrl_nrf.c b/drivers/pinctrl/pinctrl_nrf.c index 34c0107b591..a1585729d53 100644 --- a/drivers/pinctrl/pinctrl_nrf.c +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -5,11 +5,10 @@ */ #include +#include +#include #include -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif BUILD_ASSERT(((NRF_PULL_NONE == NRF_GPIO_PIN_NOPULL) && (NRF_PULL_DOWN == NRF_GPIO_PIN_PULLDOWN) && @@ -124,13 +123,99 @@ static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = { #endif #endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_hpf_mspi_controller) || ... */ -int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, - uintptr_t reg) +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_gpio_pad_group) +#define GPIO_HAS_PAD_GROUP 1 +#else +#define GPIO_HAS_PAD_GROUP 0 +#endif + +#if GPIO_HAS_PAD_GROUP + +#define GPIO_PAD_GROUP_GET_OR_NULL(idx, _) \ + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(_CONCAT(gpio_pad_group, idx))) + +static const struct device *const pad_groups[] = { + LISTIFY(10, GPIO_PAD_GROUP_GET_OR_NULL, (,)) +}; + +static atomic_t pad_group_masks[ARRAY_SIZE(pad_groups)]; + +static int pad_group_request_pin(uint16_t pin_number) +{ + uint8_t port_number = NRF_GET_PORT(pin_number); + uint8_t port_pin_number = NRF_GET_PORT_PIN(pin_number); + const struct device *pad_group = pad_groups[port_number]; + atomic_t *pad_group_mask = &pad_group_masks[port_number]; + + if (atomic_test_and_set_bit(pad_group_mask, port_pin_number)) { + /* already requested */ + return 0; + } + + if (pm_device_runtime_get(pad_group)) { + atomic_clear_bit(pad_group_mask, port_pin_number); + return -EIO; + } + + return 0; +} + +static int pad_group_release_pin(uint16_t pin_number) +{ + uint8_t port_number = NRF_GET_PORT(pin_number); + uint8_t port_pin_number = NRF_GET_PORT_PIN(pin_number); + const struct device *pad_group = pad_groups[port_number]; + atomic_t *pad_group_mask = &pad_group_masks[port_number]; + + if (!atomic_test_and_clear_bit(pad_group_mask, port_pin_number)) { + /* already released */ + return 0; + } + + if (pm_device_runtime_put(pad_group)) { + atomic_set_bit(pad_group_mask, port_pin_number); + return -EIO; + } + + return 0; +} + +#else + +static int pad_group_request_pin(uint16_t pin_number) +{ + ARG_UNUSED(pin_number); + return 0; +} + +static int pad_group_release_pin(uint16_t pin_number) { -#ifdef CONFIG_SOC_NRF54H20_GPD - bool gpd_requested = false; + ARG_UNUSED(pin_number); + return 0; +} + #endif +#if NRF_GPIO_HAS_CLOCKPIN + +static void port_pin_clock_set(uint16_t pin_number, bool enable) +{ + nrf_gpio_pin_clock_set(pin_number, enable); +} + +#else + +static void port_pin_clock_set(uint16_t pin_number, bool enable) +{ + ARG_UNUSED(pin_number); + ARG_UNUSED(enable); +} + +#endif + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, + uintptr_t reg) +{ for (uint8_t i = 0U; i < pin_cnt; i++) { nrf_gpio_pin_drive_t drive; uint8_t drive_idx = NRF_GET_DRIVE(pins[i]); @@ -505,25 +590,8 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, if (psel != PSEL_DISCONNECTED) { uint32_t pin = psel; -#ifdef CONFIG_SOC_NRF54H20_GPD - if (NRF_GET_GPD_FAST_ACTIVE1(pins[i]) == 1U) { - if (!gpd_requested) { - int ret; - - ret = nrf_gpd_request(NRF_GPD_SLOW_ACTIVE); - if (ret < 0) { - return ret; - } - gpd_requested = true; - } - } - - /* - * Pad power domain now on, retain no longer needed - * as pad config will be persists as pad is powered. - */ - nrf_gpio_pin_retain_disable(pin); -#endif /* CONFIG_SOC_NRF54H20_GPD */ + /* enable pin */ + pad_group_request_pin(pin); if (write != NO_WRITE) { nrf_gpio_pin_write(pin, write); @@ -535,35 +603,20 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, input = NRF_GPIO_PIN_INPUT_DISCONNECT; } + /* configure pin */ nrf_gpio_cfg(pin, dir, input, NRF_GET_PULL(pins[i]), drive, NRF_GPIO_PIN_NOSENSE); -#if NRF_GPIO_HAS_CLOCKPIN - nrf_gpio_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i])); -#endif -#ifdef CONFIG_SOC_NRF54H20_GPD + if (NRF_GET_LP(pins[i]) == NRF_LP_ENABLE) { - /* - * Pad power domain may be turned off, and pad is not - * actively used as pincnf is low-power. Enable retain - * to ensure pad output and config persists if pad - * power domain is suspended. - */ - nrf_gpio_pin_retain_enable(pin); + /* disable pin and pin clock */ + pad_group_release_pin(pin); + port_pin_clock_set(pin, false); + } else { + /* configure pin clock */ + port_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i])); } -#endif /* CONFIG_SOC_NRF54H20_GPD */ } } -#ifdef CONFIG_SOC_NRF54H20_GPD - if (gpd_requested) { - int ret; - - ret = nrf_gpd_release(NRF_GPD_SLOW_ACTIVE); - if (ret < 0) { - return ret; - } - } -#endif - return 0; } diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index e5a046fd975..8565fd1187a 100644 --- a/drivers/pwm/pwm_nrfx.c +++ b/drivers/pwm/pwm_nrfx.c @@ -14,9 +14,6 @@ #include #include #include -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif #include @@ -39,14 +36,9 @@ LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL); #define PWM(dev_idx) DT_NODELABEL(pwm##dev_idx) #define PWM_PROP(dev_idx, prop) DT_PROP(PWM(dev_idx), prop) #define PWM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(PWM(idx), prop) +#define PWM_NRFX_IS_FAST(idx) NRF_DT_IS_FAST(PWM(idx)) -#define PWM_NRFX_IS_FAST(unused, prefix, idx, _) \ - COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(PWM(idx)), \ - (COND_CODE_1(PWM_HAS_PROP(idx, power_domains), \ - (IS_EQ(DT_PHA(PWM(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \ - (0))), (0)) - -#if NRFX_FOREACH_PRESENT(PWM, PWM_NRFX_IS_FAST, (||), (0)) +#if NRF_DT_INST_ANY_IS_FAST #define PWM_NRFX_FAST_PRESENT 1 /* If fast instances are used then system managed device PM cannot be used because * it may call PM actions from locked context and fast PWM PM actions can only be @@ -383,10 +375,6 @@ static int pwm_resume(const struct device *dev) (void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); -#ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(config->pcfg, false); -#endif - for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) { uint32_t psel; @@ -423,10 +411,6 @@ static int pwm_suspend(const struct device *dev) while (!nrfx_pwm_stopped_check(&config->pwm)) { } -#ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(config->pcfg, true); -#endif - memset(dev->data, 0, sizeof(struct pwm_nrfx_data)); (void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); @@ -487,7 +471,7 @@ static int pwm_nrfx_init(const struct device *dev) #if defined(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY) && \ CONFIG_PWM_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY #define PWM_INIT_PRIORITY(idx) \ - COND_CODE_1(PWM_NRFX_IS_FAST(_, /*empty*/, idx, _), \ + COND_CODE_1(PWM_NRFX_IS_FAST(idx), \ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ (CONFIG_PWM_INIT_PRIORITY)) #else @@ -523,7 +507,7 @@ static int pwm_nrfx_init(const struct device *dev) IF_ENABLED(CONFIG_DCACHE, \ (.mem_attr = PWM_GET_MEM_ATTR(idx),)) \ IF_ENABLED(PWM_NRFX_USE_CLOCK_CONTROL, \ - (.clk_dev = PWM_NRFX_IS_FAST(_, /*empty*/, idx, _) \ + (.clk_dev = PWM_NRFX_IS_FAST(idx) \ ? DEVICE_DT_GET(DT_CLOCKS_CTLR(PWM(idx))) \ : NULL, \ .clk_spec = { \ diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 149a48d88b2..db322ec8ba5 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -118,23 +118,23 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL); #define UARTE_ANY_LOW_POWER 1 #endif -#ifdef CONFIG_SOC_NRF54H20_GPD -#include - -/* Macro must resolve to literal 0 or 1 */ -#define INSTANCE_IS_FAST_PD(unused, prefix, idx, _) \ - COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \ - (COND_CODE_1(DT_NODE_HAS_PROP(UARTE(idx), power_domains), \ - (IS_EQ(DT_PHA(UARTE(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \ - (0))), (0)) - -#if UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_FAST_PD, (||), (0)) -/* Instance in fast power domain (PD) requires special PM treatment and clock control, so - * device runtime PM and clock control must be enabled. +/* Only cores with access to GDFS can control clocks and power domains, so if a fast instance is + * used by other cores, treat the UART like a normal one. This presumes cores with access to GDFS + * have requested the clocks and power domains needed by the fast instance to be ACTIVE before + * other cores use the fast instance. */ -BUILD_ASSERT(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)); -BUILD_ASSERT(IS_ENABLED(CONFIG_CLOCK_CONTROL)); -#define UARTE_ANY_FAST_PD 1 +#if CONFIG_NRFS_GDFS_SERVICE_ENABLED +#define INSTANCE_IS_FAST(unused, prefix, idx, _) \ + UTIL_AND( \ + UTIL_AND( \ + IS_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##idx), \ + NRF_DT_IS_FAST(UARTE(idx)) \ + ), \ + IS_ENABLED(CONFIG_CLOCK_CONTROL) \ + ) + +#if UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_FAST, (||), (0)) +#define UARTE_ANY_FAST 1 #endif #endif @@ -407,7 +407,7 @@ struct uarte_nrfx_data { * @retval false if device PM is not ISR safe. */ #define IS_PM_ISR_SAFE(dev) \ - (!IS_ENABLED(UARTE_ANY_FAST_PD) ||\ + (!IS_ENABLED(UARTE_ANY_FAST) ||\ COND_CODE_1(CONFIG_PM_DEVICE,\ ((dev->pm_base->flags & BIT(PM_DEVICE_FLAG_ISR_SAFE))), \ (0))) @@ -423,7 +423,7 @@ struct uarte_nrfx_config { #ifdef CONFIG_HAS_NORDIC_DMM void *mem_reg; #endif -#ifdef UARTE_ANY_FAST_PD +#ifdef UARTE_ANY_FAST const struct device *clk_dev; struct nrf_clock_spec clk_spec; #endif @@ -512,6 +512,7 @@ static void endtx_isr(const struct device *dev) static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask) { struct uarte_nrfx_data *data = dev->data; + const struct uarte_nrfx_config *config = dev->config; data->flags &= ~dis_mask; if (data->flags & UARTE_FLAG_LOW_POWER) { @@ -519,8 +520,6 @@ static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask) } #if defined(UARTE_ANY_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX) - const struct uarte_nrfx_config *config = dev->config; - if (data->async && HW_RX_COUNTING_ENABLED(config)) { nrfx_timer_disable(&config->timer); /* Timer/counter value is reset when disabled. */ @@ -529,12 +528,8 @@ static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask) } #endif -#ifdef CONFIG_SOC_NRF54H20_GPD - const struct uarte_nrfx_config *cfg = dev->config; - - nrf_gpd_retain_pins_set(cfg->pcfg, true); -#endif nrf_uarte_disable(get_uarte_instance(dev)); + (void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); } #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED @@ -845,7 +840,7 @@ static void uarte_periph_enable(const struct device *dev) struct uarte_nrfx_data *data = dev->data; (void)data; -#ifdef UARTE_ANY_FAST_PD +#ifdef UARTE_ANY_FAST if (config->clk_dev) { int err; @@ -855,10 +850,9 @@ static void uarte_periph_enable(const struct device *dev) } #endif + (void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); nrf_uarte_enable(uarte); -#ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(config->pcfg, false); -#endif + #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED if (config->cross_domain && uarte_has_cross_domain_connection(config)) { #if UARTE_CROSS_DOMAIN_PINS_HANDLE @@ -872,6 +866,7 @@ static void uarte_periph_enable(const struct device *dev) #endif } #endif + #if UARTE_BAUDRATE_RETENTION_WORKAROUND if (config->flags & UARTE_CFG_FLAG_VOLATILE_BAUDRATE) { nrf_uarte_baudrate_set(uarte, @@ -2090,7 +2085,7 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, nrf_uarte_rx_buffer_set(uarte, buf, len); - if (IS_ENABLED(UARTE_ANY_FAST_PD) && (cfg->flags & UARTE_CFG_FLAG_CACHEABLE)) { + if (IS_ENABLED(UARTE_ANY_FAST) && (cfg->flags & UARTE_CFG_FLAG_CACHEABLE)) { /* Spurious RXTO event was seen on fast instance (UARTE120) thus * RXTO interrupt is kept enabled only when RX is active. */ @@ -2585,7 +2580,7 @@ static void rxto_isr(const struct device *dev) #ifdef CONFIG_UART_NRFX_UARTE_ENHANCED_RX NRF_UARTE_Type *uarte = get_uarte_instance(dev); - if (IS_ENABLED(UARTE_ANY_FAST_PD) && (config->flags & UARTE_CFG_FLAG_CACHEABLE)) { + if (IS_ENABLED(UARTE_ANY_FAST) && (config->flags & UARTE_CFG_FLAG_CACHEABLE)) { /* Spurious RXTO event was seen on fast instance (UARTE120) thus * RXTO interrupt is kept enabled only when RX is active. */ @@ -3206,9 +3201,8 @@ static void uarte_pm_resume(const struct device *dev) { const struct uarte_nrfx_config *cfg = dev->config; - (void)pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); - if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || !LOW_POWER_ENABLED(cfg)) { + (void)pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); uarte_periph_enable(dev); } } @@ -3220,7 +3214,7 @@ static void uarte_pm_suspend(const struct device *dev) struct uarte_nrfx_data *data = dev->data; (void)data; -#ifdef UARTE_ANY_FAST_PD +#ifdef UARTE_ANY_FAST if (cfg->clk_dev) { int err; @@ -3282,9 +3276,6 @@ static void uarte_pm_suspend(const struct device *dev) wait_for_tx_stopped(dev); } -#ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(cfg->pcfg, true); -#endif #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED if (cfg->cross_domain && uarte_has_cross_domain_connection(cfg)) { #if UARTE_CROSS_DOMAIN_PINS_HANDLE @@ -3299,9 +3290,8 @@ static void uarte_pm_suspend(const struct device *dev) } #endif - nrf_uarte_disable(uarte); - (void)pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP); + nrf_uarte_disable(uarte); } static int uarte_nrfx_pm_action(const struct device *dev, enum pm_device_action action) @@ -3515,13 +3505,13 @@ static int uarte_instance_init(const struct device *dev, * which is using nrfs (IPC) are initialized later. */ #define UARTE_INIT_LEVEL(idx) \ - COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), (POST_KERNEL), (PRE_KERNEL_1)) + COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), (POST_KERNEL), (PRE_KERNEL_1)) /* Get initialization priority of an instance. Instances that requires clock control * which is using nrfs (IPC) are initialized later. */ #define UARTE_INIT_PRIO(idx) \ - COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), \ + COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ (CONFIG_SERIAL_INIT_PRIORITY)) @@ -3552,12 +3542,28 @@ static int uarte_instance_init(const struct device *dev, : UART_CFG_FLOW_CTRL_NONE, \ } -/* Macro determines if PM actions are interrupt safe. They are in case of - * asynchronous API (except for instance in fast power domain) and non-asynchronous - * API if RX is disabled. Macro must resolve to a literal 1 or 0. +#define UARTE_ON_MANAGED_POWER_DOMAIN(idx) \ + UTIL_AND( \ + IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN), \ + UTIL_AND( \ + DT_NODE_HAS_PROP(UARTE(idx), power_domains), \ + DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE(UARTE(idx), power_domains)) \ + ) \ + ) + +/* Macro determines if PM actions are interrupt safe. + * + * Requesting/releasing clocks or power domains is not necessarily ISR safe (we can't + * reliably know, its out of our control). UARTE_ON_MANAGED_POWER_DOMAIN() let's us check if we + * will be requesting/releasing power domains (and clocks for now since the only case where we + * need to request power domains happens to be the same criteria). + * + * Furthermore, non-asynchronous API if RX is disabled is not ISR safe. + * + * Macro must resolve to a literal 1 or 0. */ #define UARTE_PM_ISR_SAFE(idx) \ - COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), \ + COND_CODE_1(UARTE_ON_MANAGED_POWER_DOMAIN(idx), \ (0), \ (COND_CODE_1(CONFIG_UART_##idx##_ASYNC, \ (PM_DEVICE_ISR_SAFE), \ @@ -3633,8 +3639,8 @@ static int uarte_instance_init(const struct device *dev, IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \ (.timer = NRFX_TIMER_INSTANCE( \ CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \ - IF_ENABLED(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), \ - (.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(UARTE(idx))), \ + IF_ENABLED(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \ + (.clk_dev = DEVICE_DT_GET_OR_NULL(DT_CLOCKS_CTLR(UARTE(idx))), \ .clk_spec = { \ .frequency = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),\ .accuracy = 0, \ diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index ef832713936..89aabea349e 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -13,9 +13,6 @@ #include #include #include -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif #include #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 #include @@ -54,20 +51,33 @@ LOG_MODULE_REGISTER(spi_nrfx_spim, CONFIG_SPI_LOG_LEVEL); #define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop) #define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop) -#if defined(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL) -#define SPIM_REQUESTS_CLOCK(node) \ - DT_NODE_HAS_COMPAT(DT_CLOCKS_CTLR(node), nordic_nrf_hsfll_global) -#define SPIM_REQUESTS_CLOCK_OR(node) SPIM_REQUESTS_CLOCK(node) || -#if (DT_FOREACH_STATUS_OKAY(nordic_nrf_spim, SPIM_REQUESTS_CLOCK_OR) 0) -#define USE_CLOCK_REQUESTS 1 +/* Execute macro f(x) for all instances. */ +#define SPIM_FOR_EACH_INSTANCE(f, sep, off_code, ...) \ + NRFX_FOREACH_PRESENT(SPIM, f, sep, off_code, __VA_ARGS__) + +/* Only CPUAPP and CPURAD can control clocks and power domains, so if a fast instance is + * used by other cores, treat the SPIM like a normal one. This presumes the CPUAPP or CPURAD + * have requested the clocks and power domains needed by the fast instance to be ACTIVE before + * other cores use the fast instance. + */ +#if CONFIG_SOC_NRF54H20_CPUAPP || CONFIG_SOC_NRF54H20_CPURAD +#define INSTANCE_IS_FAST(unused, prefix, idx, _) \ + UTIL_AND( \ + UTIL_AND( \ + IS_ENABLED(CONFIG_HAS_HW_NRF_SPIM##prefix##idx), \ + NRF_DT_IS_FAST(SPIM(idx)) \ + ), \ + IS_ENABLED(CONFIG_CLOCK_CONTROL) \ + ) + +#if SPIM_FOR_EACH_INSTANCE(INSTANCE_IS_FAST, (||), (0)) +#define SPIM_ANY_FAST 1 /* If fast instances are used then system managed device PM cannot be used because * it may call PM actions from locked context and fast SPIM PM actions can only be * called from a thread context. */ BUILD_ASSERT(!IS_ENABLED(CONFIG_PM_DEVICE_SYSTEM_MANAGED)); #endif -#else -#define SPIM_REQUESTS_CLOCK(node) 0 #endif #define SPIM_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \ @@ -107,7 +117,7 @@ struct spi_nrfx_data { uint8_t ppi_ch; uint8_t gpiote_ch; #endif -#ifdef USE_CLOCK_REQUESTS +#ifdef SPIM_ANY_FAST bool clock_requested; #endif }; @@ -124,7 +134,7 @@ struct spi_nrfx_config { #endif uint32_t wake_pin; nrfx_gpiote_t wake_gpiote; -#ifdef USE_CLOCK_REQUESTS +#ifdef SPIM_ANY_FAST const struct device *clk_dev; struct nrf_clock_spec clk_spec; #endif @@ -139,7 +149,7 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context); static inline int request_clock(const struct device *dev) { -#ifdef USE_CLOCK_REQUESTS +#ifdef SPIM_ANY_FAST struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; int error; @@ -166,7 +176,7 @@ static inline int request_clock(const struct device *dev) static inline void release_clock(const struct device *dev) { -#ifdef USE_CLOCK_REQUESTS +#ifdef SPIM_ANY_FAST struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; @@ -762,9 +772,6 @@ static int spim_resume(const struct device *dev) return -EAGAIN; } -#ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(dev_config->pcfg, false); -#endif #if SPIM_CROSS_DOMAIN_SUPPORTED if (dev_config->cross_domain && spim_has_cross_domain_connection(dev_config)) { #if SPIM_CROSS_DOMAIN_PINS_HANDLE @@ -798,9 +805,6 @@ static void spim_suspend(const struct device *dev) spi_context_cs_put_all(&dev_data->ctx); -#ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(dev_config->pcfg, true); -#endif #if SPIM_CROSS_DOMAIN_SUPPORTED if (dev_config->cross_domain && spim_has_cross_domain_connection(dev_config)) { #if SPIM_CROSS_DOMAIN_PINS_HANDLE @@ -901,20 +905,13 @@ static int spi_nrfx_deinit(const struct device *dev) ()) \ )) -/* Fast instances depend on the global HSFLL clock controller (as they need - * to request the highest frequency from it to operate correctly), so they - * must be initialized after that controller driver, hence the default SPI - * initialization priority may be too early for them. +/* Get initialization priority of an instance. Instances that requires clock control + * which is using nrfs (IPC) are initialized later. */ -#if defined(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY) && \ - CONFIG_SPI_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY #define SPIM_INIT_PRIORITY(idx) \ - COND_CODE_1(SPIM_REQUESTS_CLOCK(SPIM(idx)), \ + COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ (CONFIG_SPI_INIT_PRIORITY)) -#else -#define SPIM_INIT_PRIORITY(idx) CONFIG_SPI_INIT_PRIORITY -#endif #define SPI_NRFX_SPIM_DEFINE(idx) \ NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ @@ -967,10 +964,9 @@ static int spi_nrfx_deinit(const struct device *dev) .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \ WAKE_PIN_NOT_USED), \ .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \ - IF_ENABLED(USE_CLOCK_REQUESTS, \ - (.clk_dev = SPIM_REQUESTS_CLOCK(SPIM(idx)) \ - ? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \ - : NULL, \ + IF_ENABLED(SPIM_ANY_FAST, \ + (.clk_dev = DEVICE_DT_GET_OR_NULL( \ + DT_CLOCKS_CTLR(SPIM(idx))), \ .clk_spec = { \ .frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \ },)) \ @@ -997,4 +993,4 @@ static int spi_nrfx_deinit(const struct device *dev) #define COND_NRF_SPIM_DEVICE(unused, prefix, i, _) \ IF_ENABLED(CONFIG_HAS_HW_NRF_SPIM##prefix##i, (SPI_NRFX_SPIM_DEFINE(prefix##i);)) -NRFX_FOREACH_PRESENT(SPIM, COND_NRF_SPIM_DEVICE, (), (), _) +SPIM_FOR_EACH_INSTANCE(COND_NRF_SPIM_DEVICE, (), (), _) diff --git a/drivers/spi/spi_nrfx_spis.c b/drivers/spi/spi_nrfx_spis.c index 71256b84fc3..cbd3abfdf31 100644 --- a/drivers/spi/spi_nrfx_spis.c +++ b/drivers/spi/spi_nrfx_spis.c @@ -20,15 +20,7 @@ LOG_MODULE_REGISTER(spi_nrfx_spis, CONFIG_SPI_LOG_LEVEL); #include "spi_context.h" -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif - -#define SPIS_IS_FAST(idx) IS_EQ(idx, 120) - -#define NRFX_SPIS_IS_FAST(unused, prefix, id, _) SPIS_IS_FAST(prefix##id) - -#if NRFX_FOREACH_ENABLED(SPIS, NRFX_SPIS_IS_FAST, (+), (0), _) +#if NRF_DT_INST_ANY_IS_FAST /* If fast instances are used then system managed device PM cannot be used because * it may call PM actions from locked context and fast SPIM PM actions can only be * called from a thread context. @@ -84,9 +76,6 @@ struct spi_nrfx_config { nrfx_spis_config_t config; void (*irq_connect)(void); uint16_t max_buf_len; -#ifdef CONFIG_SOC_NRF54H20_GPD - bool gpd_ctrl; -#endif const struct pinctrl_dev_config *pcfg; struct gpio_dt_spec wake_gpio; void *mem_reg; @@ -441,11 +430,6 @@ static void spi_nrfx_suspend(const struct device *dev) nrf_spis_disable(dev_config->spis.p_reg); } -#ifdef CONFIG_SOC_NRF54H20_GPD - if (dev_config->gpd_ctrl) { - nrf_gpd_retain_pins_set(dev_config->pcfg, true); - } -#endif #if SPIS_CROSS_DOMAIN_SUPPORTED if (dev_config->cross_domain && spis_has_cross_domain_connection(dev_config)) { #if SPIS_CROSS_DOMAIN_PINS_HANDLE @@ -469,11 +453,6 @@ static void spi_nrfx_resume(const struct device *dev) (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); -#ifdef CONFIG_SOC_NRF54H20_GPD - if (dev_config->gpd_ctrl) { - nrf_gpd_retain_pins_set(dev_config->pcfg, false); - } -#endif #if SPIS_CROSS_DOMAIN_SUPPORTED if (dev_config->cross_domain && spis_has_cross_domain_connection(dev_config)) { #if SPIS_CROSS_DOMAIN_PINS_HANDLE @@ -604,9 +583,6 @@ static int spi_nrfx_init(const struct device *dev) .irq_connect = irq_connect##idx, \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPIS(idx)), \ .max_buf_len = BIT_MASK(SPIS_PROP(idx, easydma_maxcnt_bits)), \ - IF_ENABLED(CONFIG_SOC_NRF54H20_GPD, \ - (.gpd_ctrl = NRF_PERIPH_GET_FREQUENCY(SPIS(idx)) > \ - NRFX_MHZ_TO_HZ(16UL),)) \ .wake_gpio = GPIO_DT_SPEC_GET_OR(SPIS(idx), wake_gpios, {0}), \ .mem_reg = DMM_DEV_TO_REG(SPIS(idx)), \ IF_ENABLED(SPIS_PINS_CROSS_DOMAIN(_, /*empty*/, idx, _), \ @@ -619,7 +595,8 @@ static int spi_nrfx_init(const struct device *dev) !(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ "WAKE line must be configured as active high"); \ PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, \ - COND_CODE_1(SPIS_IS_FAST(idx), (0), (PM_DEVICE_ISR_SAFE))); \ + COND_CODE_1(NRF_DT_IS_FAST(SPIS(idx)), (0), \ + (PM_DEVICE_ISR_SAFE))); \ SPI_DEVICE_DT_DEFINE(SPIS(idx), \ spi_nrfx_init, \ PM_DEVICE_DT_GET(SPIS(idx)), \ diff --git a/dts/arm/nordic/nrf54h20_cpuapp.dtsi b/dts/arm/nordic/nrf54h20_cpuapp.dtsi index c56df42ddd5..9e790656e50 100644 --- a/dts/arm/nordic/nrf54h20_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54h20_cpuapp.dtsi @@ -59,3 +59,63 @@ wdt011: &cpuapp_wdt011 {}; &grtc { interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>; }; + +&fll16m { + status = "okay"; +}; + +&hsfll120 { + status = "okay"; +}; + +&lfclk { + status = "okay"; +}; + +&gdpwr { + status = "okay"; +}; + +&gdpwr_fast_active_0 { + status = "okay"; +}; + +&gdpwr_fast_active_1 { + status = "okay"; +}; + +&gdpwr_fast_main { + status = "okay"; +}; + +&gdpwr_slow_active { + status = "okay"; +}; + +&gdpwr_slow_main { + status = "okay"; +}; + +&gpio_pad_group0 { + status = "okay"; +}; + +&gpio_pad_group1 { + status = "okay"; +}; + +&gpio_pad_group2 { + status = "okay"; +}; + +&gpio_pad_group6 { + status = "okay"; +}; + +&gpio_pad_group7 { + status = "okay"; +}; + +&gpio_pad_group9 { + status = "okay"; +}; diff --git a/dts/arm/nordic/nrf54h20_cpurad.dtsi b/dts/arm/nordic/nrf54h20_cpurad.dtsi index e8ff2dac3a4..e6cf92474f7 100644 --- a/dts/arm/nordic/nrf54h20_cpurad.dtsi +++ b/dts/arm/nordic/nrf54h20_cpurad.dtsi @@ -107,3 +107,63 @@ wdt011: &cpurad_wdt011 {}; &bt_hci_sdc { status = "okay"; }; + +&fll16m { + status = "okay"; +}; + +&hsfll120 { + status = "okay"; +}; + +&lfclk { + status = "okay"; +}; + +&gdpwr { + status = "okay"; +}; + +&gdpwr_fast_active_0 { + status = "okay"; +}; + +&gdpwr_fast_active_1 { + status = "okay"; +}; + +&gdpwr_fast_main { + status = "okay"; +}; + +&gdpwr_slow_active { + status = "okay"; +}; + +&gdpwr_slow_main { + status = "okay"; +}; + +&gpio_pad_group0 { + status = "okay"; +}; + +&gpio_pad_group1 { + status = "okay"; +}; + +&gpio_pad_group2 { + status = "okay"; +}; + +&gpio_pad_group6 { + status = "okay"; +}; + +&gpio_pad_group7 { + status = "okay"; +}; + +&gpio_pad_group9 { + status = "okay"; +}; diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 68884b8a567..c17aff0f593 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -14,7 +14,6 @@ #include #include #include -#include /delete-node/ &sw_pwm; @@ -170,16 +169,18 @@ fll16m: fll16m { compatible = "nordic,nrf-fll16m"; + clock-names = "hfxo", "lfxo"; #clock-cells = <0>; clock-frequency = ; open-loop-accuracy-ppm = <20000>; open-loop-startup-time-us = <200>; /* To be measured */ clocks = <&hfxo>, <&lfxo>; - clock-names = "hfxo", "lfxo"; + status = "disabled"; }; hsfll120: hsfll120 { compatible = "nordic,nrf-hsfll-global"; + status = "disabled"; clocks = <&fll16m>; #clock-cells = <0>; clock-frequency = <320000000>; @@ -191,6 +192,7 @@ lfclk: lfclk { compatible = "nordic,nrf-lfclk"; + status = "disabled"; #clock-cells = <0>; clock-frequency = <32768>; status = "okay"; @@ -209,9 +211,39 @@ }; }; - gpd: global-power-domain { - compatible = "nordic,nrf-gpd"; - #power-domain-cells = <1>; + gdpwr: gdpwr { + compatible = "nordic,nrfs-gdpwr"; + status = "disabled"; + + gdpwr_fast_active_0: fast-active-0 { + #power-domain-cells = <0>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; + + gdpwr_fast_active_1: fast-active-1 { + #power-domain-cells = <0>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; + + gdpwr_fast_main: fast-main { + #power-domain-cells = <0>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; + + gdpwr_slow_active: slow-active { + #power-domain-cells = <0>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; + + gdpwr_slow_main: slow-main { + #power-domain-cells = <0>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; soc { @@ -221,7 +253,7 @@ mram1x: mram@e000000 { compatible = "nordic,mram"; reg = <0xe000000 DT_SIZE_K(2048)>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; erase-block-size = <4096>; write-block-size = <16>; }; @@ -520,7 +552,7 @@ reg = <0x86000 0x1000>, <0x2f700000 0x40000>; reg-names = "wrapper", "core"; interrupts = <134 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; num-in-eps = <8>; num-out-eps = <10>; ghwcfg1 = <0xaa555000>; @@ -536,7 +568,7 @@ reg = <0x95000 0x500 0x95500 0xb00>; reg-names = "wrapper", "core"; interrupts = <149 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; clock-frequency = ; fifo-depth = <32>; status = "disabled"; @@ -545,21 +577,21 @@ cpusec_bellboard: mailbox@99000 { reg = <0x99000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; #mbox-cells = <1>; }; cpuapp_bellboard: mailbox@9a000 { reg = <0x9a000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; #mbox-cells = <1>; }; cpurad_bellboard: mailbox@9b000 { reg = <0x9b000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; #mbox-cells = <1>; }; @@ -600,7 +632,7 @@ compatible = "nordic,nrf-vpr-coprocessor"; reg = <0x8d4000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x8d4000 0x1000>; @@ -622,7 +654,7 @@ interrupts = <216 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&canpll>, <&hsfll120>; clock-names = "auxpll", "hsfll"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; status = "disabled"; }; @@ -631,7 +663,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x8e1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; }; timer120: timer@8e2000 { @@ -640,7 +672,7 @@ status = "disabled"; cc-num = <6>; interrupts = <226 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; max-bit-width = <32>; clocks = <&hsfll120>; prescaler = <0>; @@ -652,7 +684,7 @@ status = "disabled"; cc-num = <6>; interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; max-bit-width = <32>; clocks = <&hsfll120>; prescaler = <0>; @@ -664,7 +696,7 @@ status = "disabled"; interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; #pwm-cells = <3>; idleout-supported; }; @@ -673,7 +705,7 @@ compatible = "nordic,nrf-spis"; reg = <0x8e5000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; easydma-maxcnt-bits = <15>; interrupts = <229 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; @@ -687,7 +719,7 @@ compatible = "nordic,nrf-spim"; reg = <0x8e6000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; easydma-maxcnt-bits = <15>; interrupts = <230 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; @@ -705,7 +737,7 @@ status = "disabled"; interrupts = <230 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; endtx-stoptx-supported; frame-timeout-supported; }; @@ -717,7 +749,7 @@ easydma-maxcnt-bits = <15>; interrupts = <231 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -733,7 +765,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x908000 0x1000>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; cpuppr_vevif_tx: mailbox@0 { compatible = "nordic,nrf-vevif-task-tx"; @@ -749,7 +781,7 @@ compatible = "nordic,nrf-ipct-global"; reg = <0x921000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; channels = <8>; global-domain-id = <13>; }; @@ -758,7 +790,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x922000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; rtc130: rtc@928000 { @@ -768,7 +800,7 @@ cc-num = <4>; clock-frequency = <32768>; interrupts = <296 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; clocks = <&lfclk>; prescaler = <1>; }; @@ -780,7 +812,7 @@ cc-num = <4>; clock-frequency = <32768>; interrupts = <297 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; clocks = <&lfclk>; prescaler = <1>; }; @@ -791,7 +823,7 @@ status = "disabled"; interrupts = <299 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&lfclk>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; wdt132: watchdog@92c000 { @@ -800,7 +832,7 @@ status = "disabled"; interrupts = <300 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&lfclk>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; egu130: egu@92d000 { @@ -808,14 +840,14 @@ reg = <0x92d000 0x1000>; status = "disabled"; interrupts = <301 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; gpiote130: gpiote@934000 { compatible = "nordic,nrf-gpiote"; reg = <0x934000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; instance = <130>; }; @@ -825,10 +857,19 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <12>; port = <0>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group0: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio1: gpio@938200 { @@ -837,10 +878,19 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <12>; port = <1>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group1: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio2: gpio@938400 { @@ -849,10 +899,19 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <12>; port = <2>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group2: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio6: gpio@938c00 { @@ -861,11 +920,18 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>, - <&gpd NRF_GPD_FAST_ACTIVE1>; - power-domain-names = "peripheral", "pad"; + power-domains = <&gdpwr_slow_main>; ngpios = <14>; port = <6>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group6: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_fast_active_1>; + retain-mask = <0x3FFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio7: gpio@938e00 { @@ -874,11 +940,18 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>, - <&gpd NRF_GPD_FAST_ACTIVE1>; - power-domain-names = "peripheral", "pad"; + power-domains = <&gdpwr_slow_main>; ngpios = <8>; port = <7>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group7: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_fast_active_1>; + retain-mask = <0xFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio9: gpio@939200 { @@ -887,17 +960,26 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <6>; port = <9>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group9: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0x3F>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; dppic131: dppic@981000 { compatible = "nordic,nrf-dppic-global"; reg = <0x981000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; adc: adc@982000 { @@ -906,7 +988,7 @@ interrupts = <386 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; zephyr,pm-device-runtime-auto; }; @@ -919,7 +1001,7 @@ reg = <0x983000 0x1000>; status = "disabled"; interrupts = <387 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; temp: temperature-sensor@984000 { @@ -927,7 +1009,7 @@ reg = <0x984000 0x1000>; interrupts = <388 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; nfct: nfct@985000 { @@ -935,14 +1017,14 @@ reg = <0x985000 0x1000>; status = "disabled"; interrupts = <389 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; dppic132: dppic@991000 { compatible = "nordic,nrf-dppic-global"; reg = <0x991000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; pdm0: pdm@993000 { @@ -951,7 +1033,7 @@ status = "disabled"; interrupts = <403 NRF_DEFAULT_IRQ_PRIORITY>; nordic,clockpin-enable = ; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; qdec130: qdec@994000 { @@ -959,7 +1041,7 @@ reg = <0x994000 0x1000>; status = "disabled"; interrupts = <404 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; qdec131: qdec@995000 { @@ -967,7 +1049,7 @@ reg = <0x995000 0x1000>; status = "disabled"; interrupts = <405 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; grtc: grtc@99c000 { @@ -977,14 +1059,14 @@ cc-num = <16>; clocks = <&lfclk>, <&fll16m>; clock-names = "lfclock", "hfclock"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; dppic133: dppic@9a1000 { compatible = "nordic,nrf-dppic-global"; reg = <0x9a1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer130: timer@9a2000 { @@ -994,7 +1076,7 @@ cc-num = <6>; interrupts = <418 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1006,7 +1088,7 @@ cc-num = <6>; interrupts = <419 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1017,7 +1099,7 @@ status = "disabled"; interrupts = <420 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; #pwm-cells = <3>; idleout-supported; }; @@ -1028,7 +1110,7 @@ status = "disabled"; interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1044,7 +1126,7 @@ easydma-maxcnt-bits = <15>; interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1062,7 +1144,7 @@ status = "disabled"; interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1074,7 +1156,7 @@ status = "disabled"; interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1090,7 +1172,7 @@ easydma-maxcnt-bits = <15>; interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1108,17 +1190,18 @@ status = "disabled"; interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; + zephyr,pm-device-runtime-auto; }; dppic134: dppic@9b1000 { compatible = "nordic,nrf-dppic-global"; reg = <0x9b1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer132: timer@9b2000 { @@ -1128,7 +1211,7 @@ cc-num = <6>; interrupts = <434 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1140,7 +1223,7 @@ cc-num = <6>; interrupts = <435 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1151,7 +1234,7 @@ status = "disabled"; interrupts = <436 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; #pwm-cells = <3>; idleout-supported; }; @@ -1162,7 +1245,7 @@ status = "disabled"; interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1178,7 +1261,7 @@ easydma-maxcnt-bits = <15>; interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1196,7 +1279,7 @@ status = "disabled"; interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1208,7 +1291,7 @@ status = "disabled"; interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1224,7 +1307,7 @@ easydma-maxcnt-bits = <15>; interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1242,7 +1325,7 @@ status = "disabled"; interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1252,7 +1335,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x9c1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer134: timer@9c2000 { @@ -1262,7 +1345,7 @@ cc-num = <6>; interrupts = <450 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1274,7 +1357,7 @@ cc-num = <6>; interrupts = <451 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1286,7 +1369,7 @@ interrupts = <452 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; #pwm-cells = <3>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; idleout-supported; }; @@ -1296,7 +1379,7 @@ status = "disabled"; interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1312,7 +1395,7 @@ easydma-maxcnt-bits = <15>; interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1330,7 +1413,7 @@ status = "disabled"; interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1342,7 +1425,7 @@ status = "disabled"; interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1358,7 +1441,7 @@ easydma-maxcnt-bits = <15>; interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1376,7 +1459,7 @@ status = "disabled"; interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1386,7 +1469,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x9d1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer136: timer@9d2000 { @@ -1396,7 +1479,7 @@ cc-num = <6>; interrupts = <466 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1408,7 +1491,7 @@ cc-num = <6>; interrupts = <467 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1420,7 +1503,7 @@ interrupts = <468 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; #pwm-cells = <3>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; idleout-supported; }; @@ -1430,7 +1513,7 @@ status = "disabled"; interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1446,7 +1529,7 @@ easydma-maxcnt-bits = <15>; interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1464,10 +1547,11 @@ status = "disabled"; interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; + zephyr,pm-device-runtime-auto; }; i2c137: i2c@9d6000 { @@ -1476,7 +1560,7 @@ status = "disabled"; interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1492,7 +1576,7 @@ easydma-maxcnt-bits = <15>; interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1510,7 +1594,7 @@ status = "disabled"; interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1525,7 +1609,7 @@ interrupts = <402 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = , ; }; @@ -1539,7 +1623,7 @@ interrupts = <407 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = , ; }; diff --git a/soc/nordic/common/pinctrl_soc.h b/soc/nordic/common/pinctrl_soc.h index f1d3b6357f9..b9b93e5bc94 100644 --- a/soc/nordic/common/pinctrl_soc.h +++ b/soc/nordic/common/pinctrl_soc.h @@ -81,9 +81,7 @@ typedef uint32_t pinctrl_soc_pin_t; (DT_PROP(node_id, nordic_drive_mode) << NRF_DRIVE_POS) | \ ((NRF_LP_ENABLE * DT_PROP(node_id, low_power_enable)) << NRF_LP_POS) |\ (DT_PROP(node_id, nordic_invert) << NRF_INVERT_POS) | \ - Z_GET_CLOCKPIN_ENABLE(node_id, prop, idx, p_node_id) | \ - Z_GET_GPD_FAST_ACTIVE1(p_node_id) \ - ), + Z_GET_CLOCKPIN_ENABLE(node_id, prop, idx, p_node_id)), /** * @brief Utility macro to initialize state pins contained in a given property. @@ -154,6 +152,20 @@ typedef uint32_t pinctrl_soc_pin_t; */ #define NRF_GET_PIN(pincfg) (((pincfg) >> NRF_PIN_POS) & NRF_PIN_MSK) +/** + * @brief Utility macro to obtain port. + * + * @param pincfg Pin configuration bit field. + */ +#define NRF_GET_PORT(pincfg) (NRF_GET_PIN(pincfg) >> 5) + +/** + * @brief Utility macro to obtain pin relative to port. + * + * @param pincfg Pin configuration bit field. + */ +#define NRF_GET_PORT_PIN(pincfg) (NRF_GET_PIN(pincfg) & 0x1F) + /** @endcond */ #ifdef __cplusplus diff --git a/soc/nordic/common/soc_nrf_common.h b/soc/nordic/common/soc_nrf_common.h index e2ff929a503..12ac373fd6e 100644 --- a/soc/nordic/common/soc_nrf_common.h +++ b/soc/nordic/common/soc_nrf_common.h @@ -268,6 +268,52 @@ (DT_PROP_LAST(DT_CLOCKS_CTLR(node), supported_clock_frequency)))), \ (NRFX_MHZ_TO_HZ(16))) +/** + * @brief Utility macro to check if instance is fast by node, expands to 1 or 0. + * + * @param node_id Node identifier. + */ +#define NRF_DT_IS_FAST(node_id) \ + COND_CODE_1( \ + UTIL_AND( \ + DT_NODE_EXISTS(DT_PHANDLE(node_id, power_domains)), \ + DT_NODE_EXISTS(DT_NODELABEL(gdpwr_fast_active_1)) \ + ), \ + ( \ + DT_SAME_NODE( \ + DT_PHANDLE(node_id, power_domains), \ + DT_NODELABEL(gdpwr_fast_active_1) \ + ) \ + ), \ + (0) \ + ) + +/** + * @brief Utility macro to check if instance is fast by DT_DRV_INST, expands to 1 or 0. + * + * @param inst Driver instance + */ +#define NRF_DT_INST_IS_FAST(inst) \ + NRF_DT_IS_FAST(DT_DRV_INST(inst)) + +/** + * @brief Utility macro to check if instance is fast by DT_DRV_INST, expands to 1 or empty. + * + * @param inst Driver instance + */ +#define NRF_DT_INST_IS_FAST_OR_EMPTY(inst) \ + IF_ENABLED(NRF_DT_INST_IS_FAST(inst), 1) + +/** + * @brief Utility macro to check if any instance with compat is fast. Expands to 1 or 0. + */ +#define NRF_DT_INST_ANY_IS_FAST \ + COND_CODE_0( \ + IS_EMPTY(DT_INST_FOREACH_STATUS_OKAY(NRF_DT_INST_IS_FAST_OR_EMPTY)), \ + (1), \ + (0) \ + ) + #endif /* !_ASMLANGUAGE */ #endif diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 56b64f293ba..6663fcbb865 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -106,4 +106,3 @@ config SOC_NRF54H20_CPUFLPR select RISCV_CORE_NORDIC_VPR rsource "bicr/Kconfig" -rsource "gpd/Kconfig" diff --git a/soc/nordic/nrf54h/Kconfig.defconfig b/soc/nordic/nrf54h/Kconfig.defconfig index 486343a78ab..b11dcd9916c 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig +++ b/soc/nordic/nrf54h/Kconfig.defconfig @@ -35,11 +35,18 @@ config SPI_DW_HSSI config SPI_DW_ACCESS_WORD_ONLY default y if SPI_DW -config PM_DEVICE_POWER_DOMAIN - default n if PM_DEVICE +if PM_DEVICE config PM_DEVICE_RUNTIME - default y if PM_DEVICE + default y + +config DEVICE_DEPS + default y + +config PM_DEVICE_POWER_DOMAIN + default y + +endif # PM_DEVICE config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,grtc,clock-frequency) if NRF_GRTC_TIMER diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp index 69bde826ba4..0cdc2276040 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -11,4 +11,7 @@ config NUM_IRQS config SHELL_BACKEND_SERIAL default n if NRF_ETR_SHELL +config POWER_DOMAIN + default y + endif # SOC_NRF54H20_CPUAPP diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad index 8f86835b92c..b3f5216c8f9 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -11,4 +11,7 @@ config NUM_IRQS config PM default y +config POWER_DOMAIN + default y + endif # SOC_NRF54H20_CPURAD diff --git a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf index 025c842f70b..a18a3b576e3 100644 --- a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf @@ -1,2 +1 @@ -CONFIG_SOC_NRF54H20_GPD=n CONFIG_SSF_CLIENT_SYS_INIT=n diff --git a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf index 025c842f70b..a18a3b576e3 100644 --- a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf @@ -1,2 +1 @@ -CONFIG_SOC_NRF54H20_GPD=n CONFIG_SSF_CLIENT_SYS_INIT=n diff --git a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n From 422f777d7731050b2635e4bcd249f0952ff4cb64 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 3 Jul 2025 02:29:16 +0200 Subject: [PATCH 5/9] [nrf fromtree] soc: nrf54h: remove deprecated gpd (global power domain) driver Remove the deprecated GPD (Global Power Domain) driver. Signed-off-by: Bjarki Arge Andreasen (cherry picked from commit 2854115443626c1a14d5bce334939c64f4763617) --- drivers/spi/spi_nrfx_spis.c | 6 +- dts/bindings/power/nordic,nrf-gpd.yaml | 11 - dts/vendor/nordic/nrf54h20.dtsi | 4 +- .../zephyr/dt-bindings/power/nordic-nrf-gpd.h | 17 - soc/nordic/common/pinctrl_soc.h | 19 - soc/nordic/nrf54h/CMakeLists.txt | 1 - soc/nordic/nrf54h/gpd/CMakeLists.txt | 5 - soc/nordic/nrf54h/gpd/Kconfig | 12 - soc/nordic/nrf54h/gpd/gpd.c | 388 ------------------ soc/nordic/nrf54h/gpd/include/nrf/gpd.h | 45 -- 10 files changed, 6 insertions(+), 502 deletions(-) delete mode 100644 dts/bindings/power/nordic,nrf-gpd.yaml delete mode 100644 include/zephyr/dt-bindings/power/nordic-nrf-gpd.h delete mode 100644 soc/nordic/nrf54h/gpd/CMakeLists.txt delete mode 100644 soc/nordic/nrf54h/gpd/Kconfig delete mode 100644 soc/nordic/nrf54h/gpd/gpd.c delete mode 100644 soc/nordic/nrf54h/gpd/include/nrf/gpd.h diff --git a/drivers/spi/spi_nrfx_spis.c b/drivers/spi/spi_nrfx_spis.c index cbd3abfdf31..64c9a6f14c4 100644 --- a/drivers/spi/spi_nrfx_spis.c +++ b/drivers/spi/spi_nrfx_spis.c @@ -34,10 +34,12 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_PM_DEVICE_SYSTEM_MANAGED)); * - HAL design (requirement of drv_inst_idx in nrfx_spis_t) * - Name-based HAL IRQ handlers, e.g. nrfx_spis_0_irq_handler */ -#define SPIS_NODE(idx) COND_CODE_1(SPIS_IS_FAST(idx), (spis##idx), (spi##idx)) +#define SPIS_NODE(idx) \ + COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(spis##idx)), (spis##idx), (spi##idx)) #define SPIS(idx) DT_NODELABEL(SPIS_NODE(idx)) #define SPIS_PROP(idx, prop) DT_PROP(SPIS(idx), prop) #define SPIS_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIS(idx), prop) +#define SPIS_IS_FAST(idx) NRF_DT_IS_FAST(SPIS(idx)) #define SPIS_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \ COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(SPIS(prefix##idx)), \ @@ -595,7 +597,7 @@ static int spi_nrfx_init(const struct device *dev) !(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ "WAKE line must be configured as active high"); \ PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, \ - COND_CODE_1(NRF_DT_IS_FAST(SPIS(idx)), (0), \ + COND_CODE_1(SPIS_IS_FAST(idx), (0), \ (PM_DEVICE_ISR_SAFE))); \ SPI_DEVICE_DT_DEFINE(SPIS(idx), \ spi_nrfx_init, \ diff --git a/dts/bindings/power/nordic,nrf-gpd.yaml b/dts/bindings/power/nordic,nrf-gpd.yaml deleted file mode 100644 index feb5f2862e9..00000000000 --- a/dts/bindings/power/nordic,nrf-gpd.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2024 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: Nordic nRF Global Power Domain - -compatible: "nordic,nrf-gpd" - -include: base.yaml - -power-domain-cells: - - id diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index c17aff0f593..40824c4e690 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -169,13 +169,13 @@ fll16m: fll16m { compatible = "nordic,nrf-fll16m"; - clock-names = "hfxo", "lfxo"; + status = "disabled"; #clock-cells = <0>; clock-frequency = ; open-loop-accuracy-ppm = <20000>; open-loop-startup-time-us = <200>; /* To be measured */ clocks = <&hfxo>, <&lfxo>; - status = "disabled"; + clock-names = "hfxo", "lfxo"; }; hsfll120: hsfll120 { diff --git a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h b/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h deleted file mode 100644 index e4a5b83a304..00000000000 --- a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - - -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD -#define ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD - -/* numbers aligned to nrfs service identifiers */ -#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/common/pinctrl_soc.h b/soc/nordic/common/pinctrl_soc.h index b9b93e5bc94..6bf39d487fa 100644 --- a/soc/nordic/common/pinctrl_soc.h +++ b/soc/nordic/common/pinctrl_soc.h @@ -14,7 +14,6 @@ #include #include -#include #include #ifdef __cplusplus @@ -56,16 +55,6 @@ typedef uint32_t pinctrl_soc_pin_t; (), NRF_GET_FUN(DT_PROP_BY_IDX(node_id, prop, idx))) \ 0)), (0)) -/** - * @brief Utility macro to get the GPD_FAST_ACTIVE1 flag - * - * @param p_node_id Parent node identifier. - */ -#define Z_GET_GPD_FAST_ACTIVE1(p_node_id) \ - COND_CODE_1(DT_NODE_HAS_PROP(p_node_id, power_domains), \ - ((DT_PHA(p_node_id, power_domains, id) == \ - NRF_GPD_FAST_ACTIVE1) << NRF_GPD_FAST_ACTIVE1_POS), (0)) - /** * @brief Utility macro to initialize each pin. * @@ -109,14 +98,6 @@ typedef uint32_t pinctrl_soc_pin_t; #define NRF_GET_CLOCKPIN_ENABLE(pincfg) \ (((pincfg) >> NRF_CLOCKPIN_ENABLE_POS) & NRF_CLOCKPIN_ENABLE_MSK) -/** - * @brief Utility macro to obtain GPD_FAST_ACTIVE1 flag - * - * @param pincfg Pin configuration bit field. - */ -#define NRF_GET_GPD_FAST_ACTIVE1(pincfg) \ - (((pincfg) >> NRF_GPD_FAST_ACTIVE1_POS) & NRF_GPD_FAST_ACTIVE1_MSK) - /** * @brief Utility macro to obtain pin inversion flag. * diff --git a/soc/nordic/nrf54h/CMakeLists.txt b/soc/nordic/nrf54h/CMakeLists.txt index 23c1cab1e77..94e38e62f2b 100644 --- a/soc/nordic/nrf54h/CMakeLists.txt +++ b/soc/nordic/nrf54h/CMakeLists.txt @@ -17,4 +17,3 @@ zephyr_include_directories(.) zephyr_linker_sources(SECTIONS SORT_KEY zzz_place_align_at_end align.ld) add_subdirectory(bicr) -add_subdirectory(gpd) diff --git a/soc/nordic/nrf54h/gpd/CMakeLists.txt b/soc/nordic/nrf54h/gpd/CMakeLists.txt deleted file mode 100644 index 7d029d2c8fc..00000000000 --- a/soc/nordic/nrf54h/gpd/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library_sources_ifdef(CONFIG_SOC_NRF54H20_GPD gpd.c) -zephyr_include_directories(include) diff --git a/soc/nordic/nrf54h/gpd/Kconfig b/soc/nordic/nrf54h/gpd/Kconfig deleted file mode 100644 index d9b696b82c7..00000000000 --- a/soc/nordic/nrf54h/gpd/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -config SOC_NRF54H20_GPD - bool "Global Power Domain service" - imply NRFS - imply NRFS_GDPWR_SERVICE_ENABLED - select ONOFF - select PINCTRL - default y if !MCUBOOT && (SOC_NRF54H20_CPUAPP || SOC_NRF54H20_CPURAD) - help - This option enables the Global Power Domain service. diff --git a/soc/nordic/nrf54h/gpd/gpd.c b/soc/nordic/nrf54h/gpd/gpd.c deleted file mode 100644 index 5e5f0b2dae1..00000000000 --- a/soc/nordic/nrf54h/gpd/gpd.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -LOG_MODULE_REGISTER(gpd, CONFIG_SOC_LOG_LEVEL); - -/* enforce alignment between DT<->nrfs */ -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; - onoff_notify_fn notify; - uint8_t id; - struct k_mutex lock; - struct k_sem sem; - int res; -}; - -static void start(struct onoff_manager *mgr, onoff_notify_fn notify); -static void stop(struct onoff_manager *mgr, onoff_notify_fn notify); - -#define GPD_READY_TIMEOUT_MS 1000 - -#define GPD_SERVICE_READY BIT(0) -#define GPD_SERVICE_ERROR BIT(1) -#define GPD_SERVICE_REQ_OK BIT(2) -#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), - .sem = Z_SEM_INITIALIZER(slow_active.sem, 0, 1), -}; -static struct gpd_onoff_manager slow_main = { - .id = NRF_GPD_SLOW_MAIN, - .lock = Z_MUTEX_INITIALIZER(slow_main.lock), - .sem = Z_SEM_INITIALIZER(slow_main.sem, 0, 1), -}; - -static const struct onoff_transitions transitions = - ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL); - -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: - return &slow_main; - default: - return NULL; - } -} - -static void request_cb(struct onoff_manager *mgr_, struct onoff_client *cli, uint32_t state, - int res) -{ - ARG_UNUSED(cli); - ARG_UNUSED(state); - - struct gpd_onoff_manager *gpd_mgr = CONTAINER_OF(mgr_, struct gpd_onoff_manager, mgr); - - gpd_mgr->res = res; - k_sem_give(&gpd_mgr->sem); -} - -static int nrf_gpd_sync(struct gpd_onoff_manager *gpd_mgr) -{ - int64_t start; - nrfs_err_t err; - k_spinlock_key_t key; - gdpwr_request_type_t request; - - key = k_spin_lock(&gpd_mgr->mgr.lock); - - if (gpd_mgr->mgr.refs == 0) { - request = GDPWR_POWER_REQUEST_CLEAR; - } else { - request = GDPWR_POWER_REQUEST_SET; - } - - k_spin_unlock(&gpd_mgr->mgr.lock, key); - - atomic_clear_bit(&gpd_service_status, GPD_SERVICE_REQ_ERR); - atomic_clear_bit(&gpd_service_status, GPD_SERVICE_REQ_OK); - - err = nrfs_gdpwr_power_request(gpd_mgr->id, request, gpd_mgr); - if (err != NRFS_SUCCESS) { - return -EIO; - } - - start = k_uptime_get(); - while (k_uptime_get() - start < GPD_READY_TIMEOUT_MS) { - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_REQ_ERR)) { - return -EIO; - } - - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_REQ_OK)) { - return 0; - } - - k_yield(); - } - - LOG_ERR("nRFs GDPWR request timed out"); - - return -ETIMEDOUT; -} - -static void evt_handler(nrfs_gdpwr_evt_t const *p_evt, void *context) -{ - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_READY)) { - struct gpd_onoff_manager *gpd_mgr = context; - - switch (p_evt->type) { - case NRFS_GDPWR_REQ_APPLIED: - gpd_mgr->notify(&gpd_mgr->mgr, 0); - break; - default: - LOG_ERR("nRFs GDPWR request not applied"); - gpd_mgr->notify(&gpd_mgr->mgr, -EIO); - break; - } - } else { - switch (p_evt->type) { - case NRFS_GDPWR_REQ_APPLIED: - atomic_set_bit(&gpd_service_status, GPD_SERVICE_REQ_OK); - break; - default: - LOG_ERR("nRFs GDPWR request not applied"); - atomic_set_bit(&gpd_service_status, GPD_SERVICE_REQ_ERR); - break; - } - } -} - -static void start(struct onoff_manager *mgr, onoff_notify_fn notify) -{ - struct gpd_onoff_manager *gpd_mgr = CONTAINER_OF(mgr, struct gpd_onoff_manager, mgr); - - gpd_mgr->notify = notify; - - if (!atomic_test_bit(&gpd_service_status, GPD_SERVICE_READY)) { - notify(mgr, 0); - } else { - nrfs_err_t err; - - err = nrfs_gdpwr_power_request(gpd_mgr->id, GDPWR_POWER_REQUEST_SET, gpd_mgr); - if (err != NRFS_SUCCESS) { - LOG_ERR("nRFs GDPWR request failed (%d)", err); - notify(mgr, -EIO); - } - } -} - -static void stop(struct onoff_manager *mgr, onoff_notify_fn notify) -{ - struct gpd_onoff_manager *gpd_mgr = CONTAINER_OF(mgr, struct gpd_onoff_manager, mgr); - - gpd_mgr->notify = notify; - - if (!atomic_test_bit(&gpd_service_status, GPD_SERVICE_READY)) { - notify(mgr, 0); - } else { - nrfs_err_t err; - - err = nrfs_gdpwr_power_request(gpd_mgr->id, GDPWR_POWER_REQUEST_CLEAR, gpd_mgr); - if (err != NRFS_SUCCESS) { - LOG_ERR("nRFs GDPWR request failed (%d)", err); - notify(mgr, -EIO); - } - } -} - -int nrf_gpd_request(uint8_t id) -{ - int ret; - struct onoff_client client; - struct gpd_onoff_manager *gpd_mgr; - - gpd_mgr = get_mgr(id); - if (gpd_mgr == NULL) { - return -EINVAL; - } - - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_ERROR)) { - LOG_ERR("GPD service did not initialize properly"); - return -EIO; - } - - if (k_is_pre_kernel()) { - sys_notify_init_spinwait(&client.notify); - - ret = onoff_request(&gpd_mgr->mgr, &client); - if (ret < 0) { - return ret; - } - - while (sys_notify_fetch_result(&client.notify, &ret) == -EAGAIN) { - } - } else { - sys_notify_init_callback(&client.notify, request_cb); - k_mutex_lock(&gpd_mgr->lock, K_FOREVER); - - ret = onoff_request(&gpd_mgr->mgr, &client); - if (ret >= 0) { - (void)k_sem_take(&gpd_mgr->sem, K_FOREVER); - ret = gpd_mgr->res; - } - - k_mutex_unlock(&gpd_mgr->lock); - } - - return ret; -} - -int nrf_gpd_release(uint8_t id) -{ - struct gpd_onoff_manager *gpd_mgr; - - gpd_mgr = get_mgr(id); - if (gpd_mgr == NULL) { - return -EINVAL; - } - - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_ERROR)) { - LOG_ERR("GPD service did not initialize properly"); - return -EIO; - } - - return onoff_release(&gpd_mgr->mgr); -} - -int nrf_gpd_retain_pins_set(const struct pinctrl_dev_config *pcfg, bool retain) -{ - const struct pinctrl_state *state; - int ret; - - ret = pinctrl_lookup_state(pcfg, PINCTRL_STATE_DEFAULT, &state); - if (ret < 0) { - return ret; - } - - for (uint8_t i = 0U; i < state->pin_cnt; i++) { - uint32_t pin = NRF_GET_PIN(state->pins[i]); - - if (pin == NRF_PIN_DISCONNECTED) { - continue; - } - - if (retain) { - nrf_gpio_pin_retain_enable(pin); - } else { - nrf_gpio_pin_retain_disable(pin); - } - } - - return 0; -} - -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; - } - - ret = onoff_manager_init(&slow_main.mgr, &transitions); - if (ret < 0) { - return ret; - } - - return 0; -} - -static int nrf_gpd_post_init(void) -{ - nrfs_err_t err; - int ret; - - err = nrfs_backend_wait_for_connection(K_FOREVER); - if (err != NRFS_SUCCESS) { - ret = -EIO; - goto err; - } - - err = nrfs_gdpwr_init(evt_handler); - if (err != NRFS_SUCCESS) { - ret = -EIO; - goto err; - } - - /* 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; - } - - ret = nrf_gpd_sync(&slow_main); - if (ret < 0) { - goto err; - } - - atomic_set_bit(&gpd_service_status, GPD_SERVICE_READY); - - return 0; - -err: - atomic_set_bit(&gpd_service_status, GPD_SERVICE_ERROR); - - return ret; -} - -SYS_INIT(nrf_gpd_pre_init, PRE_KERNEL_1, 0); -SYS_INIT(nrf_gpd_post_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/soc/nordic/nrf54h/gpd/include/nrf/gpd.h b/soc/nordic/nrf54h/gpd/include/nrf/gpd.h deleted file mode 100644 index b8aab94accb..00000000000 --- a/soc/nordic/nrf54h/gpd/include/nrf/gpd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_NRF54H_GPD_INCLUDE_NRF_GPD_H_ -#define ZEPHYR_SOC_NORDIC_NRF54H_GPD_INCLUDE_NRF_GPD_H_ - -#include - -#include -#include - -/** - * @brief Request a global power domain. - * - * @param id Domain ID. - * - * @retval 0 If the request was successful. - * @retval -errno If the request was not successful. - */ -int nrf_gpd_request(uint8_t id); - -/** - * @brief Release a global power domain. - * - * @param id Domain ID. - * - * @retval 0 If the request was successful. - * @retval -errno If the request was not successful. - */ -int nrf_gpd_release(uint8_t id); - -/** - * @brief Retain set/clear a set of pins. - * - * @param pcfg Device pin configuration. - * @param retain Retain or not. - * - * @retval 0 If the request was successful. - * @retval -errno If the request was not successful. - */ -int nrf_gpd_retain_pins_set(const struct pinctrl_dev_config *pcfg, bool retain); - -#endif /* ZEPHYR_SOC_NORDIC_NRF54H_GPD_INCLUDE_NRF_GPD_H_ */ From dc124242ca1a75e205e417a6b7e6d15cdb330aeb Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 5 Aug 2025 19:44:41 +0200 Subject: [PATCH 6/9] [nrf fromtree] drivers: counter: counter_nrfx_timer: fix fast instance clock ctrl Update handling of fast instances to take into account whether CONFIG_CLOCK_CONTROL is enabled or not. Signed-off-by: Bjarki Arge Andreasen (cherry picked from commit c326bf6bc718afc72a1cd78ef97c73f95051284d) --- drivers/counter/counter_nrfx_timer.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/counter/counter_nrfx_timer.c b/drivers/counter/counter_nrfx_timer.c index a31d9672c76..26fa49b1aee 100644 --- a/drivers/counter/counter_nrfx_timer.c +++ b/drivers/counter/counter_nrfx_timer.c @@ -35,8 +35,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL); #define MAYBE_CONST_CONFIG const #endif -#if NRF_DT_INST_ANY_IS_FAST -#define COUNTER_ANY_FAST 1 +#if NRF_DT_INST_ANY_IS_FAST && CONFIG_CLOCK_CONTROL +#define COUNTER_IS_FAST(idx) NRF_DT_INST_IS_FAST(idx) +#define COUNTER_ANY_FAST +#else +#define COUNTER_IS_FAST(idx) 0 #endif struct counter_nrfx_data { @@ -460,13 +463,13 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { * which is using nrfs (IPC) are initialized later. */ #define TIMER_INIT_LEVEL(idx) \ - COND_CODE_1(NRF_DT_INST_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1)) + COND_CODE_1(COUNTER_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1)) /* Get initialization priority of an instance. Instances that requires clock control * which is using nrfs (IPC) are initialized later. */ #define TIMER_INIT_PRIO(idx) \ - COND_CODE_1(NRF_DT_INST_IS_FAST(idx), \ + COND_CODE_1(COUNTER_IS_FAST(idx), \ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ (CONFIG_COUNTER_INIT_PRIORITY)) @@ -522,8 +525,8 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { }, \ .ch_data = counter##idx##_ch_data, \ .timer = (NRF_TIMER_Type *)DT_INST_REG_ADDR(idx), \ - IF_ENABLED(NRF_DT_INST_IS_FAST(idx), \ - (.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_DRV_INST(idx))), \ + IF_ENABLED(COUNTER_IS_FAST(idx), \ + (.clk_dev = DEVICE_DT_GET_OR_NULL(DT_CLOCKS_CTLR(DT_DRV_INST(idx))), \ .clk_spec = { \ .frequency = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)), \ .accuracy = 0, \ From bd35a9c547dcd1a209333e4bd36cbceb31626b25 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 30 Jul 2025 15:37:26 +0200 Subject: [PATCH 7/9] [nrf fromlist] dts: bindings: introduce nordic,nrfs-swext Introduce nordic NRFS SWEXT power domain bindings and add it to relevant SoC devicetree files. Upstream PR #: 93880 Signed-off-by: Bjarki Arge Andreasen --- .../power-domain/nordic,nrfs-swext.yaml | 26 +++++++++++++++++++ dts/vendor/nordic/nrf54h20.dtsi | 9 +++++++ 2 files changed, 35 insertions(+) create mode 100644 dts/bindings/power-domain/nordic,nrfs-swext.yaml diff --git a/dts/bindings/power-domain/nordic,nrfs-swext.yaml b/dts/bindings/power-domain/nordic,nrfs-swext.yaml new file mode 100644 index 00000000000..a504f4d97cd --- /dev/null +++ b/dts/bindings/power-domain/nordic,nrfs-swext.yaml @@ -0,0 +1,26 @@ +# Copyright 2025 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic NRFS SWEXT power domain + +compatible: "nordic,nrfs-swext" + +include: power-domain.yaml + +properties: + "#power-domain-cells": + const: 0 + + max-current-ua: + type: int + description: Maxmimum supported current in microamps. + required: true + + current-limit-ua: + type: int + description: Maxmimum allowed current in microamps. + required: true + + power-down-clamp: + type: boolean + description: Enable ground clamp on output when powered down. diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 40824c4e690..771bbe5f679 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -246,6 +246,15 @@ }; }; + swext: swext { + compatible = "nordic,nrfs-swext"; + status = "disabled"; + max-current-ua = <7500>; + current-limit-ua = <7500>; + zephyr,pm-device-runtime-auto; + #power-domain-cells = <0>; + }; + soc { #address-cells = <1>; #size-cells = <1>; From 1d642917b9da588ebc27748478c8cfe4a5f4be26 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 30 Jul 2025 15:40:11 +0200 Subject: [PATCH 8/9] [nrf fromlist] drivers: power_domain: introduce nrfs_swext device driver Introduce nrfx_swext device driver for NRFS SWEXT power domain device. Upstream PR #: 93880 Signed-off-by: Bjarki Arge Andreasen --- drivers/power_domain/CMakeLists.txt | 1 + drivers/power_domain/Kconfig | 1 + drivers/power_domain/Kconfig.nrfs_swext | 9 + .../power_domain/power_domain_nrfs_swext.c | 200 ++++++++++++++++++ 4 files changed, 211 insertions(+) create mode 100644 drivers/power_domain/Kconfig.nrfs_swext create mode 100644 drivers/power_domain/power_domain_nrfs_swext.c diff --git a/drivers/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index 9d508249f5e..2e56a366c87 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -8,5 +8,6 @@ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO_MONITOR power_domain_gpio_ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_adsp.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NXP_SCU power_domain_nxp_scu.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRFS_GDPWR power_domain_nrfs_gdpwr.c) +zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRFS_SWEXT power_domain_nrfs_swext.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRF_GPIO_PAD_GROUP power_domain_nrf_gpio_pad_group.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_SOC_PM_STATE power_domain_soc_state_change.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index 90a10ca9406..6334af3a56a 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -100,6 +100,7 @@ config POWER_DOMAIN_SOC_PM_STATE PM subsystem transitions in and out certain power states. rsource "Kconfig.nrfs_gdpwr" +rsource "Kconfig.nrfs_swext" rsource "Kconfig.nrf_gpio_pad_group" endif diff --git a/drivers/power_domain/Kconfig.nrfs_swext b/drivers/power_domain/Kconfig.nrfs_swext new file mode 100644 index 00000000000..1a2c5d2d895 --- /dev/null +++ b/drivers/power_domain/Kconfig.nrfs_swext @@ -0,0 +1,9 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config POWER_DOMAIN_NRFS_SWEXT + bool "NRFS SWEXT power domain driver" + depends on DT_HAS_NORDIC_NRFS_SWEXT_ENABLED + select NRFS + select NRFS_SWEXT_SERVICE_ENABLED + default y diff --git a/drivers/power_domain/power_domain_nrfs_swext.c b/drivers/power_domain/power_domain_nrfs_swext.c new file mode 100644 index 00000000000..900fe4f7a8e --- /dev/null +++ b/drivers/power_domain/power_domain_nrfs_swext.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrfs_swext + +#include +#include +#include +#include + +#include +#include + +LOG_MODULE_REGISTER(nrfs_swext, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +BUILD_ASSERT( + DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, + "multiple instances not supported" +); + +struct nrfs_swext_data { + struct k_sem evt_sem; + nrfs_swext_evt_type_t evt; +}; + +struct nrfs_swext_config { + uint16_t current_limit_ua; + bool enable_power_down_clamp; +}; + +static void nrfs_swext_driver_evt_handler(nrfs_swext_evt_t const *p_evt, void *context) +{ + struct nrfs_swext_data *dev_data = context; + + LOG_DBG("evt %u", (uint32_t)p_evt->type); + + if (p_evt->type == NRFS_SWEXT_EVT_OVERCURRENT) { + /* Overcurrent is an unrecoverable condition which requires hardware fix */ + LOG_ERR("overcurrent"); + k_panic(); + }; + + dev_data->evt = p_evt->type; + k_sem_give(&dev_data->evt_sem); +} + +static int nrfs_swext_driver_power_down(const struct device *dev) +{ + const struct nrfs_swext_config *dev_config = dev->config; + nrfs_err_t err; + swext_pd_clamp_t pd_clamp = dev_config->enable_power_down_clamp + ? SWEXT_PD_CLAMP_ENABLED + : SWEXT_PD_CLAMP_DISABLED; + + /* + * Power down request does not respond with an event. + * Set context to NULL, fire and forget. + */ + err = nrfs_swext_power_down(pd_clamp, NULL); + if (err != NRFS_SUCCESS) { + LOG_ERR("failed to request power down"); + return -ENODEV; + } + + return 0; +} + +static int nrfs_swext_driver_power_up(const struct device *dev) +{ + struct nrfs_swext_data *dev_data = dev->data; + const struct nrfs_swext_config *dev_config = dev->config; + nrfs_err_t err; + uint8_t load_current; + + load_current = nrfs_swext_load_current_to_raw(dev_config->current_limit_ua); + err = nrfs_swext_power_up(load_current, dev_data); + if (err != NRFS_SUCCESS) { + LOG_ERR("failed to request power up"); + return -ENODEV; + } + + (void)k_sem_take(&dev_data->evt_sem, K_FOREVER); + + if (dev_data->evt == NRFS_SWEXT_EVT_ENABLED) { + return 0; + } + + LOG_ERR("power up request rejected"); + return -EIO; +} + +#if IS_ENABLED(CONFIG_DEVICE_DEPS) && IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN) +static void nrfs_swext_driver_notify_children(const struct device *dev, + enum pm_device_action action) +{ + pm_device_children_action_run(dev, action, NULL); +} +#else +static void nrfs_swext_driver_notify_children(const struct device *dev, + enum pm_device_action action) +{ + ARG_UNUSED(dev); + ARG_UNUSED(action); +} +#endif + +static int nrfs_swext_driver_suspend(const struct device *dev) +{ + int ret; + + nrfs_swext_driver_notify_children(dev, PM_DEVICE_ACTION_TURN_OFF); + + ret = nrfs_swext_driver_power_down(dev); + if (ret) { + nrfs_swext_driver_notify_children(dev, PM_DEVICE_ACTION_TURN_ON); + } + + return ret; +} + +static int nrfs_swext_driver_resume(const struct device *dev) +{ + int ret; + + ret = nrfs_swext_driver_power_up(dev); + if (ret == 0) { + nrfs_swext_driver_notify_children(dev, PM_DEVICE_ACTION_TURN_ON); + } + + return ret; +} + +static int nrfs_swext_driver_pm_action(const struct device *dev, + enum pm_device_action action) +{ + int ret; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + ret = nrfs_swext_driver_suspend(dev); + break; + + case PM_DEVICE_ACTION_RESUME: + ret = nrfs_swext_driver_resume(dev); + break; + + default: + ret = -ENOTSUP; + break; + }; + + return ret; +} + +static int nrfs_swext_driver_init(const struct device *dev) +{ + struct nrfs_swext_data *dev_data = dev->data; + nrfs_err_t err; + + LOG_DBG("waiting for nrfs backend connected"); + err = nrfs_backend_wait_for_connection(K_FOREVER); + if (err != NRFS_SUCCESS) { + LOG_ERR("nrfs backend not connected"); + return -ENODEV; + } + + err = nrfs_swext_init(nrfs_swext_driver_evt_handler); + if (err != NRFS_SUCCESS) { + LOG_ERR("failed to init swext service"); + return -ENODEV; + } + + k_sem_init(&dev_data->evt_sem, 0, 1); + return pm_device_driver_init(dev, nrfs_swext_driver_pm_action); +} + +PM_DEVICE_DT_INST_DEFINE(0, nrfs_swext_driver_pm_action); + +BUILD_ASSERT(DT_INST_PROP(0, max_current_ua) <= UINT16_MAX); +BUILD_ASSERT(DT_INST_PROP(0, current_limit_ua) <= DT_INST_PROP(0, max_current_ua)); + +static struct nrfs_swext_data data0; +static const struct nrfs_swext_config config0 = { + .current_limit_ua = DT_INST_PROP(0, current_limit_ua), + .enable_power_down_clamp = DT_INST_PROP(0, power_down_clamp), +}; + +DEVICE_DT_INST_DEFINE( + 0, + nrfs_swext_driver_init, + PM_DEVICE_DT_INST_GET(0), + &data0, + &config0, + POST_KERNEL, + UTIL_INC(CONFIG_NRFS_BACKEND_IPC_SERVICE_INIT_PRIO), + NULL +); From 095d11e077b6a82ba3b0a37655c54f8e18fd005a Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 7 Aug 2025 13:09:24 +0200 Subject: [PATCH 9/9] [nrf fromlist] power_domain: nrfs_gdpwr: patch init sync The nrfs_gdpwr driver has a two stage init, which requires tracking an "expected" state of the power domain, to be applied once the ipc service needed to control the power domain is ready. This was tracked with the "off" member of struct domain_data. So, "off" was initialized to false, but, should actually be initialized to true, since by default, if nothing needs the power domain, it should be turned off when ipc service is ready. To fix this, rename "off" member to "on" and adjust logic. Additionally, define the correct struct domain_data in the DOMAIN_DEFINE() macro. Can save 2 bytes. This did not cause any issue since we typecast it anyway, and its size is large enough. Upstream PR #: 94214 Signed-off-by: Bjarki Arge Andreasen --- drivers/power_domain/power_domain_nrfs_gdpwr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/power_domain/power_domain_nrfs_gdpwr.c b/drivers/power_domain/power_domain_nrfs_gdpwr.c index 64e83f5774b..16343293be5 100644 --- a/drivers/power_domain/power_domain_nrfs_gdpwr.c +++ b/drivers/power_domain/power_domain_nrfs_gdpwr.c @@ -26,7 +26,7 @@ static const struct device *const domains[] = { }; struct domain_data { - bool off; + bool on; bool synced; }; @@ -104,7 +104,7 @@ static int manager_set_domain(const struct device *dev, bool on) * is ready. */ ret = 0; - dev_data->off = !on; + dev_data->on = on; } if (ret == 0) { @@ -134,9 +134,9 @@ static int manager_sync_domain_locked(const struct device *dev) /* * Power domains initialize ON so we only need to send a request - * if the expected state of the power domain is OFF. + * if the expected state of the power domain is not ON. */ - if (dev_data->off) { + if (!dev_data->on) { return manager_set_domain_locked(dev_config->domain, false); } @@ -261,7 +261,7 @@ static int domain_init(const struct device *dev) _CONCAT(GDPWR_GD_, DT_NODE_FULL_NAME_UPPER_TOKEN(node)) #define DOMAIN_DEFINE(node) \ - static struct domain_config DOMAIN_NODE_SYMNAME(node, data); \ + static struct domain_data DOMAIN_NODE_SYMNAME(node, data); \ static const struct domain_config DOMAIN_NODE_SYMNAME(node, config) = { \ .domain = DOMAIN_NODE_TO_GDPWR_ENUM(node), \ }; \