From cea20f32b8c7dd4c175fe0e5307e8a83cd50daca Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 2 Jul 2025 22:14:42 +0200 Subject: [PATCH 1/6] 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 --- 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 811f640b55a4a..dce536a7c5184 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -7,5 +7,6 @@ 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) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_TISCI power_domain_tisci.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index 759aeec559abc..e5fae7c03546c 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -123,4 +123,6 @@ config SOC_POWER_DOMAIN_INIT endif #POWER_DOMAIN_TISCI +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 0000000000000..bf9abd59aedba --- /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 0000000000000..64e83f5774bc1 --- /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 0000000000000..916db56f475c3 --- /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 0aecde7599cdac47d3fb2febaa8c5bf2c8a8b454 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 2 Jul 2025 22:20:28 +0200 Subject: [PATCH 2/6] drivers: power_domain: introduce nrfs swext Introduce NRFS SWEXT (Switch External) device driver and devicetree binding. 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 | 204 ++++++++++++++++++ .../power-domain/nordic,nrfs-swext.yaml | 26 +++ 5 files changed, 241 insertions(+) create mode 100644 drivers/power_domain/Kconfig.nrfs_swext create mode 100644 drivers/power_domain/power_domain_nrfs_swext.c create mode 100644 dts/bindings/power-domain/nordic,nrfs-swext.yaml diff --git a/drivers/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index dce536a7c5184..d9ccf1b15486b 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_SOC_PM_STATE power_domain_soc_state_change.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_TISCI power_domain_tisci.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index e5fae7c03546c..2e6387ba0cc2a 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -124,5 +124,6 @@ config SOC_POWER_DOMAIN_INIT endif #POWER_DOMAIN_TISCI rsource "Kconfig.nrfs_gdpwr" +rsource "Kconfig.nrfs_swext" endif diff --git a/drivers/power_domain/Kconfig.nrfs_swext b/drivers/power_domain/Kconfig.nrfs_swext new file mode 100644 index 0000000000000..1a2c5d2d895e1 --- /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 0000000000000..0a73a07215993 --- /dev/null +++ b/drivers/power_domain/power_domain_nrfs_swext.c @@ -0,0 +1,204 @@ +/* + * 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) +{ + struct nrfs_swext_data *dev_data = dev->data; + 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; + + err = nrfs_swext_power_down(pd_clamp, dev_data); + if (err != NRFS_SUCCESS) { + LOG_ERR("failed to request power down"); + 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 down request rejected"); + return -EIO; +} + +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 +); 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 0000000000000..a504f4d97cddd --- /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. From 88d003bc9c998c155c2220b1bd3cf7954370b944 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 2 Jul 2025 22:23:43 +0200 Subject: [PATCH 3/6] 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 --- 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 d9ccf1b15486b..6e8abf1cd7bf0 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -9,5 +9,6 @@ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_a 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) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_TISCI power_domain_tisci.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index 2e6387ba0cc2a..fb22142f1bfbb 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -125,5 +125,6 @@ endif #POWER_DOMAIN_TISCI rsource "Kconfig.nrfs_gdpwr" rsource "Kconfig.nrfs_swext" +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 0000000000000..1b36c0cc7e08c --- /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 0000000000000..8b4119312c10a --- /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 0000000000000..29aade85cbf05 --- /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 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 cdf841b96f6cd91c936df792e42c804630a1890b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 3 Jul 2025 02:22:54 +0200 Subject: [PATCH 4/6] 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 --- drivers/can/can_nrf.c | 11 - drivers/counter/counter_nrfx_timer.c | 22 +- drivers/gpio/gpio_nrfx.c | 72 +---- drivers/pinctrl/pinctrl_nrf.c | 155 ++++++---- drivers/pwm/pwm_nrfx.c | 24 +- drivers/serial/uart_nrfx_uarte.c | 98 ++++--- drivers/spi/spi_nrfx_spim.c | 92 +++--- drivers/spi/spi_nrfx_spis.c | 33 +-- dts/arm/nordic/nrf54h20_cpuapp.dtsi | 60 ++++ dts/arm/nordic/nrf54h20_cpurad.dtsi | 60 ++++ .../gpio/nordic,nrf-gpio-pad-group.yaml | 6 +- dts/vendor/nordic/nrf54h20.dtsi | 275 ++++++++++++------ 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 - 28 files changed, 612 insertions(+), 390 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_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf delete mode 100644 tests/arch/arm/arm_irq_vector_table/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 f8c037835a834..606117b194859 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 71f7f7edd3316..a31d9672c76b9 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 0a94b84c67fd5..1bcf76180a67f 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 NRF_GPIO_HAS_PAD_GROUP 1 +#else +#define NRF_GPIO_HAS_PAD_GROUP 0 #endif struct gpio_nrfx_data { @@ -33,8 +35,8 @@ struct gpio_nrfx_cfg { uint32_t edge_sense; uint8_t port_num; nrfx_gpiote_t gpiote; -#ifdef CONFIG_SOC_NRF54H20_GPD - uint8_t pad_pd; +#if NRF_GPIO_HAS_PAD_GROUP + const struct device *pad_group; #endif }; @@ -64,30 +66,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) { @@ -134,8 +112,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) { @@ -216,7 +192,6 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, } end: - gpio_nrfx_gpd_retain_set(port, BIT(pin)); return pm_device_runtime_put(port); } @@ -317,10 +292,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); } @@ -335,9 +308,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); } @@ -352,9 +323,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); } @@ -372,10 +341,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); } @@ -546,14 +513,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 NRF_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; @@ -562,14 +525,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 NRF_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; @@ -660,12 +619,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 NRF_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) \ @@ -679,7 +637,7 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = { .port_num = DT_INST_PROP(id, port), \ .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \ .gpiote = GPIOTE_INSTANCE(id), \ - 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 07941fcb5ad5c..75d3db8c5129c 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) && @@ -112,13 +111,105 @@ static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = { #define NRF_PSEL_TDM(reg, line) ((NRF_TDM_Type *)reg)->PSEL.line #endif -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 NRF_GPIO_HAS_PAD_GROUP 1 +#else +#define NRF_GPIO_HAS_PAD_GROUP 0 +#endif + +#if NRF_GPIO_HAS_PAD_GROUP + +static const struct device *const pad_groups[] = { + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group0)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group1)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group2)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group3)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group4)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group5)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group6)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group7)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group8)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio_pad_group9)), +}; + +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]); @@ -472,25 +563,9 @@ 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); + port_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i])); if (write != NO_WRITE) { nrf_gpio_pin_write(pin, write); @@ -502,35 +577,17 @@ 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 */ + pad_group_release_pin(pin); + port_pin_clock_set(pin, false); } -#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 6a106c128412a..f9941bcd0697b 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 @@ -522,7 +506,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 46c5a8b83d2e9..2f13091910422 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 CPUAPP and CPURAD 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 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. */ -BUILD_ASSERT(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)); -BUILD_ASSERT(IS_ENABLED(CONFIG_CLOCK_CONTROL)); -#define UARTE_ANY_FAST_PD 1 +#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_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 @@ -333,7 +333,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))) @@ -349,7 +349,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 @@ -419,6 +419,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) { @@ -436,12 +437,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 defined(UARTE_ANY_NONE_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ) @@ -713,7 +710,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; @@ -723,10 +720,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_BAUDRATE_RETENTION_WORKAROUND nrf_uarte_baudrate_set(uarte, COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, @@ -1192,7 +1188,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. */ @@ -1713,7 +1709,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. */ @@ -2332,9 +2328,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); } } @@ -2346,7 +2341,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; @@ -2408,13 +2403,8 @@ 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 - - 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) @@ -2581,13 +2571,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)) @@ -2618,12 +2608,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 neccesarily ISR safe (we can't + * relyable now, its out of our control). UARTE_ON_MANAGED_POWER_DOMAIN() lets 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), \ @@ -2686,8 +2692,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 c92104d9da87f..842f667b3cba1 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 #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 #include #endif @@ -43,20 +40,44 @@ LOG_MODULE_REGISTER(spi_nrfx_spim, CONFIG_SPI_LOG_LEVEL); #define SPI_BUFFER_IN_RAM 1 #endif -#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 +/* + * We use NODELABEL here because the nrfx API requires us to call + * functions which are named according to SoC peripheral instance + * being operated on. Since DT_INST() makes no guarantees about that, + * it won't work. + */ +#define SPIM(idx) DT_NODELABEL(spi##idx) +#define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop) +#define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop) +#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions) + +/* 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 struct spi_nrfx_data { @@ -74,7 +95,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 }; @@ -94,7 +115,7 @@ struct spi_nrfx_config { #ifdef CONFIG_DCACHE uint32_t mem_attr; #endif -#ifdef USE_CLOCK_REQUESTS +#ifdef SPIM_ANY_FAST const struct device *clk_dev; struct nrf_clock_spec clk_spec; #endif @@ -104,7 +125,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; @@ -131,7 +152,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; @@ -682,10 +703,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 - return pm_device_runtime_is_enabled(dev) ? request_clock(dev) : 0; } @@ -705,10 +722,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 - (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); } @@ -787,17 +800,6 @@ static int spi_nrfx_deinit(const struct device *dev) return 0; } -/* - * We use NODELABEL here because the nrfx API requires us to call - * functions which are named according to SoC peripheral instance - * being operated on. Since DT_INST() makes no guarantees about that, - * it won't work. - */ -#define SPIM(idx) DT_NODELABEL(spi##idx) -#define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop) -#define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop) -#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions) - #define SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \ IF_ENABLED(NRFX_SPIM_EXTENDED_ENABLED, \ (.dcx_pin = NRF_SPIM_PIN_NOT_CONNECTED, \ @@ -813,20 +815,13 @@ static int spi_nrfx_deinit(const struct device *dev) (0))), \ (0)) -/* 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_PD(_, /*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)); \ @@ -880,10 +875,9 @@ static int spi_nrfx_deinit(const struct device *dev) .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \ IF_ENABLED(CONFIG_DCACHE, \ (.mem_attr = SPIM_GET_MEM_ATTR(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, \ },)) \ @@ -910,4 +904,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 ceb479c0441ff..66994956e53b3 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. @@ -52,9 +44,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; @@ -379,12 +368,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 - (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); } @@ -394,12 +377,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 (dev_config->wake_gpio.port == NULL) { nrf_spis_enable(dev_config->spis.p_reg); } @@ -489,7 +466,7 @@ static int spi_nrfx_init(const struct device *dev) * - 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(IS_EQ(idx, 120), (spis##idx), (spi##idx)) #define SPIS(idx) DT_NODELABEL(SPIS_NODE(idx)) @@ -528,9 +505,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)), \ }; \ @@ -538,7 +512,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 c56df42ddd5b2..9e790656e501c 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 2d2fdee8d270e..279bc75811128 100644 --- a/dts/arm/nordic/nrf54h20_cpurad.dtsi +++ b/dts/arm/nordic/nrf54h20_cpurad.dtsi @@ -99,3 +99,63 @@ wdt011: &cpurad_wdt011 {}; &dppic020 { 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/bindings/gpio/nordic,nrf-gpio-pad-group.yaml b/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml index 29aade85cbf05..104277addd35e 100644 --- a/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml +++ b/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml @@ -13,9 +13,9 @@ description: | the power domain is suspended. The GPIO pad group is a child node of the GPIO - controller which manages the the pad group, - named pad-group. The pad group's nodelabel is - named gpio_pad_group. + controller which manages the pad group, named + pad-group. The pad group's nodelabel is named + gpio_pad_group. Example layout: diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 042725a16171d..3ab3870191ea1 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -15,7 +15,6 @@ #include #include #include -#include /delete-node/ &sw_pwm; @@ -181,6 +180,7 @@ open-loop-startup-time-us = <200>; /* To be measured */ clocks = <&hfxo>, <&lfxo>; clock-names = "hfxo", "lfxo"; + status = "disabled"; }; hsfll120: hsfll120 { @@ -192,6 +192,7 @@ 128000000 256000000 320000000>; + status = "disabled"; }; lfclk: lfclk { @@ -205,6 +206,7 @@ lflprc-startup-time-us = <200>; /* To be measured */ clocks = <&hfxo>, <&lfxo>; clock-names = "hfxo", "lfxo"; + status = "disabled"; }; audiopll: audiopll { @@ -214,9 +216,48 @@ }; }; - 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"; + }; + }; + + swext: swext { + compatible = "nordic,nrfs-swext"; + max-current-ua = <10000>; + current-limit-ua = <10000>; + zephyr,pm-device-runtime-auto; + #power-domain-cells = <0>; + status = "disabled"; }; soc { @@ -226,7 +267,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>; }; @@ -513,7 +554,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>; @@ -529,7 +570,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"; @@ -538,21 +579,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>; }; @@ -593,7 +634,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>; @@ -615,7 +656,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"; }; @@ -624,7 +665,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 { @@ -633,7 +674,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>; @@ -645,7 +686,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>; @@ -657,7 +698,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; }; @@ -666,7 +707,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>; @@ -680,7 +721,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>; @@ -698,7 +739,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; }; @@ -710,7 +751,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>; @@ -726,7 +767,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"; @@ -742,7 +783,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>; }; @@ -751,7 +792,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 { @@ -761,7 +802,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>; }; @@ -773,7 +814,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>; }; @@ -784,7 +825,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 { @@ -793,7 +834,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 { @@ -801,14 +842,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>; }; @@ -818,10 +859,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 { @@ -830,10 +880,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 { @@ -842,10 +901,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 { @@ -854,11 +922,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 { @@ -867,11 +942,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 { @@ -880,17 +962,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 { @@ -899,7 +990,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; }; @@ -912,7 +1003,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 { @@ -920,7 +1011,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 { @@ -928,14 +1019,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 { @@ -944,7 +1035,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 { @@ -952,7 +1043,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 { @@ -960,7 +1051,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 { @@ -970,14 +1061,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 { @@ -987,7 +1078,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>; }; @@ -999,7 +1090,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>; }; @@ -1010,7 +1101,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; }; @@ -1021,7 +1112,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>; @@ -1037,7 +1128,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>; @@ -1055,7 +1146,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; @@ -1067,7 +1158,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>; @@ -1083,7 +1174,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>; @@ -1101,17 +1192,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 { @@ -1121,7 +1213,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>; }; @@ -1133,7 +1225,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>; }; @@ -1144,7 +1236,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; }; @@ -1155,7 +1247,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>; @@ -1171,7 +1263,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>; @@ -1189,7 +1281,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; @@ -1201,7 +1293,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>; @@ -1217,7 +1309,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>; @@ -1235,7 +1327,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; @@ -1245,7 +1337,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 { @@ -1255,7 +1347,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>; }; @@ -1267,7 +1359,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>; }; @@ -1279,7 +1371,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; }; @@ -1289,7 +1381,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>; @@ -1305,7 +1397,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>; @@ -1323,7 +1415,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; @@ -1335,7 +1427,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>; @@ -1351,7 +1443,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>; @@ -1369,7 +1461,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; @@ -1379,7 +1471,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 { @@ -1389,7 +1481,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>; }; @@ -1401,7 +1493,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>; }; @@ -1413,7 +1505,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; }; @@ -1423,7 +1515,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>; @@ -1439,7 +1531,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>; @@ -1457,10 +1549,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 { @@ -1469,7 +1562,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>; @@ -1485,7 +1578,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>; @@ -1503,7 +1596,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; @@ -1518,7 +1611,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 = , ; }; @@ -1532,7 +1625,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 f1d3b6357f97d..337799595d735 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 port. + * + * @param pincfg Pin configuration bit field. + */ +#define NRF_GET_PORT_PIN(pincfg) (NRF_GET_PORT(pincfg) % 32) + /** @endcond */ #ifdef __cplusplus diff --git a/soc/nordic/common/soc_nrf_common.h b/soc/nordic/common/soc_nrf_common.h index dd6fb8866bfc8..9d7aae2d469a9 100644 --- a/soc/nordic/common/soc_nrf_common.h +++ b/soc/nordic/common/soc_nrf_common.h @@ -255,6 +255,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)) \ + ), \ + ( \ + IS_EQ( \ + DT_DEP_ORD(DT_PHANDLE(node_id, power_domains)), \ + DT_DEP_ORD(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 c0e619cd1e2d9..a6dfc1b57c1f1 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -87,7 +87,6 @@ config SOC_NRF54H20_CPUFLPR select RISCV_CORE_NORDIC_VPR rsource "bicr/Kconfig" -rsource "gpd/Kconfig" config SOC_NRF54H20_IRON select EXPERIMENTAL if MCUBOOT diff --git a/soc/nordic/nrf54h/Kconfig.defconfig b/soc/nordic/nrf54h/Kconfig.defconfig index 486343a78ab74..b11dcd9916c90 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 595cc2d388602..15db64affbc44 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -14,4 +14,7 @@ config NRF_REGTOOL_GENERATE_UICR 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 1fffdeae6d2e3..9dc9d4067c732 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -14,4 +14,7 @@ config NRF_REGTOOL_GENERATE_UICR 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 0bcc82e646b1a..0000000000000 --- 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 0bcc82e646b1a..0000000000000 --- 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 deleted file mode 100644 index 0bcc82e646b1a..0000000000000 --- a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=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 deleted file mode 100644 index 0bcc82e646b1a..0000000000000 --- a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=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 0bcc82e646b1a..0000000000000 --- 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 0bcc82e646b1a..0000000000000 --- 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 0bcc82e646b1a..0000000000000 --- 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 0bcc82e646b1a..0000000000000 --- 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 0bcc82e646b1a..0000000000000 --- 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 0bcc82e646b1a..0000000000000 --- a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n From 3e4dca40fc5a7b6e0f1352c39f2950b6bba1ce13 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 3 Jul 2025 02:29:16 +0200 Subject: [PATCH 5/6] soc: nrf54h: remove deprecated gpd (global power domain) driver Remove the deprecated GPD (Global Power Domain) driver. Signed-off-by: Bjarki Arge Andreasen --- dts/bindings/power/nordic,nrf-gpd.yaml | 11 - .../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 -- 8 files changed, 498 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/dts/bindings/power/nordic,nrf-gpd.yaml b/dts/bindings/power/nordic,nrf-gpd.yaml deleted file mode 100644 index feb5f2862e913..0000000000000 --- 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/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h b/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h deleted file mode 100644 index e4a5b83a30418..0000000000000 --- 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 337799595d735..e822fd40c6f8e 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 23c1cab1e77a5..94e38e62f2b17 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 7d029d2c8fcd3..0000000000000 --- 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 d9b696b82c7c7..0000000000000 --- 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 5e5f0b2dae133..0000000000000 --- 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 b8aab94accbd0..0000000000000 --- 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 12801a1f494d0784643db777edcb64e58d6fd015 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 17 Jul 2025 10:45:43 +0200 Subject: [PATCH 6/6] manifest: mcuboot: update sha to include nrf54 pd changes Update manifest to include changes which align mcuboot with the nrf54 power domain refactor. Signed-off-by: Bjarki Arge Andreasen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 411595f77b23a..1ce561f798cd1 100644 --- a/west.yml +++ b/west.yml @@ -310,7 +310,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 4eba8087fa606db801455f14d185255bc8c49467 + revision: pull/133/head path: bootloader/mcuboot groups: - bootloader