Skip to content

Commit 87e9f3a

Browse files
soc: drivers: nrfx: replace nrf_gpd with gdpwr and pinctrl
The gdpwr power domain and pinctrl have been refactored to implement the required power domain and pin retention management for the nrf54h. the nrf_gpd vendor specific solution was misusing the reserved power-domains property which made it impossible to use zephyrs power domains with the 54h20, and it duplicated the logic of power domains using onoff managers. The new solution is transparent to device drivers, using the zephyr power management and pinctrl subsystems. Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
1 parent 350d66c commit 87e9f3a

File tree

20 files changed

+279
-670
lines changed

20 files changed

+279
-670
lines changed

drivers/can/can_nrf.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,6 @@ static int can_nrf_init(const struct device *dev)
187187
sys_write32(CAN_INTEN_CORE0_Msk | CAN_INTEN_CORE1_Msk, config->wrapper + CAN_INTEN);
188188
sys_write32(1U, config->wrapper + CAN_TASKS_START);
189189

190-
#ifdef CONFIG_SOC_NRF54H20_GPD
191-
ret = nrf_gpd_retain_pins_set(config->pcfg, false);
192-
if (ret < 0) {
193-
return ret;
194-
}
195-
#endif
196-
197190
config->irq_configure();
198191

199192
ret = can_mcan_configure_mram(dev, config->mrba, config->mram);

drivers/pinctrl/pinctrl_nrf.c

Lines changed: 133 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
*/
66

77
#include <zephyr/drivers/pinctrl.h>
8+
#include <zephyr/pm/device_runtime.h>
9+
#include <zephyr/sys/atomic.h>
810

911
#include <hal/nrf_gpio.h>
10-
#ifdef CONFIG_SOC_NRF54H20_GPD
11-
#include <nrf/gpd.h>
12-
#endif
1312

1413
BUILD_ASSERT(((NRF_PULL_NONE == NRF_GPIO_PIN_NOPULL) &&
1514
(NRF_PULL_DOWN == NRF_GPIO_PIN_PULLDOWN) &&
@@ -112,13 +111,131 @@ static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = {
112111
#define NRF_PSEL_TDM(reg, line) ((NRF_TDM_Type *)reg)->PSEL.line
113112
#endif
114113

115-
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
116-
uintptr_t reg)
114+
#define PORT_PD_EXISTS(node_id) \
115+
COND_CODE_1( \
116+
DT_NODE_EXISTS(node_id), \
117+
(DT_NODE_HAS_PROP(node_id, power_domains)), \
118+
(0) \
119+
)
120+
121+
#define PORT_PD_DEV_GET_OR_NULL(node_id) \
122+
COND_CODE_1( \
123+
DT_NODE_EXISTS(node_id), \
124+
(DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, power_domains))), \
125+
(NULL) \
126+
)
127+
128+
#define PORTS_HAVE_PD \
129+
PORT_PD_EXISTS(DT_NODELABEL(gpio0)) || \
130+
PORT_PD_EXISTS(DT_NODELABEL(gpio1)) || \
131+
PORT_PD_EXISTS(DT_NODELABEL(gpio2)) || \
132+
PORT_PD_EXISTS(DT_NODELABEL(gpio3)) || \
133+
PORT_PD_EXISTS(DT_NODELABEL(gpio4)) || \
134+
PORT_PD_EXISTS(DT_NODELABEL(gpio5)) || \
135+
PORT_PD_EXISTS(DT_NODELABEL(gpio6)) || \
136+
PORT_PD_EXISTS(DT_NODELABEL(gpio7)) || \
137+
PORT_PD_EXISTS(DT_NODELABEL(gpio8)) || \
138+
PORT_PD_EXISTS(DT_NODELABEL(gpio9))
139+
140+
#if PORTS_HAVE_PD
141+
142+
static const struct device *const port_pd_devs[] = {
143+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio0)),
144+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio1)),
145+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio2)),
146+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio3)),
147+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio4)),
148+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio5)),
149+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio6)),
150+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio7)),
151+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio8)),
152+
PORT_PD_DEV_GET_OR_NULL(DT_NODELABEL(gpio9)),
153+
};
154+
155+
static atomic_t port_pd_masks[ARRAY_SIZE(port_pd_devs)];
156+
157+
static int port_pd_request_pin(uint16_t pin_number)
158+
{
159+
uint8_t port_number = NRF_GET_PORT(pin_number);
160+
uint16_t port_pin_number = NRF_GET_PORT_PIN(pin_number);
161+
const struct device *port_pd_dev = port_pd_devs[port_number];
162+
atomic_t *port_pd_mask = &port_pd_masks[port_number];
163+
164+
if (atomic_test_and_set_bit(port_pd_mask, port_pin_number)) {
165+
/* already requested */
166+
return 0;
167+
}
168+
169+
if (pm_device_runtime_get(port_pd_dev)) {
170+
atomic_clear_bit(port_pd_mask, port_pin_number);
171+
return -EIO;
172+
}
173+
174+
/* power domain now active, retain can be disabled */
175+
nrf_gpio_pin_retain_disable(pin_number);
176+
return 0;
177+
}
178+
179+
static int port_pd_release_pin(uint16_t pin_number)
180+
{
181+
uint8_t port_number = NRF_GET_PORT(pin_number);
182+
uint16_t port_pin_number = NRF_GET_PORT_PIN(pin_number);
183+
const struct device *port_pd_dev = port_pd_devs[port_number];
184+
atomic_t *port_pd_mask = &port_pd_masks[port_number];
185+
186+
if (!atomic_test_and_clear_bit(port_pd_mask, port_pin_number)) {
187+
/* already released */
188+
return 0;
189+
}
190+
191+
/* power domain may become inactive, retain shall be enabled */
192+
nrf_gpio_pin_retain_enable(pin_number);
193+
194+
if (pm_device_runtime_put(port_pd_dev)) {
195+
nrf_gpio_pin_retain_disable(pin_number);
196+
atomic_set_bit(port_pd_mask, port_pin_number);
197+
return -EIO;
198+
}
199+
200+
return 0;
201+
}
202+
203+
#else
204+
205+
static int port_pd_request_pin(uint16_t pin_number)
117206
{
118-
#ifdef CONFIG_SOC_NRF54H20_GPD
119-
bool gpd_requested = false;
207+
ARG_UNUSED(pin_number);
208+
return 0;
209+
}
210+
211+
static int port_pd_release_pin(uint16_t pin_number)
212+
{
213+
ARG_UNUSED(pin_number);
214+
return 0;
215+
}
216+
120217
#endif
121218

219+
#if NRF_GPIO_HAS_CLOCKPIN
220+
221+
static void port_pin_clock_set(uint16_t pin_number, bool enable)
222+
{
223+
nrf_gpio_pin_clock_set(pin_number, enable);
224+
}
225+
226+
#else
227+
228+
static void port_pin_clock_set(uint16_t pin_number, bool enable)
229+
{
230+
ARG_UNUSED(pin_number);
231+
ARG_UNUSED(enable);
232+
}
233+
234+
#endif
235+
236+
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
237+
uintptr_t reg)
238+
{
122239
for (uint8_t i = 0U; i < pin_cnt; i++) {
123240
nrf_gpio_pin_drive_t drive;
124241
uint8_t drive_idx = NRF_GET_DRIVE(pins[i]);
@@ -472,21 +589,9 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
472589
if (psel != PSEL_DISCONNECTED) {
473590
uint32_t pin = psel;
474591

475-
#ifdef CONFIG_SOC_NRF54H20_GPD
476-
if (NRF_GET_GPD_FAST_ACTIVE1(pins[i]) == 1U) {
477-
if (!gpd_requested) {
478-
int ret;
479-
480-
ret = nrf_gpd_request(NRF_GPD_SLOW_ACTIVE);
481-
if (ret < 0) {
482-
return ret;
483-
}
484-
gpd_requested = true;
485-
}
486-
487-
nrf_gpio_pin_retain_disable(pin);
488-
}
489-
#endif /* CONFIG_SOC_NRF54H20_GPD */
592+
/* enable pin */
593+
port_pd_request_pin(pin);
594+
port_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i]));
490595

491596
if (write != NO_WRITE) {
492597
nrf_gpio_pin_write(pin, write);
@@ -498,29 +603,17 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
498603
input = NRF_GPIO_PIN_INPUT_DISCONNECT;
499604
}
500605

606+
/* configure pin */
501607
nrf_gpio_cfg(pin, dir, input, NRF_GET_PULL(pins[i]),
502608
drive, NRF_GPIO_PIN_NOSENSE);
503-
#if NRF_GPIO_HAS_CLOCKPIN
504-
nrf_gpio_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i]));
505-
#endif
506-
#ifdef CONFIG_SOC_NRF54H20_GPD
507-
if (NRF_GET_GPD_FAST_ACTIVE1(pins[i]) == 1U) {
508-
nrf_gpio_pin_retain_enable(pin);
509-
}
510-
#endif /* CONFIG_SOC_NRF54H20_GPD */
511-
}
512-
}
513-
514-
#ifdef CONFIG_SOC_NRF54H20_GPD
515-
if (gpd_requested) {
516-
int ret;
517609

518-
ret = nrf_gpd_release(NRF_GPD_SLOW_ACTIVE);
519-
if (ret < 0) {
520-
return ret;
610+
if (NRF_GET_LP(pins[i]) == NRF_LP_ENABLE) {
611+
/* disable pin */
612+
port_pd_release_pin(pin);
613+
port_pin_clock_set(pin, false);
614+
}
521615
}
522616
}
523-
#endif
524617

525618
return 0;
526619
}

drivers/pwm/pwm_nrfx.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,6 @@ static int pwm_resume(const struct device *dev)
383383

384384
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
385385

386-
#ifdef CONFIG_SOC_NRF54H20_GPD
387-
nrf_gpd_retain_pins_set(config->pcfg, false);
388-
#endif
389-
390386
for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) {
391387
uint32_t psel;
392388

@@ -423,10 +419,6 @@ static int pwm_suspend(const struct device *dev)
423419
while (!nrfx_pwm_stopped_check(&config->pwm)) {
424420
}
425421

426-
#ifdef CONFIG_SOC_NRF54H20_GPD
427-
nrf_gpd_retain_pins_set(config->pcfg, true);
428-
#endif
429-
430422
memset(dev->data, 0, sizeof(struct pwm_nrfx_data));
431423
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
432424

drivers/serial/uart_nrfx_uarte.c

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,8 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
122122
#include <nrf/gpd.h>
123123

124124
/* Macro must resolve to literal 0 or 1 */
125-
#define INSTANCE_IS_FAST_PD(unused, prefix, idx, _) \
126-
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \
127-
(COND_CODE_1(DT_NODE_HAS_PROP(UARTE(idx), power_domains), \
128-
(IS_EQ(DT_PHA(UARTE(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \
129-
(0))), (0))
125+
#define INSTANCE_IS_FAST_PD(unused, prefix, idx, _) \
126+
UTIL_AND(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), Z_GET_GPD_FAST_ACTIVE1(UARTE(idx)))
130127

131128
#if UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_FAST_PD, (||), (0))
132129
/* Instance in fast power domain (PD) requires special PM treatment and clock control, so
@@ -419,6 +416,7 @@ static void endtx_isr(const struct device *dev)
419416
static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask)
420417
{
421418
struct uarte_nrfx_data *data = dev->data;
419+
const struct uarte_nrfx_config *config = dev->config;
422420

423421
data->flags &= ~dis_mask;
424422
if (data->flags & UARTE_FLAG_LOW_POWER) {
@@ -436,12 +434,9 @@ static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask)
436434
}
437435
#endif
438436

439-
#ifdef CONFIG_SOC_NRF54H20_GPD
440-
const struct uarte_nrfx_config *cfg = dev->config;
441-
442-
nrf_gpd_retain_pins_set(cfg->pcfg, true);
443-
#endif
444437
nrf_uarte_disable(get_uarte_instance(dev));
438+
439+
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
445440
}
446441

447442
#if defined(UARTE_ANY_NONE_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ)
@@ -724,9 +719,9 @@ static void uarte_periph_enable(const struct device *dev)
724719
#endif
725720

726721
nrf_uarte_enable(uarte);
727-
#ifdef CONFIG_SOC_NRF54H20_GPD
728-
nrf_gpd_retain_pins_set(config->pcfg, false);
729-
#endif
722+
723+
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
724+
730725
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
731726
nrf_uarte_baudrate_set(uarte,
732727
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
@@ -2408,10 +2403,6 @@ static void uarte_pm_suspend(const struct device *dev)
24082403
wait_for_tx_stopped(dev);
24092404
}
24102405

2411-
#ifdef CONFIG_SOC_NRF54H20_GPD
2412-
nrf_gpd_retain_pins_set(cfg->pcfg, true);
2413-
#endif
2414-
24152406
nrf_uarte_disable(uarte);
24162407

24172408
(void)pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP);

drivers/spi/spi_nrfx_spim.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -682,10 +682,6 @@ static int spim_resume(const struct device *dev)
682682
return -EAGAIN;
683683
}
684684

685-
#ifdef CONFIG_SOC_NRF54H20_GPD
686-
nrf_gpd_retain_pins_set(dev_config->pcfg, false);
687-
#endif
688-
689685
return pm_device_runtime_is_enabled(dev) ? request_clock(dev) : 0;
690686
}
691687

@@ -705,10 +701,6 @@ static void spim_suspend(const struct device *dev)
705701

706702
spi_context_cs_put_all(&dev_data->ctx);
707703

708-
#ifdef CONFIG_SOC_NRF54H20_GPD
709-
nrf_gpd_retain_pins_set(dev_config->pcfg, true);
710-
#endif
711-
712704
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP);
713705
}
714706

drivers/spi/spi_nrfx_spis.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,6 @@ static void spi_nrfx_suspend(const struct device *dev)
379379
nrf_spis_disable(dev_config->spis.p_reg);
380380
}
381381

382-
#ifdef CONFIG_SOC_NRF54H20_GPD
383-
if (dev_config->gpd_ctrl) {
384-
nrf_gpd_retain_pins_set(dev_config->pcfg, true);
385-
}
386-
#endif
387-
388382
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP);
389383
}
390384

@@ -394,12 +388,6 @@ static void spi_nrfx_resume(const struct device *dev)
394388

395389
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT);
396390

397-
#ifdef CONFIG_SOC_NRF54H20_GPD
398-
if (dev_config->gpd_ctrl) {
399-
nrf_gpd_retain_pins_set(dev_config->pcfg, false);
400-
}
401-
#endif
402-
403391
if (dev_config->wake_gpio.port == NULL) {
404392
nrf_spis_enable(dev_config->spis.p_reg);
405393
}

dts/arm/nordic/nrf54h20_cpuapp.dtsi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ wdt011: &cpuapp_wdt011 {};
5959
&grtc {
6060
interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>;
6161
};
62+
63+
&gdpwr {
64+
status = "okay";
65+
};

dts/arm/nordic/nrf54h20_cpurad.dtsi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,7 @@ wdt011: &cpurad_wdt011 {};
9999
&dppic020 {
100100
status = "okay";
101101
};
102+
103+
&gdpwr {
104+
status = "okay";
105+
};

dts/bindings/power/nordic,nrf-gpd.yaml

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)