Skip to content

Commit 56c5b1e

Browse files
gmarullmmahadevan108
authored andcommitted
drivers: gpio: nrfx: add support for ports with pad on FAST_ACTIVE1
This patch allows to _safely_ configure GPIO ports that have their pad on FAST_ACTIVE1 domain. Signed-off-by: Gerard Marull-Paretas <[email protected]>
1 parent 0b18f31 commit 56c5b1e

File tree

1 file changed

+108
-8
lines changed

1 file changed

+108
-8
lines changed

drivers/gpio/gpio_nrfx.c

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
#include <zephyr/drivers/gpio/gpio_utils.h>
1616

17+
#ifdef CONFIG_SOC_NRF54H20_GPD
18+
#include <nrf/gpd.h>
19+
#endif
20+
1721
struct 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

3239
static 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+
58114
static 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

177244
static 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

202275
static 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

212291
static 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

222307
static 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

Comments
 (0)