Skip to content

Conversation

bjarki-andreasen
Copy link
Contributor

@bjarki-andreasen bjarki-andreasen commented May 28, 2025

Replace highly coupled use of GPD (gpd.h) from device drivers, with power domain device drivers using zephyr's PM_DEVICE_POWER_DOMAIN infrastructure.

The gpd.h currently is used for two things:

  • Manually requests power domains like fast_active_main and slow_active_main on the H20
  • Manually applies pin state retention on individual pins, or pins found in a pinctrl config.

Nordic device drivers currently have to do this manually, conditionally, which is adding immense complexity to them, only relevant for certain SoCs, and which is in theory duplicate code. In reality, device drivers do their best, but since gpd is not well understood, device drivers implement it slightly differently, in some cases working by design, some cases working by accident, and in some cases working, but breaking something else.

No more!

Both pin retention and power domains are actually designed in a way that is entirely logical, and can be expressed using power domains and the devicetree. So, using pinctrl and power domains, we can entirely decouple devices from this complexity :)

What does the refactor do?

  1. Rework the nrfh54h power domains to match zephyr's power domains. This means every power domain is represented as a node, not an index in a phandle. This does two things, it allows us to use zephyr's power domain framework, and it stops our misuse of the base power-domains property from breaking user's applications if they "dare" to use zephyrs power domain framework. See first commit.
  2. Introduce the gpio pads to the devicetree. GPIO pads are the SoCs pins, which peripherals like UARTE or GPIO can be muxed to. These can be in different power domains than the peripheral connected to them, and they need to be retained if the power domain they are in may be shut down, which only happens if no peripheral, including GPIO, is active while muxed to any pad in that pad group (a pad group is 1-1 mapped to the GPIO controller, so GPIO0 will own pad group 0). See second commit.
  3. Refactor pinctrl and device drivers to use the new power domains, and remove all usage of gpd.h
  4. Remove gpd.h
  5. Success

Copy link
Contributor

@karstenkoenig karstenkoenig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't look at SWEXT changes, but the gpio port/pad power domain handling looks good.

Will this trigger more power domain requests/releases?

@bjarki-andreasen bjarki-andreasen force-pushed the nrfs-swext-pd branch 2 times, most recently from 95015ed to 1de2f64 Compare July 3, 2025 00:30
@bjarki-andreasen bjarki-andreasen added the platform: nRF Nordic nRFx label Jul 3, 2025
@bjarki-andreasen bjarki-andreasen force-pushed the nrfs-swext-pd branch 12 times, most recently from 3acab47 to 9163316 Compare July 14, 2025 12:49
@bjarki-andreasen bjarki-andreasen force-pushed the nrfs-swext-pd branch 2 times, most recently from 126e8cb to 3e4dca4 Compare July 14, 2025 16:00
@bjarki-andreasen bjarki-andreasen marked this pull request as ready for review July 14, 2025 17:12
@zephyrbot zephyrbot requested a review from ithinuel July 24, 2025 13:50
masz-nordic
masz-nordic previously approved these changes Jul 24, 2025
@bjarki-andreasen
Copy link
Contributor Author

Rebased to solve merge conflict

@bjarki-andreasen
Copy link
Contributor Author

ping @anangl @nika-nordic

masz-nordic
masz-nordic previously approved these changes Jul 25, 2025
@bjarki-andreasen
Copy link
Contributor Author

Rebased to include cross domain changes for SPI and UARTE

@bjarki-andreasen
Copy link
Contributor Author

ping @anangl

Introduce the NRFS GDPWR (Global Domain Power Request) device
driver and devicetree binding.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Comment on lines 16 to 18
controller which manages the the pad group,
named pad-group. The pad group's nodelabel is
named gpio_pad_group<GPIO number>.
controller which manages the pad group, named
pad-group. The pad group's nodelabel is named
gpio_pad_group<GPIO number>.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This correction should be done directly in the commit that introduces the binding.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

open-loop-startup-time-us = <200>; /* To be measured */
clocks = <&hfxo>, <&lfxo>;
clock-names = "hfxo", "lfxo";
status = "disabled";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it would be probably better to have this right after compatible, like in most of the other nodes here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

*
* @param pincfg Pin configuration bit field.
*/
#define NRF_GET_PORT_PIN(pincfg) (NRF_GET_PORT(pincfg) % 32)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define NRF_GET_PORT_PIN(pincfg) (NRF_GET_PORT(pincfg) % 32)
#define NRF_GET_PORT_PIN(pincfg) (NRF_GET_PIN(pincfg) & 0x1F)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 282 to 287
( \
IS_EQ( \
DT_DEP_ORD(DT_PHANDLE(node_id, power_domains)), \
DT_DEP_ORD(DT_NODELABEL(gdpwr_fast_active_1)) \
) \
), \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
( \
IS_EQ( \
DT_DEP_ORD(DT_PHANDLE(node_id, power_domains)), \
DT_DEP_ORD(DT_NODELABEL(gdpwr_fast_active_1)) \
) \
), \
(DT_SAME_NODE(DT_PHANDLE(node_id, power_domains), \
DT_NODELABEL(gdpwr_fast_active_1))), \

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not work, DT_SAME_NODE uses ==, it does not evaluate to 0 or 1 :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

#define DT_SAME_NODE(node_id1, node_id2) \
IS_EQ(DT_DEP_ORD(node_id1), DT_DEP_ORD(node_id2))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, this was fixed after I made the commit :D ba48d83

Comment on lines 104 to 106
compatible = "nordic,nrf-spim";
status = "okay";
def-char = <0x00>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? It's a SPIM, not SPIS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some driver needs def-char to be set, this was an attempt at trying to fix it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue was with SPIS_NODE macro which checked if an instance was FAST to determine if the nodelabel was spix or spisx, this can't be done since we need to know the nodelabel first, to be able to check if its fast or not, changed to just test if the nodelabel exists:

#define SPIS_NODE(idx) \
	COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(spis##idx)), (spis##idx), (spi##idx))

Comment on lines 251 to 257
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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this added intentionally?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It should have been removed as I dropped the swext commit :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

CONFIG_SPI_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY
#define SPIM_INIT_PRIORITY(idx) \
COND_CODE_1(SPIM_REQUESTS_CLOCK(SPIM(idx)), \
COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), \
COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Introduce the NRF GPIO Pad Group device driver and binding. The
pad group device represents the GPIO pads (pins), contrary to a
GPIO controller, which is one of the many devices which can be
muxed to pads in the pad group.

The pad group belong to a power domain, which is not neccesarily the
same power domain as devices being muxed to the pads, like GPIO or
UART. If no ACTIVE device is using any of the pads in the pad
group, the pad groups power domain may be SUSPENDED. Before the pad
groups power domain is SUSPENDED, pad config retention must be
enabled to prevent the pads from loosing their state. That's what
this device driver manages. Once retained, the pad configs and
outputs are locked, even when their power domain is SUSPENDED.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Transition nrf54h away from the soc specific gpd
(global power domain) driver which mixed power domains, pinctrl
and gpio pin retention into a non scalable solution, forcing soc
specific logic to bleed into nrf drivers.

The new solution uses zephyrs PM_DEVICE based power domains to
properly model the hardware layout of device and pin power domains,
and moves pin retention logic out of drivers into pinctrl and
gpio, which are the components which manage pins (pads).

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
@bjarki-andreasen bjarki-andreasen force-pushed the nrfs-swext-pd branch 2 times, most recently from e47f3a6 to 9d6df0d Compare July 29, 2025 10:10
Remove the deprecated GPD (Global Power Domain) driver.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
Copy link

@bjarki-andreasen
Copy link
Contributor Author

ping @masz-nordic

@cfriedt cfriedt merged commit 2854115 into zephyrproject-rtos:main Jul 29, 2025
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform: nRF Nordic nRFx

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants