Skip to content

Commit 05d5a9d

Browse files
soc: drivers: nrf: refactor pinctrl and pad power domains
Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
1 parent 643a223 commit 05d5a9d

File tree

22 files changed

+349
-685
lines changed

22 files changed

+349
-685
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: 132 additions & 49 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 PAD_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 PAD_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+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p0)) || \
130+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p1)) || \
131+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p2)) || \
132+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p3)) || \
133+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p4)) || \
134+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p5)) || \
135+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p6)) || \
136+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p7)) || \
137+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p8)) || \
138+
PAD_PD_EXISTS(DT_NODELABEL(pad_group_p9))
139+
140+
#if PORTS_HAVE_PD
141+
142+
static const struct device *const pad_pd_devs[] = {
143+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p0)),
144+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p1)),
145+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p2)),
146+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p3)),
147+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p4)),
148+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p5)),
149+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p6)),
150+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p7)),
151+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p8)),
152+
PAD_PD_DEV_GET_OR_NULL(DT_NODELABEL(pad_group_p9)),
153+
};
154+
155+
static atomic_t pad_pd_masks[ARRAY_SIZE(pad_pd_devs)];
156+
157+
static int pad_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 *pad_pd_dev = pad_pd_devs[port_number];
162+
atomic_t *pad_pd_mask = &pad_pd_masks[port_number];
163+
164+
if (atomic_test_and_set_bit(pad_pd_mask, port_pin_number)) {
165+
/* already requested */
166+
return 0;
167+
}
168+
169+
if (pm_device_runtime_get(pad_pd_dev)) {
170+
atomic_clear_bit(pad_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 pad_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 *pad_pd_dev = pad_pd_devs[port_number];
184+
atomic_t *pad_pd_mask = &pad_pd_masks[port_number];
185+
186+
if (!atomic_test_and_clear_bit(pad_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(pad_pd_dev)) {
195+
nrf_gpio_pin_retain_disable(pin_number);
196+
atomic_set_bit(pad_pd_mask, port_pin_number);
197+
return -EIO;
198+
}
199+
200+
return 0;
201+
}
202+
203+
#else
204+
205+
static int pad_pd_request_pin(uint16_t pin_number)
206+
{
207+
ARG_UNUSED(pin_number);
208+
return 0;
209+
}
210+
211+
static int pad_pd_release_pin(uint16_t pin_number)
117212
{
118-
#ifdef CONFIG_SOC_NRF54H20_GPD
119-
bool gpd_requested = false;
213+
ARG_UNUSED(pin_number);
214+
return 0;
215+
}
216+
217+
#endif
218+
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+
120234
#endif
121235

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,25 +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-
488-
/*
489-
* Pad power domain now on, retain no longer needed
490-
* as pad config will be persists as pad is powered.
491-
*/
492-
nrf_gpio_pin_retain_disable(pin);
493-
#endif /* CONFIG_SOC_NRF54H20_GPD */
592+
/* enable pin */
593+
pad_pd_request_pin(pin);
594+
port_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i]));
494595

495596
if (write != NO_WRITE) {
496597
nrf_gpio_pin_write(pin, write);
@@ -502,35 +603,17 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
502603
input = NRF_GPIO_PIN_INPUT_DISCONNECT;
503604
}
504605

606+
/* configure pin */
505607
nrf_gpio_cfg(pin, dir, input, NRF_GET_PULL(pins[i]),
506608
drive, NRF_GPIO_PIN_NOSENSE);
507-
#if NRF_GPIO_HAS_CLOCKPIN
508-
nrf_gpio_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i]));
509-
#endif
510-
#ifdef CONFIG_SOC_NRF54H20_GPD
609+
511610
if (NRF_GET_LP(pins[i]) == NRF_LP_ENABLE) {
512-
/*
513-
* Pad power domain may be turned off, and pad is not
514-
* actively used as pincnf is low-power. Enable retain
515-
* to ensure pad output and config persists if pad
516-
* power domain is suspended.
517-
*/
518-
nrf_gpio_pin_retain_enable(pin);
611+
/* disable pin */
612+
pad_pd_release_pin(pin);
613+
port_pin_clock_set(pin, false);
519614
}
520-
#endif /* CONFIG_SOC_NRF54H20_GPD */
521615
}
522616
}
523617

524-
#ifdef CONFIG_SOC_NRF54H20_GPD
525-
if (gpd_requested) {
526-
int ret;
527-
528-
ret = nrf_gpd_release(NRF_GPD_SLOW_ACTIVE);
529-
if (ret < 0) {
530-
return ret;
531-
}
532-
}
533-
#endif
534-
535618
return 0;
536619
}

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 & 21 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,11 +434,7 @@ 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
437+
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
444438
nrf_uarte_disable(get_uarte_instance(dev));
445439
}
446440

@@ -723,10 +717,9 @@ static void uarte_periph_enable(const struct device *dev)
723717
}
724718
#endif
725719

720+
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
726721
nrf_uarte_enable(uarte);
727-
#ifdef CONFIG_SOC_NRF54H20_GPD
728-
nrf_gpd_retain_pins_set(config->pcfg, false);
729-
#endif
722+
730723
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
731724
nrf_uarte_baudrate_set(uarte,
732725
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
@@ -2332,9 +2325,8 @@ static void uarte_pm_resume(const struct device *dev)
23322325
{
23332326
const struct uarte_nrfx_config *cfg = dev->config;
23342327

2335-
(void)pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
2336-
23372328
if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || !LOW_POWER_ENABLED(cfg)) {
2329+
(void)pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
23382330
uarte_periph_enable(dev);
23392331
}
23402332
}
@@ -2408,13 +2400,8 @@ static void uarte_pm_suspend(const struct device *dev)
24082400
wait_for_tx_stopped(dev);
24092401
}
24102402

2411-
#ifdef CONFIG_SOC_NRF54H20_GPD
2412-
nrf_gpd_retain_pins_set(cfg->pcfg, true);
2413-
#endif
2414-
2415-
nrf_uarte_disable(uarte);
2416-
24172403
(void)pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP);
2404+
nrf_uarte_disable(uarte);
24182405
}
24192406

24202407
static int uarte_nrfx_pm_action(const struct device *dev, enum pm_device_action action)

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+
};

0 commit comments

Comments
 (0)