diff --git a/drivers/can/can_nrf.c b/drivers/can/can_nrf.c index f8c037835a8..606117b1948 100644 --- a/drivers/can/can_nrf.c +++ b/drivers/can/can_nrf.c @@ -17,10 +17,6 @@ #include #include -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif - /* nRF CAN wrapper offsets */ #define CAN_TASKS_START offsetof(NRF_CAN_Type, TASKS_START) #define CAN_EVENTS_CORE_0 offsetof(NRF_CAN_Type, EVENTS_CORE[0]) @@ -187,13 +183,6 @@ static int can_nrf_init(const struct device *dev) sys_write32(CAN_INTEN_CORE0_Msk | CAN_INTEN_CORE1_Msk, config->wrapper + CAN_INTEN); sys_write32(1U, config->wrapper + CAN_TASKS_START); -#ifdef CONFIG_SOC_NRF54H20_GPD - ret = nrf_gpd_retain_pins_set(config->pcfg, false); - if (ret < 0) { - return ret; - } -#endif - config->irq_configure(); ret = can_mcan_configure_mram(dev, config->mrba, config->mram); diff --git a/drivers/counter/counter_nrfx_timer.c b/drivers/counter/counter_nrfx_timer.c index 71f7f7edd33..a31d9672c76 100644 --- a/drivers/counter/counter_nrfx_timer.c +++ b/drivers/counter/counter_nrfx_timer.c @@ -35,23 +35,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL); #define MAYBE_CONST_CONFIG const #endif -#ifdef CONFIG_SOC_NRF54H20_GPD -#include - -#define NRF_CLOCKS_INSTANCE_IS_FAST(node) \ - COND_CODE_1(DT_NODE_HAS_PROP(node, power_domains), \ - (IS_EQ(DT_PHA(node, power_domains, id), NRF_GPD_FAST_ACTIVE1)), \ - (0)) - -/* Macro must resolve to literal 0 or 1 */ -#define INSTANCE_IS_FAST(idx) NRF_CLOCKS_INSTANCE_IS_FAST(DT_DRV_INST(idx)) - -#define INSTANCE_IS_FAST_OR(idx) INSTANCE_IS_FAST(idx) || - -#if (DT_INST_FOREACH_STATUS_OKAY(INSTANCE_IS_FAST_OR) 0) +#if NRF_DT_INST_ANY_IS_FAST #define COUNTER_ANY_FAST 1 #endif -#endif struct counter_nrfx_data { counter_top_callback_t top_cb; @@ -474,13 +460,13 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { * which is using nrfs (IPC) are initialized later. */ #define TIMER_INIT_LEVEL(idx) \ - COND_CODE_1(INSTANCE_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1)) + COND_CODE_1(NRF_DT_INST_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1)) /* Get initialization priority of an instance. Instances that requires clock control * which is using nrfs (IPC) are initialized later. */ #define TIMER_INIT_PRIO(idx) \ - COND_CODE_1(INSTANCE_IS_FAST(idx), \ + COND_CODE_1(NRF_DT_INST_IS_FAST(idx), \ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ (CONFIG_COUNTER_INIT_PRIORITY)) @@ -536,7 +522,7 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { }, \ .ch_data = counter##idx##_ch_data, \ .timer = (NRF_TIMER_Type *)DT_INST_REG_ADDR(idx), \ - IF_ENABLED(INSTANCE_IS_FAST(idx), \ + IF_ENABLED(NRF_DT_INST_IS_FAST(idx), \ (.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_DRV_INST(idx))), \ .clk_spec = { \ .frequency = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)), \ diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 0a94b84c67f..1bcf76180a6 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 34c0107b591..fa1f5c79543 100644 --- a/drivers/pinctrl/pinctrl_nrf.c +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -5,11 +5,10 @@ */ #include +#include +#include #include -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif BUILD_ASSERT(((NRF_PULL_NONE == NRF_GPIO_PIN_NOPULL) && (NRF_PULL_DOWN == NRF_GPIO_PIN_PULLDOWN) && @@ -124,13 +123,105 @@ static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = { #endif #endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_hpf_mspi_controller) || ... */ -int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, - uintptr_t reg) +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_gpio_pad_group) +#define 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]); @@ -505,25 +596,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); @@ -535,35 +610,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/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index d459e0d88c3..6e8abf1cd7b 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -7,4 +7,8 @@ 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_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 7bf5fe42470..fb22142f1bf 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -97,6 +97,34 @@ config POWER_DOMAIN_SOC_PM_STATE select DEVICE_DEPS help Generic power domain control to turn on/off devices when the - PM subsystem transitions in and out certain power states. + PM subsystem transitions in and out of certain power states. + +config POWER_DOMAIN_TISCI + bool "TISCI managed power domain" + default y + depends on DT_HAS_TI_SCI_PM_DOMAIN_ENABLED + help + TISCI managed power domain control to turn on/off devices when the + PM subsystem transitions in and out of certain power states. + +if POWER_DOMAIN_TISCI + +config POWER_DOMAIN_TISCI_INIT_PRIORITY + int "TISCI managed power domain init priority" + default 10 + help + TISCI managed power domain initialization priority. + +config SOC_POWER_DOMAIN_INIT + bool "Power domain initialization" + default y + help + Power domain initialization for the SoC. + +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 00000000000..1b36c0cc7e0 --- /dev/null +++ b/drivers/power_domain/Kconfig.nrf_gpio_pad_group @@ -0,0 +1,7 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config POWER_DOMAIN_NRF_GPIO_PAD_GROUP + bool "NRFS Global Domain Power Request driver" + depends on DT_HAS_NORDIC_NRF_GPIO_PAD_GROUP_ENABLED + default y diff --git a/drivers/power_domain/Kconfig.nrfs_gdpwr b/drivers/power_domain/Kconfig.nrfs_gdpwr new file mode 100644 index 00000000000..bf9abd59aed --- /dev/null +++ b/drivers/power_domain/Kconfig.nrfs_gdpwr @@ -0,0 +1,17 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config POWER_DOMAIN_NRFS_GDPWR + bool "NRFS Global Domain Power Request driver" + depends on DT_HAS_NORDIC_NRFS_GDPWR_ENABLED + select NRFS + select NRFS_GDPWR_SERVICE_ENABLED + default y + +if POWER_DOMAIN_NRFS_GDPWR + +config POWER_DOMAIN_NRFS_GDPWR_TIMEOUT_MS + int "GDPWR request timeout in milliseconds" + default 500 + +endif # POWER_DOMAIN_NRFS_GDPWR diff --git a/drivers/power_domain/Kconfig.nrfs_swext b/drivers/power_domain/Kconfig.nrfs_swext new file mode 100644 index 00000000000..1a2c5d2d895 --- /dev/null +++ b/drivers/power_domain/Kconfig.nrfs_swext @@ -0,0 +1,9 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config POWER_DOMAIN_NRFS_SWEXT + bool "NRFS SWEXT power domain driver" + depends on DT_HAS_NORDIC_NRFS_SWEXT_ENABLED + select NRFS + select NRFS_SWEXT_SERVICE_ENABLED + default y diff --git a/drivers/power_domain/power_domain_nrf_gpio_pad_group.c b/drivers/power_domain/power_domain_nrf_gpio_pad_group.c new file mode 100644 index 00000000000..8b4119312c1 --- /dev/null +++ b/drivers/power_domain/power_domain_nrf_gpio_pad_group.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_gpio_pad_group + +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(nrf_gpio_pad_group, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +struct nrf_port_retain_config { + NRF_GPIO_Type *regs; + uint32_t retain_mask; +}; + +static void nrf_port_retain_driver_turn_off(const struct device *dev) +{ + const struct nrf_port_retain_config *dev_config = dev->config; + + LOG_DBG("%s pads 0x%08x retain %s", dev->name, dev_config->retain_mask, "enable"); + nrf_gpio_port_retain_enable(dev_config->regs, dev_config->retain_mask); +} + +static void nrf_port_retain_driver_turn_on(const struct device *dev) +{ + const struct nrf_port_retain_config *dev_config = dev->config; + + LOG_DBG("%s pads 0x%08x retain %s", dev->name, dev_config->retain_mask, "disable"); + nrf_gpio_port_retain_disable(dev_config->regs, dev_config->retain_mask); +} + +static int nrf_port_retain_driver_pm_action(const struct device *dev, + enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_TURN_OFF: + nrf_port_retain_driver_turn_off(dev); + break; + + case PM_DEVICE_ACTION_TURN_ON: + nrf_port_retain_driver_turn_on(dev); + break; + + default: + break; + }; + + return 0; +} + +static int nrf_port_retain_driver_init(const struct device *dev) +{ + return pm_device_driver_init(dev, nrf_port_retain_driver_pm_action); +} + +#define NRF_GPIO_PAD_GROUP_DEFINE(inst) \ + static const struct nrf_port_retain_config _CONCAT(config, inst) = { \ + .regs = (NRF_GPIO_Type *)DT_REG_ADDR(DT_INST_PARENT(inst)), \ + .retain_mask = DT_PROP_OR(inst, retain_mask, UINT32_MAX), \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, nrf_port_retain_driver_pm_action); \ + \ + DEVICE_DT_INST_DEFINE( \ + inst, \ + nrf_port_retain_driver_init, \ + PM_DEVICE_DT_INST_GET(inst), \ + NULL, \ + &_CONCAT(config, inst), \ + PRE_KERNEL_1, \ + UTIL_INC(CONFIG_GPIO_INIT_PRIORITY), \ + NULL \ + ); + +DT_INST_FOREACH_STATUS_OKAY(NRF_GPIO_PAD_GROUP_DEFINE) diff --git a/drivers/power_domain/power_domain_nrfs_gdpwr.c b/drivers/power_domain/power_domain_nrfs_gdpwr.c new file mode 100644 index 00000000000..64e83f5774b --- /dev/null +++ b/drivers/power_domain/power_domain_nrfs_gdpwr.c @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrfs_gdpwr + +#include +#include +#include +#include + +#include +#include + +LOG_MODULE_REGISTER(nrfs_gdpwr, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +#define MANAGER_REQUEST_TIMEOUT K_MSEC(CONFIG_POWER_DOMAIN_NRFS_GDPWR_TIMEOUT_MS) + +static K_SEM_DEFINE(lock_sem, 1, 1); +static K_SEM_DEFINE(req_sem, 0, 1); +static nrfs_gdpwr_evt_type_t req_resp; +static const struct device *const domains[] = { + DT_INST_FOREACH_CHILD_SEP(0, DEVICE_DT_GET, (,)) +}; + +struct domain_data { + bool off; + bool synced; +}; + +struct domain_config { + gdpwr_power_domain_t domain; +}; + +static void manager_event_handler(nrfs_gdpwr_evt_t const *evt, void *context) +{ + ARG_UNUSED(context); + + req_resp = evt->type; + k_sem_give(&req_sem); +} + +static void manager_lock(void) +{ + if (k_is_pre_kernel()) { + return; + } + + (void)k_sem_take(&lock_sem, K_FOREVER); +} + +static void manager_unlock(void) +{ + if (k_is_pre_kernel()) { + return; + } + + k_sem_give(&lock_sem); +} + +static int manager_set_domain_locked(gdpwr_power_domain_t domain, bool on) +{ + nrfs_err_t err; + gdpwr_request_type_t req = on ? GDPWR_POWER_REQUEST_SET : GDPWR_POWER_REQUEST_CLEAR; + int ret; + + err = nrfs_gdpwr_power_request(domain, req, NULL); + if (err != NRFS_SUCCESS) { + LOG_ERR("%s %s", "nrfs gdpwr request", "failed"); + return -EIO; + } + + ret = k_sem_take(&req_sem, MANAGER_REQUEST_TIMEOUT); + if (ret < 0) { + LOG_ERR("%s %s", "nrfs gdpwr request", "timed out"); + return -ETIMEDOUT; + } + + if (req_resp != NRFS_GDPWR_REQ_APPLIED) { + LOG_ERR("%s %s", "nrfs gdpwr request", "rejected"); + return -EIO; + } + + return 0; +} + +static int manager_set_domain(const struct device *dev, bool on) +{ + struct domain_data *dev_data = dev->data; + const struct domain_config *dev_config = dev->config; + int ret; + + manager_lock(); + + if (dev_data->synced) { + /* NRFS GDPWR service is ready so we request domain change state */ + ret = manager_set_domain_locked(dev_config->domain, on); + } else { + /* + * NRFS GDPWR service is not ready so we track what the expected + * state of the power domain to be requested once the service + * is ready. + */ + ret = 0; + dev_data->off = !on; + } + + if (ret == 0) { + LOG_DBG("domain %s %ssynced and %s", + dev->name, + dev_data->synced ? "" : "un", + on ? "on" : "off"); + } + + manager_unlock(); + return ret; +} + +static int manager_sync_domain_locked(const struct device *dev) +{ + struct domain_data *dev_data = dev->data; + const struct domain_config *dev_config = dev->config; + + /* + * NRFS service is now ready. We will now synchronize the state + * of the power domain with the expected state we tracked with + * the struct domain_data off member. Following this, tracking + * the power domain state is handled by device PM, thus the + * struct domain_data off is no longer used. + */ + dev_data->synced = true; + + /* + * Power domains initialize ON so we only need to send a request + * if the expected state of the power domain is OFF. + */ + if (dev_data->off) { + return manager_set_domain_locked(dev_config->domain, false); + } + + return 0; +} + +static int manager_sync_domains_locked(void) +{ + int ret; + + ARRAY_FOR_EACH(domains, i) { + ret = manager_sync_domain_locked(domains[i]); + if (ret) { + break; + } + } + + return ret; +} + +static int manager_init(void) +{ + nrfs_err_t err; + int ret; + + err = nrfs_backend_wait_for_connection(K_FOREVER); + if (err != NRFS_SUCCESS) { + LOG_ERR("%s %s", "nrfs backend connection", "failed"); + return -EIO; + } + + err = nrfs_gdpwr_init(manager_event_handler); + if (err != NRFS_SUCCESS) { + LOG_ERR("%s %s", "nrfs gdpwr init", "failed"); + return -EIO; + } + + manager_lock(); + ret = manager_sync_domains_locked(); + manager_unlock(); + return ret; +} + +SYS_INIT(manager_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); + +#if IS_ENABLED(CONFIG_DEVICE_DEPS) && IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN) +static void domain_pm_notify_children(const struct device *dev, + enum pm_device_action action) +{ + pm_device_children_action_run(dev, action, NULL); +} +#else +static void domain_pm_notify_children(const struct device *dev, + enum pm_device_action action) +{ + ARG_UNUSED(dev); + ARG_UNUSED(action); +} +#endif + +static int domain_pm_suspend(const struct device *dev) +{ + int ret; + + domain_pm_notify_children(dev, PM_DEVICE_ACTION_TURN_OFF); + + ret = manager_set_domain(dev, false); + if (ret) { + domain_pm_notify_children(dev, PM_DEVICE_ACTION_TURN_ON); + } + + return ret; +} + +static int domain_pm_resume(const struct device *dev) +{ + int ret; + + ret = manager_set_domain(dev, true); + if (ret == 0) { + domain_pm_notify_children(dev, PM_DEVICE_ACTION_TURN_ON); + } + + return ret; +} + +static int domain_pm_action(const struct device *dev, enum pm_device_action action) +{ + int ret; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + ret = domain_pm_suspend(dev); + break; + + case PM_DEVICE_ACTION_RESUME: + ret = domain_pm_resume(dev); + break; + + case PM_DEVICE_ACTION_TURN_OFF: + case PM_DEVICE_ACTION_TURN_ON: + ret = -ENOTSUP; + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int domain_init(const struct device *dev) +{ + return pm_device_driver_init(dev, domain_pm_action); +} + +#define DOMAIN_NODE_SYMNAME(node, sym) \ + _CONCAT_4(domain, _, sym, DT_NODE_CHILD_IDX(node)) + +#define DOMAIN_NODE_TO_GDPWR_ENUM(node) \ + _CONCAT(GDPWR_GD_, DT_NODE_FULL_NAME_UPPER_TOKEN(node)) + +#define DOMAIN_DEFINE(node) \ + static struct domain_config DOMAIN_NODE_SYMNAME(node, data); \ + static const struct domain_config DOMAIN_NODE_SYMNAME(node, config) = { \ + .domain = DOMAIN_NODE_TO_GDPWR_ENUM(node), \ + }; \ + \ + PM_DEVICE_DT_DEFINE(node, domain_pm_action); \ + \ + DEVICE_DT_DEFINE( \ + node, \ + domain_init, \ + PM_DEVICE_DT_GET(node), \ + &DOMAIN_NODE_SYMNAME(node, data), \ + &DOMAIN_NODE_SYMNAME(node, config), \ + PRE_KERNEL_1, \ + 0, \ + NULL \ + ); + +DT_INST_FOREACH_CHILD(0, DOMAIN_DEFINE) diff --git a/drivers/power_domain/power_domain_nrfs_swext.c b/drivers/power_domain/power_domain_nrfs_swext.c new file mode 100644 index 00000000000..0a73a072159 --- /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/drivers/power_domain/power_domain_tisci.c b/drivers/power_domain/power_domain_tisci.c new file mode 100644 index 00000000000..620fc51c0cf --- /dev/null +++ b/drivers/power_domain/power_domain_tisci.c @@ -0,0 +1,105 @@ +/* + * Copyright 2025 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(tisci_pd); + +#define DT_DRV_COMPAT ti_sci_pm_domain + +const struct device *dmsc = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(dmsc)); + +struct power_domain { + uint32_t devid; + bool mode; +}; + +static int tisci_power_domain_on(const struct power_domain *pd) +{ + int ret; + + if (pd->mode) { + ret = tisci_cmd_get_device_exclusive(dmsc, pd->devid); + } else { + ret = tisci_cmd_get_device(dmsc, pd->devid); + } + + if (ret) { + LOG_ERR("TISCI PM: get_device(%u) failed (%d)\n", pd->devid, ret); + } + + return ret; +} + +static int tisci_power_domain_off(const struct power_domain *pd) +{ + int ret = tisci_cmd_put_device(dmsc, pd->devid); + + if (ret) { + LOG_ERR("TISCI PM: put_device(%u) failed (%d)\n", pd->devid, ret); + } + + return ret; +} + +static int tisci_pd_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct power_domain *data = dev->config; + + LOG_DBG("TISCI PM action %d on devid %d, mode %d", action, data->devid, data->mode); + int ret; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = tisci_power_domain_on(data); + return ret; + case PM_DEVICE_ACTION_SUSPEND: + ret = tisci_power_domain_off(data); + return ret; + case PM_DEVICE_ACTION_TURN_ON: + return 0; + case PM_DEVICE_ACTION_TURN_OFF: + return 0; + default: + return -ENOTSUP; + } + + return 0; +} + +static int tisci_pd_init(const struct device *dev) +{ + int ret; + + if (dmsc == NULL) { + LOG_ERR("DMSC device not found"); + return -ENODEV; + } + + ret = pm_device_driver_init(dev, tisci_pd_pm_action); + if (ret < 0) { + LOG_ERR("Failed to enable runtime PM: %d", ret); + return ret; + } + + return 0; +} + +#define TISCI_PD_DEVICE_DEFINE(inst) \ + static struct power_domain power_domain_data_##inst = { \ + .devid = DT_INST_PROP(inst, tisci_device_id), \ + .mode = DT_INST_ENUM_IDX(inst, tisci_device_mode), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(inst, tisci_pd_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, tisci_pd_init, PM_DEVICE_DT_INST_GET(inst), NULL, \ + &power_domain_data_##inst, PRE_KERNEL_1, \ + CONFIG_POWER_DOMAIN_TISCI_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(TISCI_PD_DEVICE_DEFINE); diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index 6a106c12841..f9941bcd069 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 46c5a8b83d2..3f632e0b828 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(_CONCAT_3(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_dw.c b/drivers/spi/spi_dw.c index 6941bfdaaa7..9b33bff3c2a 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -45,10 +45,6 @@ LOG_MODULE_REGISTER(spi_dw); #include #endif -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif - static inline bool spi_dw_is_slave(struct spi_dw_data *spi) { return (IS_ENABLED(CONFIG_SPI_SLAVE) && @@ -576,13 +572,6 @@ int spi_dw_init(const struct device *dev) #ifdef CONFIG_HAS_NRFX NRF_EXMIF->INTENSET = BIT(0); NRF_EXMIF->TASKS_START = 1; - -#ifdef CONFIG_SOC_NRF54H20_GPD - err = nrf_gpd_request(NRF_GPD_FAST_ACTIVE1); - if (err < 0) { - return err; - } -#endif #endif info->config_func(); diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index a5c4e30f190..6f393deff2b 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(_CONCAT_3(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; @@ -161,7 +182,7 @@ static inline void finalize_spi_transaction(const struct device *dev, bool deact nrfy_spim_disable(reg); } - if (!IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + if (!pm_device_runtime_is_enabled(dev)) { release_clock(dev); } @@ -550,7 +571,7 @@ static int transceive(const struct device *dev, error = configure(dev, spi_cfg); - if (error == 0 && !IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + if (error == 0 && !pm_device_runtime_is_enabled(dev)) { error = request_clock(dev); } @@ -682,11 +703,7 @@ 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 IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) ? request_clock(dev) : 0; + return pm_device_runtime_is_enabled(dev) ? request_clock(dev) : 0; } static void spim_suspend(const struct device *dev) @@ -699,16 +716,12 @@ static void spim_suspend(const struct device *dev) dev_data->initialized = false; } - if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + if (pm_device_runtime_is_enabled(dev)) { release_clock(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)), \ - (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ +#define SPIM_INIT_PRIORITY(idx) \ + COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \ + (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \ (CONFIG_SPI_INIT_PRIORITY)) -#else -#define SPIM_INIT_PRIORITY(idx) CONFIG_SPI_INIT_PRIORITY -#endif #define SPI_NRFX_SPIM_DEFINE(idx) \ NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ @@ -880,10 +875,8 @@ 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 +903,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 ceb479c0441..66994956e53 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 c56df42ddd5..9e790656e50 100644 --- a/dts/arm/nordic/nrf54h20_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54h20_cpuapp.dtsi @@ -59,3 +59,63 @@ wdt011: &cpuapp_wdt011 {}; &grtc { interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>; }; + +&fll16m { + status = "okay"; +}; + +&hsfll120 { + status = "okay"; +}; + +&lfclk { + status = "okay"; +}; + +&gdpwr { + status = "okay"; +}; + +&gdpwr_fast_active_0 { + status = "okay"; +}; + +&gdpwr_fast_active_1 { + status = "okay"; +}; + +&gdpwr_fast_main { + status = "okay"; +}; + +&gdpwr_slow_active { + status = "okay"; +}; + +&gdpwr_slow_main { + status = "okay"; +}; + +&gpio_pad_group0 { + status = "okay"; +}; + +&gpio_pad_group1 { + status = "okay"; +}; + +&gpio_pad_group2 { + status = "okay"; +}; + +&gpio_pad_group6 { + status = "okay"; +}; + +&gpio_pad_group7 { + status = "okay"; +}; + +&gpio_pad_group9 { + status = "okay"; +}; diff --git a/dts/arm/nordic/nrf54h20_cpurad.dtsi b/dts/arm/nordic/nrf54h20_cpurad.dtsi index e8ff2dac3a4..8bd3c045906 100644 --- a/dts/arm/nordic/nrf54h20_cpurad.dtsi +++ b/dts/arm/nordic/nrf54h20_cpurad.dtsi @@ -104,6 +104,66 @@ wdt011: &cpurad_wdt011 {}; 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"; +}; + &bt_hci_sdc { status = "okay"; }; diff --git a/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml b/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml new file mode 100644 index 00000000000..104277addd3 --- /dev/null +++ b/dts/bindings/gpio/nordic,nrf-gpio-pad-group.yaml @@ -0,0 +1,43 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic nRF GPIO pad group. + + The GPIO pad group describes the pads (package + pins of the SoC) the GPIO controller manages. + + The pads may be in a different power domain than + the GPIO controller, and may require enabling + retention to preserve the GPIO configuration if + the power domain is suspended. + + The GPIO pad group is a child node of the GPIO + controller which manages the pad group, named + pad-group. The pad group's nodelabel is named + gpio_pad_group. + + Example layout: + + gpio0: gpio@938000 { + compatible = "nordic,nrf-gpio"; + + ... + + gpio_pad_group0: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + }; + }; + +compatible: "nordic,nrf-gpio-pad-group" + +include: base.yaml + +properties: + retain-mask: + type: int + description: | + Mask of pins which shall be retained if pad + group's power domain is powered off. diff --git a/dts/bindings/power-domain/nordic,nrfs-gdpwr.yaml b/dts/bindings/power-domain/nordic,nrfs-gdpwr.yaml new file mode 100644 index 00000000000..916db56f475 --- /dev/null +++ b/dts/bindings/power-domain/nordic,nrfs-gdpwr.yaml @@ -0,0 +1,65 @@ +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic NRFS Global Domain Power Request + + The NRFS Global Domain Power Request service manages + global power domains using NRFS. + + Each child node represents a global power domain, mapped + by name. The fast-active-0 child node is mapped to the + FAST_ACTIVE_0 global power domain. The nodelabel of each + child node is the node name prepended with "gdpwr", + using underscores. + + Example layout: + + gdpwr { + compatible = "nordic,nrfs-gdpwr"; + status = "disabled"; + + gdpwr_fast_active_0: fast-active-0 { + #power-domain-cells = <0>; + }; + + gdpwr_fast_active_1: fast-active-1 { + #power-domain-cells = <0>; + }; + + gdpwr_fast_main: fast-main { + #power-domain-cells = <0>; + }; + + gdpwr_slow_active: slow-active { + #power-domain-cells = <0>; + }; + + gdpwr_slow_main: slow-main { + #power-domain-cells = <0>; + }; + }; + + Example usage: + + uart120: uart@8e6000 { + compatible = "nordic,nrf-uarte"; + reg = <0x8e6000 0x1000>; + status = "disabled"; + power-domains = <&gdpwr_fast_active_1>; + }; + +compatible: "nordic,nrfs-gdpwr" + +include: base.yaml + +child-binding: + description: Nordic NRFS Global Power Domain + + properties: + "#power-domain-cells": + type: int + const: 0 + + zephyr,pm-device-runtime-auto: + type: boolean diff --git a/dts/bindings/power-domain/nordic,nrfs-swext.yaml b/dts/bindings/power-domain/nordic,nrfs-swext.yaml new file mode 100644 index 00000000000..a504f4d97cd --- /dev/null +++ b/dts/bindings/power-domain/nordic,nrfs-swext.yaml @@ -0,0 +1,26 @@ +# Copyright 2025 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic NRFS SWEXT power domain + +compatible: "nordic,nrfs-swext" + +include: power-domain.yaml + +properties: + "#power-domain-cells": + const: 0 + + max-current-ua: + type: int + description: Maxmimum supported current in microamps. + required: true + + current-limit-ua: + type: int + description: Maxmimum allowed current in microamps. + required: true + + power-down-clamp: + type: boolean + description: Enable ground clamp on output when powered down. diff --git a/dts/bindings/power-domain/ti,sci-pm-domain.yaml b/dts/bindings/power-domain/ti,sci-pm-domain.yaml new file mode 100644 index 00000000000..5d19b31ef04 --- /dev/null +++ b/dts/bindings/power-domain/ti,sci-pm-domain.yaml @@ -0,0 +1,25 @@ +# Copyright 2025 Texas Instruments Incorporated +# SPDX-License-Identifier: Apache-2.0 + +description: TISCI-managed power domain + +compatible: "ti,sci-pm-domain" + +include: base.yaml + +properties: + tisci,device-id: + type: int + required: true + description: | + The device ID of the power domain as defined in the TISCI documentation. + tisci,device-mode: + type: string + required: true + enum: + - "SHARED" + - "EXCLUSIVE" + description: | + The device mode of the power domain as defined in the TISCI documentation. + "#power-domain-cells": + const: 0 diff --git a/dts/bindings/power/nordic,nrf-gpd.yaml b/dts/bindings/power/nordic,nrf-gpd.yaml deleted file mode 100644 index feb5f2862e9..00000000000 --- a/dts/bindings/power/nordic,nrf-gpd.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2024 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: Nordic nRF Global Power Domain - -compatible: "nordic,nrf-gpd" - -include: base.yaml - -power-domain-cells: - - id diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 27c3bc7192f..7d7811f4f79 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -14,7 +14,7 @@ #include #include #include -#include +#include /delete-node/ &sw_pwm; @@ -176,6 +176,7 @@ open-loop-startup-time-us = <200>; /* To be measured */ clocks = <&hfxo>, <&lfxo>; clock-names = "hfxo", "lfxo"; + status = "disabled"; }; hsfll120: hsfll120 { @@ -187,6 +188,7 @@ 128000000 256000000 320000000>; + status = "disabled"; }; lfclk: lfclk { @@ -200,6 +202,7 @@ lflprc-startup-time-us = <200>; /* To be measured */ clocks = <&hfxo>, <&lfxo>; clock-names = "hfxo", "lfxo"; + status = "disabled"; }; audiopll: audiopll { @@ -209,9 +212,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 { @@ -221,7 +263,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>; }; @@ -510,7 +552,7 @@ reg = <0x86000 0x1000>, <0x2f700000 0x40000>; reg-names = "wrapper", "core"; interrupts = <134 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; num-in-eps = <8>; num-out-eps = <10>; ghwcfg1 = <0xaa555000>; @@ -526,7 +568,7 @@ reg = <0x95000 0x500 0x95500 0xb00>; reg-names = "wrapper", "core"; interrupts = <149 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; clock-frequency = ; fifo-depth = <32>; status = "disabled"; @@ -535,21 +577,21 @@ cpusec_bellboard: mailbox@99000 { reg = <0x99000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; #mbox-cells = <1>; }; cpuapp_bellboard: mailbox@9a000 { reg = <0x9a000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; #mbox-cells = <1>; }; cpurad_bellboard: mailbox@9b000 { reg = <0x9b000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE0>; + power-domains = <&gdpwr_fast_active_0>; #mbox-cells = <1>; }; @@ -590,7 +632,7 @@ compatible = "nordic,nrf-vpr-coprocessor"; reg = <0x8d4000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x8d4000 0x1000>; @@ -612,7 +654,7 @@ interrupts = <216 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&canpll>, <&hsfll120>; clock-names = "auxpll", "hsfll"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; status = "disabled"; }; @@ -621,7 +663,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x8e1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; }; timer120: timer@8e2000 { @@ -630,7 +672,7 @@ status = "disabled"; cc-num = <6>; interrupts = <226 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; max-bit-width = <32>; clocks = <&hsfll120>; prescaler = <0>; @@ -642,7 +684,7 @@ status = "disabled"; cc-num = <6>; interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; max-bit-width = <32>; clocks = <&hsfll120>; prescaler = <0>; @@ -654,7 +696,7 @@ status = "disabled"; interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; #pwm-cells = <3>; idleout-supported; }; @@ -663,7 +705,7 @@ compatible = "nordic,nrf-spis"; reg = <0x8e5000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; easydma-maxcnt-bits = <15>; interrupts = <229 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; @@ -677,7 +719,7 @@ compatible = "nordic,nrf-spim"; reg = <0x8e6000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; easydma-maxcnt-bits = <15>; interrupts = <230 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; @@ -695,7 +737,7 @@ status = "disabled"; interrupts = <230 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; endtx-stoptx-supported; frame-timeout-supported; }; @@ -707,7 +749,7 @@ easydma-maxcnt-bits = <15>; interrupts = <231 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&hsfll120>; - power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; + power-domains = <&gdpwr_fast_active_1>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -723,7 +765,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x908000 0x1000>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; cpuppr_vevif_tx: mailbox@0 { compatible = "nordic,nrf-vevif-task-tx"; @@ -739,7 +781,7 @@ compatible = "nordic,nrf-ipct-global"; reg = <0x921000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; channels = <8>; global-domain-id = <13>; }; @@ -748,7 +790,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x922000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; rtc130: rtc@928000 { @@ -758,7 +800,7 @@ cc-num = <4>; clock-frequency = <32768>; interrupts = <296 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; clocks = <&lfclk>; prescaler = <1>; }; @@ -770,7 +812,7 @@ cc-num = <4>; clock-frequency = <32768>; interrupts = <297 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; clocks = <&lfclk>; prescaler = <1>; }; @@ -781,7 +823,7 @@ status = "disabled"; interrupts = <299 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&lfclk>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; wdt132: watchdog@92c000 { @@ -790,7 +832,7 @@ status = "disabled"; interrupts = <300 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&lfclk>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; egu130: egu@92d000 { @@ -798,14 +840,14 @@ reg = <0x92d000 0x1000>; status = "disabled"; interrupts = <301 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; }; gpiote130: gpiote@934000 { compatible = "nordic,nrf-gpiote"; reg = <0x934000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; instance = <130>; }; @@ -815,10 +857,19 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <12>; port = <0>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group0: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio1: gpio@938200 { @@ -827,10 +878,19 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <12>; port = <1>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group1: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio2: gpio@938400 { @@ -839,10 +899,19 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <12>; port = <2>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group2: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0xFFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio6: gpio@938c00 { @@ -851,11 +920,18 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>, - <&gpd NRF_GPD_FAST_ACTIVE1>; - power-domain-names = "peripheral", "pad"; + power-domains = <&gdpwr_slow_main>; ngpios = <14>; port = <6>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group6: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_fast_active_1>; + retain-mask = <0x3FFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio7: gpio@938e00 { @@ -864,11 +940,18 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>, - <&gpd NRF_GPD_FAST_ACTIVE1>; - power-domain-names = "peripheral", "pad"; + power-domains = <&gdpwr_slow_main>; ngpios = <8>; port = <7>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group7: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_fast_active_1>; + retain-mask = <0xFF>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; gpio9: gpio@939200 { @@ -877,17 +960,26 @@ status = "disabled"; #gpio-cells = <2>; gpio-controller; - power-domains = <&gpd NRF_GPD_SLOW_MAIN>; + power-domains = <&gdpwr_slow_main>; gpiote-instance = <&gpiote130>; ngpios = <6>; port = <9>; + zephyr,pm-device-runtime-auto; + + gpio_pad_group9: pad-group { + compatible = "nordic,nrf-gpio-pad-group"; + power-domains = <&gdpwr_slow_main>; + retain-mask = <0x3F>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; }; dppic131: dppic@981000 { compatible = "nordic,nrf-dppic-global"; reg = <0x981000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; adc: adc@982000 { @@ -896,7 +988,7 @@ interrupts = <386 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; zephyr,pm-device-runtime-auto; }; @@ -909,7 +1001,7 @@ reg = <0x983000 0x1000>; status = "disabled"; interrupts = <387 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; temp: temperature-sensor@984000 { @@ -917,7 +1009,7 @@ reg = <0x984000 0x1000>; interrupts = <388 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; nfct: nfct@985000 { @@ -925,14 +1017,14 @@ reg = <0x985000 0x1000>; status = "disabled"; interrupts = <389 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; dppic132: dppic@991000 { compatible = "nordic,nrf-dppic-global"; reg = <0x991000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; pdm0: pdm@993000 { @@ -941,7 +1033,7 @@ status = "disabled"; interrupts = <403 NRF_DEFAULT_IRQ_PRIORITY>; nordic,clockpin-enable = ; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; qdec130: qdec@994000 { @@ -949,7 +1041,7 @@ reg = <0x994000 0x1000>; status = "disabled"; interrupts = <404 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; qdec131: qdec@995000 { @@ -957,7 +1049,7 @@ reg = <0x995000 0x1000>; status = "disabled"; interrupts = <405 NRF_DEFAULT_IRQ_PRIORITY>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; grtc: grtc@99c000 { @@ -967,14 +1059,14 @@ cc-num = <16>; clocks = <&lfclk>, <&fll16m>; clock-names = "lfclock", "hfclock"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; dppic133: dppic@9a1000 { compatible = "nordic,nrf-dppic-global"; reg = <0x9a1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer130: timer@9a2000 { @@ -984,7 +1076,7 @@ cc-num = <6>; interrupts = <418 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -996,7 +1088,7 @@ cc-num = <6>; interrupts = <419 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1007,7 +1099,7 @@ status = "disabled"; interrupts = <420 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; #pwm-cells = <3>; idleout-supported; }; @@ -1018,7 +1110,7 @@ status = "disabled"; interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1034,7 +1126,7 @@ easydma-maxcnt-bits = <15>; interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1052,7 +1144,7 @@ status = "disabled"; interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1064,7 +1156,7 @@ status = "disabled"; interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1080,7 +1172,7 @@ easydma-maxcnt-bits = <15>; interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1098,17 +1190,18 @@ status = "disabled"; interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; + zephyr,pm-device-runtime-auto; }; dppic134: dppic@9b1000 { compatible = "nordic,nrf-dppic-global"; reg = <0x9b1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer132: timer@9b2000 { @@ -1118,7 +1211,7 @@ cc-num = <6>; interrupts = <434 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1130,7 +1223,7 @@ cc-num = <6>; interrupts = <435 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1141,7 +1234,7 @@ status = "disabled"; interrupts = <436 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; #pwm-cells = <3>; idleout-supported; }; @@ -1152,7 +1245,7 @@ status = "disabled"; interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1168,7 +1261,7 @@ easydma-maxcnt-bits = <15>; interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1186,7 +1279,7 @@ status = "disabled"; interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1198,7 +1291,7 @@ status = "disabled"; interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1214,7 +1307,7 @@ easydma-maxcnt-bits = <15>; interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1232,7 +1325,7 @@ status = "disabled"; interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1242,7 +1335,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x9c1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer134: timer@9c2000 { @@ -1252,7 +1345,7 @@ cc-num = <6>; interrupts = <450 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1264,7 +1357,7 @@ cc-num = <6>; interrupts = <451 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1276,7 +1369,7 @@ interrupts = <452 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; #pwm-cells = <3>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; idleout-supported; }; @@ -1286,7 +1379,7 @@ status = "disabled"; interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1302,7 +1395,7 @@ easydma-maxcnt-bits = <15>; interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1320,7 +1413,7 @@ status = "disabled"; interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1332,7 +1425,7 @@ status = "disabled"; interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1348,7 +1441,7 @@ easydma-maxcnt-bits = <15>; interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1366,7 +1459,7 @@ status = "disabled"; interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1376,7 +1469,7 @@ compatible = "nordic,nrf-dppic-global"; reg = <0x9d1000 0x1000>; status = "disabled"; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; }; timer136: timer@9d2000 { @@ -1386,7 +1479,7 @@ cc-num = <6>; interrupts = <466 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1398,7 +1491,7 @@ cc-num = <6>; interrupts = <467 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-bit-width = <32>; prescaler = <0>; }; @@ -1410,7 +1503,7 @@ interrupts = <468 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; #pwm-cells = <3>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; idleout-supported; }; @@ -1420,7 +1513,7 @@ status = "disabled"; interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1436,7 +1529,7 @@ easydma-maxcnt-bits = <15>; interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1454,10 +1547,11 @@ status = "disabled"; interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; + zephyr,pm-device-runtime-auto; }; i2c137: i2c@9d6000 { @@ -1466,7 +1560,7 @@ status = "disabled"; interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; easydma-maxcnt-bits = <15>; #address-cells = <1>; #size-cells = <0>; @@ -1482,7 +1576,7 @@ easydma-maxcnt-bits = <15>; interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -1500,7 +1594,7 @@ status = "disabled"; interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = ; endtx-stoptx-supported; frame-timeout-supported; @@ -1515,7 +1609,7 @@ interrupts = <402 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = , ; }; @@ -1529,7 +1623,7 @@ interrupts = <407 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; clocks = <&fll16m>; - power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + power-domains = <&gdpwr_slow_active>; nordic,clockpin-enable = , ; }; diff --git a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h b/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h deleted file mode 100644 index e4a5b83a304..00000000000 --- a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - - -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD -#define ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD - -/* numbers aligned to nrfs service identifiers */ -#define NRF_GPD_FAST_ACTIVE0 0U -#define NRF_GPD_FAST_ACTIVE1 1U -#define NRF_GPD_FAST_MAIN 2U -#define NRF_GPD_SLOW_ACTIVE 3U -#define NRF_GPD_SLOW_MAIN 4U - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD */ diff --git a/soc/nordic/common/pinctrl_soc.h b/soc/nordic/common/pinctrl_soc.h index f1d3b6357f9..e822fd40c6f 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. * @@ -81,9 +70,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. @@ -111,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. * @@ -154,6 +133,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 dd6fb8866bf..9d7aae2d469 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/CMakeLists.txt b/soc/nordic/nrf54h/CMakeLists.txt index a7deb7d66de..5de493c61f9 100644 --- a/soc/nordic/nrf54h/CMakeLists.txt +++ b/soc/nordic/nrf54h/CMakeLists.txt @@ -18,4 +18,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/Kconfig b/soc/nordic/nrf54h/Kconfig index 56b64f293ba..6663fcbb865 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -106,4 +106,3 @@ config SOC_NRF54H20_CPUFLPR select RISCV_CORE_NORDIC_VPR rsource "bicr/Kconfig" -rsource "gpd/Kconfig" diff --git a/soc/nordic/nrf54h/Kconfig.defconfig b/soc/nordic/nrf54h/Kconfig.defconfig index 486343a78ab..b11dcd9916c 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig +++ b/soc/nordic/nrf54h/Kconfig.defconfig @@ -35,11 +35,18 @@ config SPI_DW_HSSI config SPI_DW_ACCESS_WORD_ONLY default y if SPI_DW -config PM_DEVICE_POWER_DOMAIN - default n if PM_DEVICE +if PM_DEVICE config PM_DEVICE_RUNTIME - default y if PM_DEVICE + default y + +config DEVICE_DEPS + default y + +config PM_DEVICE_POWER_DOMAIN + default y + +endif # PM_DEVICE config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,grtc,clock-frequency) if NRF_GRTC_TIMER diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp index 69bde826ba4..0cdc2276040 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -11,4 +11,7 @@ config NUM_IRQS config SHELL_BACKEND_SERIAL default n if NRF_ETR_SHELL +config POWER_DOMAIN + default y + endif # SOC_NRF54H20_CPUAPP diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad index 8f86835b92c..b3f5216c8f9 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -11,4 +11,7 @@ config NUM_IRQS config PM default y +config POWER_DOMAIN + default y + endif # SOC_NRF54H20_CPURAD diff --git a/soc/nordic/nrf54h/gpd/CMakeLists.txt b/soc/nordic/nrf54h/gpd/CMakeLists.txt deleted file mode 100644 index 7d029d2c8fc..00000000000 --- a/soc/nordic/nrf54h/gpd/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library_sources_ifdef(CONFIG_SOC_NRF54H20_GPD gpd.c) -zephyr_include_directories(include) diff --git a/soc/nordic/nrf54h/gpd/Kconfig b/soc/nordic/nrf54h/gpd/Kconfig deleted file mode 100644 index d9b696b82c7..00000000000 --- a/soc/nordic/nrf54h/gpd/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -config SOC_NRF54H20_GPD - bool "Global Power Domain service" - imply NRFS - imply NRFS_GDPWR_SERVICE_ENABLED - select ONOFF - select PINCTRL - default y if !MCUBOOT && (SOC_NRF54H20_CPUAPP || SOC_NRF54H20_CPURAD) - help - This option enables the Global Power Domain service. diff --git a/soc/nordic/nrf54h/gpd/gpd.c b/soc/nordic/nrf54h/gpd/gpd.c deleted file mode 100644 index 5e5f0b2dae1..00000000000 --- a/soc/nordic/nrf54h/gpd/gpd.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -LOG_MODULE_REGISTER(gpd, CONFIG_SOC_LOG_LEVEL); - -/* enforce alignment between DT<->nrfs */ -BUILD_ASSERT(GDPWR_GD_FAST_ACTIVE_0 == NRF_GPD_FAST_ACTIVE0); -BUILD_ASSERT(GDPWR_GD_FAST_ACTIVE_1 == NRF_GPD_FAST_ACTIVE1); -BUILD_ASSERT(GDPWR_GD_FAST_MAIN == NRF_GPD_FAST_MAIN); -BUILD_ASSERT(GDPWR_GD_SLOW_ACTIVE == NRF_GPD_SLOW_ACTIVE); -BUILD_ASSERT(GDPWR_GD_SLOW_MAIN == NRF_GPD_SLOW_MAIN); - -struct gpd_onoff_manager { - struct onoff_manager mgr; - onoff_notify_fn notify; - uint8_t id; - struct k_mutex lock; - struct k_sem sem; - int res; -}; - -static void start(struct onoff_manager *mgr, onoff_notify_fn notify); -static void stop(struct onoff_manager *mgr, onoff_notify_fn notify); - -#define GPD_READY_TIMEOUT_MS 1000 - -#define GPD_SERVICE_READY BIT(0) -#define GPD_SERVICE_ERROR BIT(1) -#define GPD_SERVICE_REQ_OK BIT(2) -#define GPD_SERVICE_REQ_ERR BIT(3) -static atomic_t gpd_service_status = ATOMIC_INIT(0); - -static struct gpd_onoff_manager fast_active0 = { - .id = NRF_GPD_FAST_ACTIVE0, - .lock = Z_MUTEX_INITIALIZER(fast_active0.lock), - .sem = Z_SEM_INITIALIZER(fast_active0.sem, 0, 1), -}; -static struct gpd_onoff_manager fast_active1 = { - .id = NRF_GPD_FAST_ACTIVE1, - .lock = Z_MUTEX_INITIALIZER(fast_active1.lock), - .sem = Z_SEM_INITIALIZER(fast_active1.sem, 0, 1), -}; -static struct gpd_onoff_manager fast_main = { - .id = NRF_GPD_FAST_MAIN, - .lock = Z_MUTEX_INITIALIZER(fast_main.lock), - .sem = Z_SEM_INITIALIZER(fast_main.sem, 0, 1), -}; -static struct gpd_onoff_manager slow_active = { - .id = NRF_GPD_SLOW_ACTIVE, - .lock = Z_MUTEX_INITIALIZER(slow_active.lock), - .sem = Z_SEM_INITIALIZER(slow_active.sem, 0, 1), -}; -static struct gpd_onoff_manager slow_main = { - .id = NRF_GPD_SLOW_MAIN, - .lock = Z_MUTEX_INITIALIZER(slow_main.lock), - .sem = Z_SEM_INITIALIZER(slow_main.sem, 0, 1), -}; - -static const struct onoff_transitions transitions = - ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL); - -static struct gpd_onoff_manager *get_mgr(uint8_t id) -{ - switch (id) { - case NRF_GPD_FAST_ACTIVE0: - return &fast_active0; - case NRF_GPD_FAST_ACTIVE1: - return &fast_active1; - case NRF_GPD_FAST_MAIN: - return &fast_main; - case NRF_GPD_SLOW_ACTIVE: - return &slow_active; - case NRF_GPD_SLOW_MAIN: - return &slow_main; - default: - return NULL; - } -} - -static void request_cb(struct onoff_manager *mgr_, struct onoff_client *cli, uint32_t state, - int res) -{ - ARG_UNUSED(cli); - ARG_UNUSED(state); - - struct gpd_onoff_manager *gpd_mgr = CONTAINER_OF(mgr_, struct gpd_onoff_manager, mgr); - - gpd_mgr->res = res; - k_sem_give(&gpd_mgr->sem); -} - -static int nrf_gpd_sync(struct gpd_onoff_manager *gpd_mgr) -{ - int64_t start; - nrfs_err_t err; - k_spinlock_key_t key; - gdpwr_request_type_t request; - - key = k_spin_lock(&gpd_mgr->mgr.lock); - - if (gpd_mgr->mgr.refs == 0) { - request = GDPWR_POWER_REQUEST_CLEAR; - } else { - request = GDPWR_POWER_REQUEST_SET; - } - - k_spin_unlock(&gpd_mgr->mgr.lock, key); - - atomic_clear_bit(&gpd_service_status, GPD_SERVICE_REQ_ERR); - atomic_clear_bit(&gpd_service_status, GPD_SERVICE_REQ_OK); - - err = nrfs_gdpwr_power_request(gpd_mgr->id, request, gpd_mgr); - if (err != NRFS_SUCCESS) { - return -EIO; - } - - start = k_uptime_get(); - while (k_uptime_get() - start < GPD_READY_TIMEOUT_MS) { - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_REQ_ERR)) { - return -EIO; - } - - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_REQ_OK)) { - return 0; - } - - k_yield(); - } - - LOG_ERR("nRFs GDPWR request timed out"); - - return -ETIMEDOUT; -} - -static void evt_handler(nrfs_gdpwr_evt_t const *p_evt, void *context) -{ - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_READY)) { - struct gpd_onoff_manager *gpd_mgr = context; - - switch (p_evt->type) { - case NRFS_GDPWR_REQ_APPLIED: - gpd_mgr->notify(&gpd_mgr->mgr, 0); - break; - default: - LOG_ERR("nRFs GDPWR request not applied"); - gpd_mgr->notify(&gpd_mgr->mgr, -EIO); - break; - } - } else { - switch (p_evt->type) { - case NRFS_GDPWR_REQ_APPLIED: - atomic_set_bit(&gpd_service_status, GPD_SERVICE_REQ_OK); - break; - default: - LOG_ERR("nRFs GDPWR request not applied"); - atomic_set_bit(&gpd_service_status, GPD_SERVICE_REQ_ERR); - break; - } - } -} - -static void start(struct onoff_manager *mgr, onoff_notify_fn notify) -{ - struct gpd_onoff_manager *gpd_mgr = CONTAINER_OF(mgr, struct gpd_onoff_manager, mgr); - - gpd_mgr->notify = notify; - - if (!atomic_test_bit(&gpd_service_status, GPD_SERVICE_READY)) { - notify(mgr, 0); - } else { - nrfs_err_t err; - - err = nrfs_gdpwr_power_request(gpd_mgr->id, GDPWR_POWER_REQUEST_SET, gpd_mgr); - if (err != NRFS_SUCCESS) { - LOG_ERR("nRFs GDPWR request failed (%d)", err); - notify(mgr, -EIO); - } - } -} - -static void stop(struct onoff_manager *mgr, onoff_notify_fn notify) -{ - struct gpd_onoff_manager *gpd_mgr = CONTAINER_OF(mgr, struct gpd_onoff_manager, mgr); - - gpd_mgr->notify = notify; - - if (!atomic_test_bit(&gpd_service_status, GPD_SERVICE_READY)) { - notify(mgr, 0); - } else { - nrfs_err_t err; - - err = nrfs_gdpwr_power_request(gpd_mgr->id, GDPWR_POWER_REQUEST_CLEAR, gpd_mgr); - if (err != NRFS_SUCCESS) { - LOG_ERR("nRFs GDPWR request failed (%d)", err); - notify(mgr, -EIO); - } - } -} - -int nrf_gpd_request(uint8_t id) -{ - int ret; - struct onoff_client client; - struct gpd_onoff_manager *gpd_mgr; - - gpd_mgr = get_mgr(id); - if (gpd_mgr == NULL) { - return -EINVAL; - } - - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_ERROR)) { - LOG_ERR("GPD service did not initialize properly"); - return -EIO; - } - - if (k_is_pre_kernel()) { - sys_notify_init_spinwait(&client.notify); - - ret = onoff_request(&gpd_mgr->mgr, &client); - if (ret < 0) { - return ret; - } - - while (sys_notify_fetch_result(&client.notify, &ret) == -EAGAIN) { - } - } else { - sys_notify_init_callback(&client.notify, request_cb); - k_mutex_lock(&gpd_mgr->lock, K_FOREVER); - - ret = onoff_request(&gpd_mgr->mgr, &client); - if (ret >= 0) { - (void)k_sem_take(&gpd_mgr->sem, K_FOREVER); - ret = gpd_mgr->res; - } - - k_mutex_unlock(&gpd_mgr->lock); - } - - return ret; -} - -int nrf_gpd_release(uint8_t id) -{ - struct gpd_onoff_manager *gpd_mgr; - - gpd_mgr = get_mgr(id); - if (gpd_mgr == NULL) { - return -EINVAL; - } - - if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_ERROR)) { - LOG_ERR("GPD service did not initialize properly"); - return -EIO; - } - - return onoff_release(&gpd_mgr->mgr); -} - -int nrf_gpd_retain_pins_set(const struct pinctrl_dev_config *pcfg, bool retain) -{ - const struct pinctrl_state *state; - int ret; - - ret = pinctrl_lookup_state(pcfg, PINCTRL_STATE_DEFAULT, &state); - if (ret < 0) { - return ret; - } - - for (uint8_t i = 0U; i < state->pin_cnt; i++) { - uint32_t pin = NRF_GET_PIN(state->pins[i]); - - if (pin == NRF_PIN_DISCONNECTED) { - continue; - } - - if (retain) { - nrf_gpio_pin_retain_enable(pin); - } else { - nrf_gpio_pin_retain_disable(pin); - } - } - - return 0; -} - -static int nrf_gpd_pre_init(void) -{ - int ret; - - ret = onoff_manager_init(&fast_active0.mgr, &transitions); - if (ret < 0) { - return ret; - } - - ret = onoff_manager_init(&fast_active1.mgr, &transitions); - if (ret < 0) { - return ret; - } - - ret = onoff_manager_init(&fast_main.mgr, &transitions); - if (ret < 0) { - return ret; - } - - ret = onoff_manager_init(&slow_active.mgr, &transitions); - if (ret < 0) { - return ret; - } - - ret = onoff_manager_init(&slow_main.mgr, &transitions); - if (ret < 0) { - return ret; - } - - return 0; -} - -static int nrf_gpd_post_init(void) -{ - nrfs_err_t err; - int ret; - - err = nrfs_backend_wait_for_connection(K_FOREVER); - if (err != NRFS_SUCCESS) { - ret = -EIO; - goto err; - } - - err = nrfs_gdpwr_init(evt_handler); - if (err != NRFS_SUCCESS) { - ret = -EIO; - goto err; - } - - /* submit GD requests now to align collected statuses */ - ret = nrf_gpd_sync(&fast_active0); - if (ret < 0) { - goto err; - } - - ret = nrf_gpd_sync(&fast_active1); - if (ret < 0) { - goto err; - } - - ret = nrf_gpd_sync(&fast_main); - if (ret < 0) { - goto err; - } - - ret = nrf_gpd_sync(&slow_active); - if (ret < 0) { - goto err; - } - - ret = nrf_gpd_sync(&slow_main); - if (ret < 0) { - goto err; - } - - atomic_set_bit(&gpd_service_status, GPD_SERVICE_READY); - - return 0; - -err: - atomic_set_bit(&gpd_service_status, GPD_SERVICE_ERROR); - - return ret; -} - -SYS_INIT(nrf_gpd_pre_init, PRE_KERNEL_1, 0); -SYS_INIT(nrf_gpd_post_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/soc/nordic/nrf54h/gpd/include/nrf/gpd.h b/soc/nordic/nrf54h/gpd/include/nrf/gpd.h deleted file mode 100644 index b8aab94accb..00000000000 --- a/soc/nordic/nrf54h/gpd/include/nrf/gpd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_NRF54H_GPD_INCLUDE_NRF_GPD_H_ -#define ZEPHYR_SOC_NORDIC_NRF54H_GPD_INCLUDE_NRF_GPD_H_ - -#include - -#include -#include - -/** - * @brief Request a global power domain. - * - * @param id Domain ID. - * - * @retval 0 If the request was successful. - * @retval -errno If the request was not successful. - */ -int nrf_gpd_request(uint8_t id); - -/** - * @brief Release a global power domain. - * - * @param id Domain ID. - * - * @retval 0 If the request was successful. - * @retval -errno If the request was not successful. - */ -int nrf_gpd_release(uint8_t id); - -/** - * @brief Retain set/clear a set of pins. - * - * @param pcfg Device pin configuration. - * @param retain Retain or not. - * - * @retval 0 If the request was successful. - * @retval -errno If the request was not successful. - */ -int nrf_gpd_retain_pins_set(const struct pinctrl_dev_config *pcfg, bool retain); - -#endif /* ZEPHYR_SOC_NORDIC_NRF54H_GPD_INCLUDE_NRF_GPD_H_ */ diff --git a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_interrupt/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf index 025c842f70b..a18a3b576e3 100644 --- a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpuapp.conf @@ -1,2 +1 @@ -CONFIG_SOC_NRF54H20_GPD=n CONFIG_SSF_CLIENT_SYS_INIT=n diff --git a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf index 025c842f70b..a18a3b576e3 100644 --- a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf @@ -1,2 +1 @@ -CONFIG_SOC_NRF54H20_GPD=n CONFIG_SSF_CLIENT_SYS_INIT=n diff --git a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/arch/arm/arm_thread_swap/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/threads/dynamic_thread_stack/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpuapp.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpuapp.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n diff --git a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf deleted file mode 100644 index 0bcc82e646b..00000000000 --- a/tests/kernel/usage/thread_runtime_stats/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SOC_NRF54H20_GPD=n