1 /*
2 * Copyright (c) 2023 Antmicro <www.antmicro.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT renesas_rzt2m_gpio
8
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/gpio/gpio_utils.h>
12 #include <zephyr/drivers/syscon.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/sys/errno_private.h>
15 #include <zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h>
16 #include <soc.h>
17 #include <zephyr/drivers/gpio/gpio_utils.h>
18 #include <zephyr/irq.h>
19
20 static const struct device *const ns_portnf_md_dev = DEVICE_DT_GET(DT_NODELABEL(ns_portnf_md));
21
22 #define PMm_OFFSET 0x200
23 #define PMCm_OFFSET 0x400
24 #define PFCm_OFFSET 0x600
25 #define PINm_OFFSET 0x800
26 #define DRCTLm_OFFSET 0xa00
27
28 #define PMm_SIZE 0x2
29 #define DRCTLm_SIZE 0x8
30 #define PFCm_SIZE 0x4
31
32 /* config defines in include/zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h */
33 #define DRIVE_SHIFT 0
34 #define SCHMITT_TRIGGER_SHIFT 4
35 #define SLEW_RATE_SHIFT 5
36
37 #define PULL_SHIFT 2
38 #define PULL_NONE (0 << PULL_SHIFT)
39 #define PULL_UP (1 << PULL_SHIFT)
40 #define PULL_DOWN (2 << PULL_SHIFT)
41
42 #define INT_INVERT 0
43 #define INT_FALLING_EDGE 1
44 #define INT_RISING_EDGE 2
45 #define INT_BOTH_EDGE 3
46
47 #define IRQ_COUNT 16
48 #define NS_IRQ_COUNT 14
49
50 #define MAX_PORT_SIZE 8
51
52 #define RZT2M_GPIO_VALUE_IDENTITY(i, _) i
53
54 struct rzt2m_gpio_config {
55 struct gpio_driver_config common;
56 uint8_t pin_irqs[MAX_PORT_SIZE];
57 uint8_t *port_nsr;
58 uint8_t *ptadr;
59 uint8_t port;
60 };
61
62 struct rzt2m_gpio_data {
63 struct gpio_driver_data common;
64 sys_slist_t cb;
65 };
66
67 struct rzt2m_gpio_irq_slot {
68 const struct device *dev;
69 uint8_t pin;
70 };
71
72 struct rzt2m_gpio_common_data {
73 struct rzt2m_gpio_irq_slot irq_registered_ports[IRQ_COUNT];
74 };
75
76 static struct rzt2m_gpio_common_data rzt2m_gpio_common_data_inst;
77
rzt2m_gpio_unlock(void)78 static void rzt2m_gpio_unlock(void)
79 {
80 rzt2m_unlock_prcrn(PRCRN_PRC1 | PRCRN_PRC2);
81 rzt2m_unlock_prcrs(PRCRS_GPIO);
82 }
83
rzt2m_gpio_lock(void)84 static void rzt2m_gpio_lock(void)
85 {
86 rzt2m_lock_prcrn(PRCRN_PRC1 | PRCRN_PRC2);
87 rzt2m_lock_prcrs(PRCRS_GPIO);
88 }
89
90 /* Port m output data store */
rzt2m_gpio_get_p_reg(const struct device * dev)91 static volatile uint8_t *rzt2m_gpio_get_p_reg(const struct device *dev)
92 {
93 const struct rzt2m_gpio_config *config = dev->config;
94
95 return (volatile uint8_t *)(config->port_nsr + config->port);
96 }
97
98 /* Port m input data store */
rzt2m_gpio_get_pin_reg(const struct device * dev)99 static volatile uint8_t *rzt2m_gpio_get_pin_reg(const struct device *dev)
100 {
101 const struct rzt2m_gpio_config *config = dev->config;
102
103 return (volatile uint8_t *)(config->port_nsr + PINm_OFFSET + config->port);
104 }
105
106 /* Port m mode register */
rzt2m_gpio_get_pm_reg(const struct device * dev)107 static volatile uint16_t *rzt2m_gpio_get_pm_reg(const struct device *dev)
108 {
109 const struct rzt2m_gpio_config *config = dev->config;
110
111 return (volatile uint16_t *)(config->port_nsr + PMm_OFFSET + PMm_SIZE * config->port);
112 }
113
114 /* IO Buffer m function switching register */
rzt2m_gpio_get_drctl_reg(const struct device * dev)115 static volatile uint64_t *rzt2m_gpio_get_drctl_reg(const struct device *dev)
116 {
117 const struct rzt2m_gpio_config *config = dev->config;
118
119 return (volatile uint64_t *)(config->port_nsr + DRCTLm_OFFSET + DRCTLm_SIZE * config->port);
120 }
121
122 /* Port m region select register */
rzt2m_gpio_get_rselp_reg(const struct device * dev)123 static volatile uint8_t *rzt2m_gpio_get_rselp_reg(const struct device *dev)
124 {
125 const struct rzt2m_gpio_config *config = dev->config;
126
127 return (volatile uint8_t *)(config->ptadr + config->port);
128 }
129
130 /* Port m mode control register */
rzt2m_gpio_get_pmc_reg(const struct device * dev,uint8_t port)131 static volatile uint8_t *rzt2m_gpio_get_pmc_reg(const struct device *dev, uint8_t port)
132 {
133 const struct rzt2m_gpio_config *config = dev->config;
134
135 return (volatile uint8_t *)(config->port_nsr + PMCm_OFFSET + port);
136 }
137
138 /* Port m function control register */
rzt2m_gpio_get_pfc_reg(const struct device * dev,uint8_t port)139 static volatile uint32_t *rzt2m_gpio_get_pfc_reg(const struct device *dev, uint8_t port)
140 {
141 const struct rzt2m_gpio_config *config = dev->config;
142
143 return (volatile uint32_t *)(config->port_nsr + PFCm_OFFSET + PFCm_SIZE * port);
144 }
145
rzt2m_gpio_init(const struct device * dev)146 static int rzt2m_gpio_init(const struct device *dev)
147 {
148 rzt2m_gpio_unlock();
149
150 volatile uint8_t *rselp_reg = rzt2m_gpio_get_rselp_reg(dev);
151 *rselp_reg = 0xFF;
152
153 rzt2m_gpio_lock();
154
155 return 0;
156 }
157
rzt2m_gpio_get_raw(const struct device * dev,gpio_port_value_t * value)158 static int rzt2m_gpio_get_raw(const struct device *dev, gpio_port_value_t *value)
159 {
160 rzt2m_gpio_unlock();
161
162 volatile uint8_t *pin_reg = rzt2m_gpio_get_pin_reg(dev);
163 *value = *pin_reg;
164
165 rzt2m_gpio_lock();
166
167 return 0;
168 }
169
rzt2m_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)170 static int rzt2m_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
171 gpio_port_value_t value)
172 {
173 rzt2m_gpio_unlock();
174
175 volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
176 *p_reg = (*p_reg & ~mask) | (value & mask);
177
178 rzt2m_gpio_lock();
179
180 return 0;
181 }
182
rzt2m_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)183 static int rzt2m_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
184 {
185 rzt2m_gpio_unlock();
186
187 volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
188 *p_reg |= pins;
189
190 rzt2m_gpio_lock();
191
192 return 0;
193 }
194
rzt2m_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)195 static int rzt2m_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
196 {
197 rzt2m_gpio_unlock();
198
199 volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
200 *p_reg &= ~pins;
201
202 rzt2m_gpio_lock();
203
204 return 0;
205 }
206
rzt2m_gpio_toggle(const struct device * dev,gpio_port_pins_t pins)207 static int rzt2m_gpio_toggle(const struct device *dev, gpio_port_pins_t pins)
208 {
209 rzt2m_gpio_unlock();
210
211 volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
212 *p_reg ^= pins;
213
214 rzt2m_gpio_lock();
215
216 return 0;
217 }
218
rzt2m_gpio_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)219 static int rzt2m_gpio_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
220 {
221 volatile uint16_t *pm_reg = rzt2m_gpio_get_pm_reg(dev);
222 volatile uint64_t *drctl_reg = rzt2m_gpio_get_drctl_reg(dev);
223
224 rzt2m_gpio_unlock();
225
226 WRITE_BIT(*pm_reg, pin * 2, flags & GPIO_INPUT);
227 WRITE_BIT(*pm_reg, pin * 2 + 1, flags & GPIO_OUTPUT);
228
229 if (flags & GPIO_OUTPUT) {
230 if (flags & GPIO_OUTPUT_INIT_LOW) {
231 rzt2m_port_clear_bits_raw(dev, 1 << pin);
232 } else if (flags & GPIO_OUTPUT_INIT_HIGH) {
233 rzt2m_port_set_bits_raw(dev, 1 << pin);
234 }
235 }
236
237 if (flags & GPIO_PULL_UP && flags & GPIO_PULL_DOWN) {
238 rzt2m_gpio_lock();
239 return -EINVAL;
240 }
241
242 uint8_t drctl_pin_config = 0;
243
244 if (flags & GPIO_PULL_UP) {
245 drctl_pin_config |= PULL_UP;
246 } else if (flags & GPIO_PULL_DOWN) {
247 drctl_pin_config |= PULL_DOWN;
248 } else {
249 drctl_pin_config |= PULL_NONE;
250 }
251
252 drctl_pin_config |=
253 (flags & RZT2M_GPIO_DRIVE_MASK) >> (RZT2M_GPIO_DRIVE_OFFSET - DRIVE_SHIFT);
254 drctl_pin_config |= (flags & RZT2M_GPIO_SCHMITT_TRIGGER_MASK) >>
255 (RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET - SCHMITT_TRIGGER_SHIFT);
256 drctl_pin_config |= (flags & RZT2M_GPIO_SLEW_RATE_MASK) >>
257 (RZT2M_GPIO_SLEW_RATE_OFFSET - SLEW_RATE_SHIFT);
258
259 uint64_t drctl_pin_value = *drctl_reg & ~(0xFFULL << (pin * 8));
260 *drctl_reg = drctl_pin_value | ((uint64_t)drctl_pin_config << (pin * 8));
261
262 rzt2m_gpio_lock();
263
264 return 0;
265 }
266
rzt2m_gpio_get_pin_irq(const struct device * dev,gpio_pin_t pin)267 static int rzt2m_gpio_get_pin_irq(const struct device *dev, gpio_pin_t pin)
268 {
269 const struct rzt2m_gpio_config *config = dev->config;
270
271 if (pin >= MAX_PORT_SIZE) {
272 return -1;
273 }
274 return config->pin_irqs[pin] - 1;
275 }
276
rzt2m_gpio_is_irq_used_by_other_pin(const struct device * dev,gpio_pin_t pin,uint8_t irq)277 static bool rzt2m_gpio_is_irq_used_by_other_pin(const struct device *dev, gpio_pin_t pin,
278 uint8_t irq)
279 {
280 if (irq >= IRQ_COUNT) {
281 return false;
282 }
283 if (rzt2m_gpio_common_data_inst.irq_registered_ports[irq].dev == NULL) {
284 return false;
285 }
286 if (rzt2m_gpio_common_data_inst.irq_registered_ports[irq].dev != dev) {
287 return true;
288 }
289 return rzt2m_gpio_common_data_inst.irq_registered_ports[irq].pin != pin;
290 }
291
rzt2m_gpio_isr(uint8_t * irq_n)292 static void rzt2m_gpio_isr(uint8_t *irq_n)
293 {
294 const struct device *dev = rzt2m_gpio_common_data_inst.irq_registered_ports[*irq_n].dev;
295
296 if (dev) {
297 struct rzt2m_gpio_data *data = dev->data;
298 int irq_pin = rzt2m_gpio_common_data_inst.irq_registered_ports[*irq_n].pin;
299
300 if (irq_pin >= 0) {
301 gpio_fire_callbacks(&data->cb, dev, 1 << irq_pin);
302 }
303 }
304 }
305
rzt2m_gpio_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)306 static int rzt2m_gpio_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
307 enum gpio_int_mode mode, enum gpio_int_trig trig)
308 {
309 const struct rzt2m_gpio_config *config = dev->config;
310 volatile uint8_t *pmc_reg = rzt2m_gpio_get_pmc_reg(dev, config->port);
311 volatile uint32_t *pfc_reg = rzt2m_gpio_get_pfc_reg(dev, config->port);
312 uint32_t ns_portnf_md_val = 0;
313
314 syscon_read_reg(ns_portnf_md_dev, 0, &ns_portnf_md_val);
315
316 /* level interrupts are not supported */
317 if (mode == GPIO_INT_MODE_LEVEL) {
318 return -ENOTSUP;
319 }
320
321 uint8_t irq = rzt2m_gpio_get_pin_irq(dev, pin);
322 bool irq_used_by_other = rzt2m_gpio_is_irq_used_by_other_pin(dev, pin, irq);
323
324 if (irq < 0) {
325 return -ENOTSUP;
326 }
327
328 /* secure range - currently not supported*/
329 if (irq >= NS_IRQ_COUNT) {
330 return -ENOSYS;
331 }
332
333 if (mode == GPIO_INT_MODE_DISABLED) {
334 rzt2m_gpio_unlock();
335 WRITE_BIT(*pmc_reg, pin, 0);
336
337 /* check if selected pin is using irq line to avoid unregistering other pin irq
338 * handler
339 */
340 if (!irq_used_by_other) {
341 rzt2m_gpio_common_data_inst.irq_registered_ports[irq].dev = NULL;
342 }
343 rzt2m_gpio_lock();
344 return 0;
345 }
346
347 /* the irq line is used by another pin */
348 if (irq_used_by_other) {
349 return -EBUSY;
350 }
351
352 uint8_t md_mode = 0x0;
353
354 switch (trig) {
355 case GPIO_INT_TRIG_LOW:
356 md_mode = INT_FALLING_EDGE;
357 break;
358 case GPIO_INT_TRIG_HIGH:
359 md_mode = INT_RISING_EDGE;
360 break;
361 case GPIO_INT_TRIG_BOTH:
362 md_mode = INT_BOTH_EDGE;
363 break;
364 default:
365 return -EINVAL;
366 }
367
368 rzt2m_gpio_unlock();
369
370 uint32_t mdx_mask =
371 ~((uint32_t)0b11 << irq); /* description of interrupt type has length of 2 bits */
372 ns_portnf_md_val = (ns_portnf_md_val & mdx_mask) | (md_mode << irq);
373 syscon_write_reg(ns_portnf_md_dev, 0, ns_portnf_md_val); /* set interrupt type */
374
375 WRITE_BIT(*pmc_reg, pin, 1); /* enable special function on selected pin */
376
377 /* in case of every pin on every port irq function number is 0 */
378 *pfc_reg &= ~((uint32_t)0b1111 << pin * 4);
379
380 /* register handling interrupt in isr for selected port and pin */
381 rzt2m_gpio_common_data_inst.irq_registered_ports[irq].dev = dev;
382 rzt2m_gpio_common_data_inst.irq_registered_ports[irq].pin = pin;
383
384 rzt2m_gpio_lock();
385
386 return 0;
387 }
388
rzt2m_gpio_manage_callback(const struct device * dev,struct gpio_callback * cb,bool set)389 static int rzt2m_gpio_manage_callback(const struct device *dev, struct gpio_callback *cb, bool set)
390 {
391 struct rzt2m_gpio_data *data = dev->data;
392
393 return gpio_manage_callback(&data->cb, cb, set);
394 }
395
396 static DEVICE_API(gpio, rzt2m_gpio_driver_api) = {
397 .pin_configure = rzt2m_gpio_configure,
398 .port_get_raw = rzt2m_gpio_get_raw,
399 .port_set_masked_raw = rzt2m_port_set_masked_raw,
400 .port_set_bits_raw = rzt2m_port_set_bits_raw,
401 .port_clear_bits_raw = rzt2m_port_clear_bits_raw,
402 .port_toggle_bits = rzt2m_gpio_toggle,
403 .pin_interrupt_configure = rzt2m_gpio_pin_interrupt_configure,
404 .manage_callback = rzt2m_gpio_manage_callback};
405
406 #define RZT2M_INIT_IRQ(irq_n) \
407 IRQ_CONNECT(DT_IRQ_BY_IDX(DT_INST(0, renesas_rzt2m_gpio_common), irq_n, irq), \
408 DT_IRQ_BY_IDX(DT_INST(0, renesas_rzt2m_gpio_common), irq_n, priority), \
409 rzt2m_gpio_isr, &n[irq_n], \
410 DT_IRQ_BY_IDX(DT_INST(0, renesas_rzt2m_gpio_common), irq_n, flags)) \
411 irq_enable(DT_IRQ_BY_IDX(DT_INST(0, renesas_rzt2m_gpio_common), irq_n, irq));
412
rzt2m_gpio_common_init(const struct device * dev)413 static int rzt2m_gpio_common_init(const struct device *dev)
414 {
415 struct rzt2m_gpio_common_data *data = dev->data;
416
417 static uint8_t n[IRQ_COUNT];
418
419 for (int i = 0; i < ARRAY_SIZE(n); i++) {
420 n[i] = i;
421 data->irq_registered_ports[i].dev = NULL;
422 }
423
424 FOR_EACH(RZT2M_INIT_IRQ, (), LISTIFY(NS_IRQ_COUNT, RZT2M_GPIO_VALUE_IDENTITY, (,)))
425
426 return 0;
427 }
428
429 DEVICE_DT_DEFINE(DT_INST(0, renesas_rzt2m_gpio_common),
430 rzt2m_gpio_common_init,
431 NULL,
432 &rzt2m_gpio_common_data_inst, NULL,
433 PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
434 NULL);
435
436 #define VALUE_2X(i, _) UTIL_X2(i)
437
438 #define PIN_IRQ_INITIALIZER(idx, inst) \
439 COND_CODE_1(DT_INST_PROP_HAS_IDX(inst, irqs, idx), \
440 ([DT_INST_PROP_BY_IDX(inst, irqs, idx)] = \
441 DT_INST_PROP_BY_IDX(inst, irqs, UTIL_INC(idx)) + 1,), \
442 ())
443
444 #define PORT_IRQS_INITIALIZER(inst) \
445 FOR_EACH_FIXED_ARG(PIN_IRQ_INITIALIZER, (), inst, \
446 LISTIFY(DT_INST_PROP_LEN_OR(inst, irqs, 0), VALUE_2X, (,)))
447
448 #define RZT2M_GPIO_DEFINE(inst) \
449 static struct rzt2m_gpio_data rzt2m_gpio_data##inst; \
450 static struct rzt2m_gpio_config rzt2m_gpio_config##inst = { \
451 .port_nsr = (uint8_t *)DT_REG_ADDR_BY_NAME(DT_INST_GPARENT(inst), port_nsr), \
452 .ptadr = (uint8_t *)DT_REG_ADDR_BY_NAME(DT_INST_GPARENT(inst), ptadr), \
453 .port = DT_INST_REG_ADDR(inst), \
454 .pin_irqs = {PORT_IRQS_INITIALIZER(inst)}, \
455 .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst)}}; \
456 DEVICE_DT_INST_DEFINE(inst, rzt2m_gpio_init, NULL, &rzt2m_gpio_data##inst, \
457 &rzt2m_gpio_config##inst, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \
458 &rzt2m_gpio_driver_api);
459
460 DT_INST_FOREACH_STATUS_OKAY(RZT2M_GPIO_DEFINE)
461