1414
1515#include <zephyr/drivers/gpio/gpio_utils.h>
1616
17+ #ifdef CONFIG_SOC_NRF54H20_GPD
18+ #include <nrf/gpd.h>
19+ #endif
20+
1721struct gpio_nrfx_data {
1822 /* gpio_driver_data needs to be first */
1923 struct gpio_driver_data common ;
@@ -27,6 +31,9 @@ struct gpio_nrfx_cfg {
2731 uint32_t edge_sense ;
2832 uint8_t port_num ;
2933 nrfx_gpiote_t gpiote ;
34+ #ifdef CONFIG_SOC_NRF54H20_GPD
35+ uint8_t pad_pd ;
36+ #endif
3037};
3138
3239static inline struct gpio_nrfx_data * get_port_data (const struct device * port )
@@ -55,9 +62,59 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
5562 return NRF_GPIO_PIN_NOPULL ;
5663}
5764
65+ static int gpio_nrfx_gpd_retain_set (const struct device * port , uint32_t mask , gpio_flags_t flags )
66+ {
67+ #ifdef CONFIG_SOC_NRF54H20_GPD
68+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
69+
70+ if (cfg -> pad_pd == NRF_GPD_FAST_ACTIVE1 ) {
71+ int ret ;
72+
73+ if (flags & GPIO_OUTPUT ) {
74+ cfg -> port -> RETAINSET = mask ;
75+ }
76+
77+ ret = nrf_gpd_release (NRF_GPD_FAST_ACTIVE1 );
78+ if (ret < 0 ) {
79+ return ret ;
80+ }
81+ }
82+ #else
83+ ARG_UNUSED (port );
84+ ARG_UNUSED (mask );
85+ ARG_UNUSED (flags );
86+ #endif
87+
88+ return 0 ;
89+ }
90+
91+ static int gpio_nrfx_gpd_retain_clear (const struct device * port , uint32_t mask )
92+ {
93+ #ifdef CONFIG_SOC_NRF54H20_GPD
94+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
95+
96+ if (cfg -> pad_pd == NRF_GPD_FAST_ACTIVE1 ) {
97+ int ret ;
98+
99+ ret = nrf_gpd_request (NRF_GPD_FAST_ACTIVE1 );
100+ if (ret < 0 ) {
101+ return ret ;
102+ }
103+
104+ cfg -> port -> RETAINCLR = mask ;
105+ }
106+ #else
107+ ARG_UNUSED (port );
108+ ARG_UNUSED (mask );
109+ #endif
110+
111+ return 0 ;
112+ }
113+
58114static int gpio_nrfx_pin_configure (const struct device * port , gpio_pin_t pin ,
59115 gpio_flags_t flags )
60116{
117+ int ret = 0 ;
61118 nrfx_err_t err = NRFX_SUCCESS ;
62119 uint8_t ch ;
63120 bool free_ch = false;
@@ -95,6 +152,11 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
95152 return - EINVAL ;
96153 }
97154
155+ ret = gpio_nrfx_gpd_retain_clear (port , BIT (pin ));
156+ if (ret < 0 ) {
157+ return ret ;
158+ }
159+
98160 if (flags & GPIO_OUTPUT_INIT_HIGH ) {
99161 nrf_gpio_port_out_set (cfg -> port , BIT (pin ));
100162 } else if (flags & GPIO_OUTPUT_INIT_LOW ) {
@@ -110,7 +172,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
110172 : NRF_GPIO_PIN_INPUT_DISCONNECT ;
111173
112174 nrf_gpio_reconfigure (abs_pin , & dir , & input , & pull , & drive , NULL );
113- return 0 ;
175+
176+ goto end ;
114177 }
115178
116179 /* Get the GPIOTE channel associated with this pin, if any. It needs
@@ -137,7 +200,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
137200 err = nrfx_gpiote_input_configure (& cfg -> gpiote ,
138201 abs_pin , & input_pin_config );
139202 if (err != NRFX_SUCCESS ) {
140- return - EINVAL ;
203+ ret = - EINVAL ;
204+ goto end ;
141205 }
142206 }
143207
@@ -162,7 +226,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
162226 }
163227
164228 if (err != NRFX_SUCCESS ) {
165- return - EINVAL ;
229+ ret = - EINVAL ;
230+ goto end ;
166231 }
167232 }
168233
@@ -171,7 +236,9 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
171236 __ASSERT_NO_MSG (err == NRFX_SUCCESS );
172237 }
173238
174- return 0 ;
239+ end :
240+ (void )gpio_nrfx_gpd_retain_set (port , BIT (pin ), flags );
241+ return ret ;
175242}
176243
177244static int gpio_nrfx_port_get_raw (const struct device * port ,
@@ -189,34 +256,52 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
189256 gpio_port_value_t value )
190257{
191258 NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
259+ int ret ;
192260
193261 const uint32_t set_mask = value & mask ;
194262 const uint32_t clear_mask = (~set_mask ) & mask ;
195263
264+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
265+ if (ret < 0 ) {
266+ return ret ;
267+ }
268+
196269 nrf_gpio_port_out_set (reg , set_mask );
197270 nrf_gpio_port_out_clear (reg , clear_mask );
198271
199- return 0 ;
272+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
200273}
201274
202275static int gpio_nrfx_port_set_bits_raw (const struct device * port ,
203276 gpio_port_pins_t mask )
204277{
205278 NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
279+ int ret ;
280+
281+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
282+ if (ret < 0 ) {
283+ return ret ;
284+ }
206285
207286 nrf_gpio_port_out_set (reg , mask );
208287
209- return 0 ;
288+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
210289}
211290
212291static int gpio_nrfx_port_clear_bits_raw (const struct device * port ,
213292 gpio_port_pins_t mask )
214293{
215294 NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
295+ int ret ;
296+
297+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
298+ if (ret < 0 ) {
299+ return ret ;
300+ }
216301
217302 nrf_gpio_port_out_clear (reg , mask );
218303
219- return 0 ;
304+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
220305}
221306
222307static int gpio_nrfx_port_toggle_bits (const struct device * port ,
@@ -226,11 +311,17 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
226311 const uint32_t value = nrf_gpio_port_out_read (reg ) ^ mask ;
227312 const uint32_t set_mask = value & mask ;
228313 const uint32_t clear_mask = (~value ) & mask ;
314+ int ret ;
315+
316+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
317+ if (ret < 0 ) {
318+ return ret ;
319+ }
229320
230321 nrf_gpio_port_out_set (reg , set_mask );
231322 nrf_gpio_port_out_clear (reg , clear_mask );
232323
233- return 0 ;
324+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
234325}
235326
236327#ifdef CONFIG_GPIO_NRFX_INTERRUPT
@@ -450,6 +541,14 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
450541 "Please enable GPIOTE instance for used GPIO port!")), \
451542 ())
452543
544+ #ifdef CONFIG_SOC_NRF54H20_GPD
545+ #define PAD_PD (inst ) \
546+ .pad_pd = DT_INST_PHA_BY_NAME_OR(inst, power_domains, pad, id, \
547+ NRF_GPD_SLOW_MAIN),
548+ #else
549+ #define PAD_PD (inst )
550+ #endif
551+
453552#define GPIO_NRF_DEVICE (id ) \
454553 GPIOTE_CHECK(id); \
455554 static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
@@ -461,6 +560,7 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
461560 .port_num = DT_INST_PROP(id, port), \
462561 .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
463562 .gpiote = GPIOTE_INSTANCE(id), \
563+ PAD_PD(id) \
464564 }; \
465565 \
466566 static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
0 commit comments