1 /*
2  * Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT sifive_gpio0
8 
9 /**
10  * @file GPIO driver for the SiFive Freedom Processor
11  */
12 
13 #include <errno.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/device.h>
16 #include <soc.h>
17 #include <zephyr/drivers/gpio.h>
18 #include <zephyr/sys/util.h>
19 #include <zephyr/irq.h>
20 
21 #include <zephyr/drivers/gpio/gpio_utils.h>
22 
23 typedef void (*sifive_cfg_func_t)(void);
24 
25 /* sifive GPIO register-set structure */
26 struct gpio_sifive_t {
27 	unsigned int in_val;
28 	unsigned int in_en;
29 	unsigned int out_en;
30 	unsigned int out_val;
31 	unsigned int pue;
32 	unsigned int ds;
33 	unsigned int rise_ie;
34 	unsigned int rise_ip;
35 	unsigned int fall_ie;
36 	unsigned int fall_ip;
37 	unsigned int high_ie;
38 	unsigned int high_ip;
39 	unsigned int low_ie;
40 	unsigned int low_ip;
41 	unsigned int iof_en;
42 	unsigned int iof_sel;
43 	unsigned int invert;
44 };
45 
46 struct gpio_sifive_config {
47 	/* gpio_driver_config needs to be first */
48 	struct gpio_driver_config common;
49 	uintptr_t            gpio_base_addr;
50 	/* multi-level encoded interrupt corresponding to pin 0 */
51 	uint32_t                gpio_irq_base;
52 	sifive_cfg_func_t    gpio_cfg_func;
53 };
54 
55 struct gpio_sifive_data {
56 	/* gpio_driver_data needs to be first */
57 	struct gpio_driver_data common;
58 	/* list of callbacks */
59 	sys_slist_t cb;
60 };
61 
62 /* Helper Macros for GPIO */
63 #define DEV_GPIO_CFG(dev)						\
64 	((const struct gpio_sifive_config * const)(dev)->config)
65 #define DEV_GPIO(dev)							\
66 	((volatile struct gpio_sifive_t *)(DEV_GPIO_CFG(dev))->gpio_base_addr)
67 #define DEV_GPIO_DATA(dev)				\
68 	((struct gpio_sifive_data *)(dev)->data)
69 
70 
71 /* Given gpio_irq_base and the pin number, return the IRQ number for the pin */
gpio_sifive_pin_irq(unsigned int base_irq,int pin)72 static inline unsigned int gpio_sifive_pin_irq(unsigned int base_irq, int pin)
73 {
74 	unsigned int level = irq_get_level(base_irq);
75 	unsigned int pin_irq = 0;
76 
77 	if (level == 1) {
78 		pin_irq = base_irq + pin;
79 	} else if (level == 2) {
80 		pin_irq = base_irq + (pin << 8);
81 	}
82 
83 	return pin_irq;
84 }
85 
86 /* Given the PLIC source number, return the number of the GPIO pin associated
87  * with the interrupt
88  */
gpio_sifive_plic_to_pin(unsigned int base_irq,int plic_irq)89 static inline int gpio_sifive_plic_to_pin(unsigned int base_irq, int plic_irq)
90 {
91 	unsigned int level = irq_get_level(base_irq);
92 
93 	if (level == 2) {
94 		base_irq = irq_from_level_2(base_irq);
95 	}
96 
97 	return (plic_irq - base_irq);
98 }
99 
gpio_sifive_irq_handler(const struct device * dev)100 static void gpio_sifive_irq_handler(const struct device *dev)
101 {
102 	struct gpio_sifive_data *data = DEV_GPIO_DATA(dev);
103 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
104 	const struct gpio_sifive_config *cfg = DEV_GPIO_CFG(dev);
105 
106 	/* Calculate pin and mask from base level 2 line */
107 	uint8_t pin = 1 + (riscv_plic_get_irq() - (uint8_t)(cfg->gpio_irq_base >> 8));
108 
109 	/* This peripheral tracks each condition separately: a
110 	 * transition from low to high will mark the pending bit for
111 	 * both rise and high, while low will probably be set from the
112 	 * previous state.
113 	 *
114 	 * It is certainly possible, especially on double-edge, that
115 	 * multiple conditions are present.  However, there is no way
116 	 * to tell which one occurred first, and no provision to
117 	 * indicate which one occurred in the callback.
118 	 *
119 	 * Clear all the conditions so we only invoke the callback
120 	 * once.  Level conditions will remain set after clear.
121 	 */
122 	gpio->rise_ip = BIT(pin);
123 	gpio->fall_ip = BIT(pin);
124 	gpio->high_ip = BIT(pin);
125 	gpio->low_ip = BIT(pin);
126 
127 	/* Call the corresponding callback registered for the pin */
128 	gpio_fire_callbacks(&data->cb, dev, BIT(pin));
129 }
130 
131 /**
132  * @brief Configure pin
133  *
134  * @param dev Device structure
135  * @param pin The pin number
136  * @param flags Flags of pin or port
137  *
138  * @return 0 if successful, failed otherwise
139  */
gpio_sifive_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)140 static int gpio_sifive_config(const struct device *dev,
141 			      gpio_pin_t pin,
142 			      gpio_flags_t flags)
143 {
144 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
145 
146 	if (pin >= SIFIVE_PINMUX_PINS) {
147 		return -EINVAL;
148 	}
149 
150 	/* We cannot support open-source open-drain configuration */
151 	if ((flags & GPIO_SINGLE_ENDED) != 0) {
152 		return -ENOTSUP;
153 	}
154 
155 	/* We only support pull-ups, not pull-downs */
156 	if ((flags & GPIO_PULL_DOWN) != 0) {
157 		return -ENOTSUP;
158 	}
159 
160 	/* Set pull-up if requested */
161 	WRITE_BIT(gpio->pue, pin, flags & GPIO_PULL_UP);
162 
163 	/* Set the initial output value before enabling output to avoid
164 	 * glitches
165 	 */
166 	if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
167 		gpio->out_val |= BIT(pin);
168 	}
169 	if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
170 		gpio->out_val &= ~BIT(pin);
171 	}
172 
173 	/* Enable input/output */
174 	WRITE_BIT(gpio->out_en, pin, flags & GPIO_OUTPUT);
175 	WRITE_BIT(gpio->in_en, pin, flags & GPIO_INPUT);
176 
177 	return 0;
178 }
179 
gpio_sifive_port_get_raw(const struct device * dev,gpio_port_value_t * value)180 static int gpio_sifive_port_get_raw(const struct device *dev,
181 				    gpio_port_value_t *value)
182 {
183 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
184 
185 	*value = gpio->in_val;
186 
187 	return 0;
188 }
189 
gpio_sifive_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)190 static int gpio_sifive_port_set_masked_raw(const struct device *dev,
191 					   gpio_port_pins_t mask,
192 					   gpio_port_value_t value)
193 {
194 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
195 
196 	gpio->out_val = (gpio->out_val & ~mask) | (value & mask);
197 
198 	return 0;
199 }
200 
gpio_sifive_port_set_bits_raw(const struct device * dev,gpio_port_pins_t mask)201 static int gpio_sifive_port_set_bits_raw(const struct device *dev,
202 					 gpio_port_pins_t mask)
203 {
204 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
205 
206 	gpio->out_val |= mask;
207 
208 	return 0;
209 }
210 
gpio_sifive_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t mask)211 static int gpio_sifive_port_clear_bits_raw(const struct device *dev,
212 					   gpio_port_pins_t mask)
213 {
214 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
215 
216 	gpio->out_val &= ~mask;
217 
218 	return 0;
219 }
220 
gpio_sifive_port_toggle_bits(const struct device * dev,gpio_port_pins_t mask)221 static int gpio_sifive_port_toggle_bits(const struct device *dev,
222 					gpio_port_pins_t mask)
223 {
224 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
225 
226 	gpio->out_val ^= mask;
227 
228 	return 0;
229 }
230 
gpio_sifive_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)231 static int gpio_sifive_pin_interrupt_configure(const struct device *dev,
232 					       gpio_pin_t pin,
233 					       enum gpio_int_mode mode,
234 					       enum gpio_int_trig trig)
235 {
236 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
237 	const struct gpio_sifive_config *cfg = DEV_GPIO_CFG(dev);
238 
239 	gpio->rise_ie &= ~BIT(pin);
240 	gpio->fall_ie &= ~BIT(pin);
241 	gpio->high_ie &= ~BIT(pin);
242 	gpio->low_ie  &= ~BIT(pin);
243 
244 	switch (mode) {
245 	case GPIO_INT_MODE_DISABLED:
246 		irq_disable(gpio_sifive_pin_irq(cfg->gpio_irq_base, pin));
247 		break;
248 	case GPIO_INT_MODE_LEVEL:
249 		/* Board supports both levels, but Zephyr does not. */
250 		if (trig == GPIO_INT_TRIG_HIGH) {
251 			gpio->high_ip = BIT(pin);
252 			gpio->high_ie |= BIT(pin);
253 		} else {
254 			__ASSERT_NO_MSG(trig == GPIO_INT_TRIG_LOW);
255 			gpio->low_ip = BIT(pin);
256 			gpio->low_ie  |= BIT(pin);
257 		}
258 		irq_enable(gpio_sifive_pin_irq(cfg->gpio_irq_base, pin));
259 		break;
260 	case GPIO_INT_MODE_EDGE:
261 		__ASSERT_NO_MSG(GPIO_INT_TRIG_BOTH ==
262 				(GPIO_INT_LOW_0 | GPIO_INT_HIGH_1));
263 
264 		if ((trig & GPIO_INT_HIGH_1) != 0) {
265 			gpio->rise_ip = BIT(pin);
266 			gpio->rise_ie |= BIT(pin);
267 		}
268 		if ((trig & GPIO_INT_LOW_0) != 0) {
269 			gpio->fall_ip = BIT(pin);
270 			gpio->fall_ie |= BIT(pin);
271 		}
272 		irq_enable(gpio_sifive_pin_irq(cfg->gpio_irq_base, pin));
273 		break;
274 	default:
275 		__ASSERT(false, "Invalid MODE %d passed to driver", mode);
276 		return -ENOTSUP;
277 	}
278 
279 	return 0;
280 }
281 
gpio_sifive_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)282 static int gpio_sifive_manage_callback(const struct device *dev,
283 				       struct gpio_callback *callback,
284 				       bool set)
285 {
286 	struct gpio_sifive_data *data = DEV_GPIO_DATA(dev);
287 
288 	return gpio_manage_callback(&data->cb, callback, set);
289 }
290 
291 #ifdef CONFIG_GPIO_GET_DIRECTION
gpio_sifive_port_get_dir(const struct device * dev,gpio_port_pins_t map,gpio_port_pins_t * inputs,gpio_port_pins_t * outputs)292 static int gpio_sifive_port_get_dir(const struct device *dev, gpio_port_pins_t map,
293 				    gpio_port_pins_t *inputs, gpio_port_pins_t *outputs)
294 {
295 	const struct gpio_sifive_config *cfg = DEV_GPIO_CFG(dev);
296 
297 	map &= cfg->common.port_pin_mask;
298 
299 	if (inputs != NULL) {
300 		*inputs = map & DEV_GPIO(dev)->in_en;
301 	}
302 
303 	if (outputs != NULL) {
304 		*outputs = map & DEV_GPIO(dev)->out_en;
305 	}
306 
307 	return 0;
308 }
309 #endif /* CONFIG_GPIO_GET_DIRECTION */
310 
311 static const struct gpio_driver_api gpio_sifive_driver = {
312 	.pin_configure           = gpio_sifive_config,
313 	.port_get_raw            = gpio_sifive_port_get_raw,
314 	.port_set_masked_raw     = gpio_sifive_port_set_masked_raw,
315 	.port_set_bits_raw       = gpio_sifive_port_set_bits_raw,
316 	.port_clear_bits_raw     = gpio_sifive_port_clear_bits_raw,
317 	.port_toggle_bits        = gpio_sifive_port_toggle_bits,
318 	.pin_interrupt_configure = gpio_sifive_pin_interrupt_configure,
319 	.manage_callback         = gpio_sifive_manage_callback,
320 #ifdef CONFIG_GPIO_GET_DIRECTION
321 	.port_get_direction      = gpio_sifive_port_get_dir,
322 #endif /* CONFIG_GPIO_GET_DIRECTION */
323 };
324 
325 /**
326  * @brief Initialize a GPIO controller
327  *
328  * Perform basic initialization of a GPIO controller
329  *
330  * @param dev GPIO device struct
331  *
332  * @return 0
333  */
gpio_sifive_init(const struct device * dev)334 static int gpio_sifive_init(const struct device *dev)
335 {
336 	volatile struct gpio_sifive_t *gpio = DEV_GPIO(dev);
337 	const struct gpio_sifive_config *cfg = DEV_GPIO_CFG(dev);
338 
339 	/* Ensure that all gpio registers are reset to 0 initially */
340 	gpio->in_en   = 0U;
341 	gpio->out_en  = 0U;
342 	gpio->pue     = 0U;
343 	gpio->rise_ie = 0U;
344 	gpio->fall_ie = 0U;
345 	gpio->high_ie = 0U;
346 	gpio->low_ie  = 0U;
347 	gpio->iof_en  = 0U;
348 	gpio->iof_sel = 0U;
349 	gpio->invert  = 0U;
350 
351 	/* Setup IRQ handler for each gpio pin */
352 	cfg->gpio_cfg_func();
353 
354 	return 0;
355 }
356 
357 static void gpio_sifive_cfg_0(void);
358 
359 static const struct gpio_sifive_config gpio_sifive_config0 = {
360 	.common = {
361 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0),
362 	},
363 	.gpio_base_addr = DT_INST_REG_ADDR(0),
364 	.gpio_irq_base  = DT_INST_IRQN(0),
365 	.gpio_cfg_func  = gpio_sifive_cfg_0,
366 };
367 
368 static struct gpio_sifive_data gpio_sifive_data0;
369 
370 DEVICE_DT_INST_DEFINE(0,
371 		    gpio_sifive_init,
372 		    NULL,
373 		    &gpio_sifive_data0, &gpio_sifive_config0,
374 		    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
375 		    &gpio_sifive_driver);
376 
377 #define		IRQ_INIT(n)					\
378 IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, n, irq),			\
379 		DT_INST_IRQ_BY_IDX(0, n, priority),		\
380 		gpio_sifive_irq_handler,			\
381 		DEVICE_DT_INST_GET(0),				\
382 		0);
383 
gpio_sifive_cfg_0(void)384 static void gpio_sifive_cfg_0(void)
385 {
386 #if DT_INST_IRQ_HAS_IDX(0, 0)
387 	IRQ_INIT(0);
388 #endif
389 #if DT_INST_IRQ_HAS_IDX(0, 1)
390 	IRQ_INIT(1);
391 #endif
392 #if DT_INST_IRQ_HAS_IDX(0, 2)
393 	IRQ_INIT(2);
394 #endif
395 #if DT_INST_IRQ_HAS_IDX(0, 3)
396 	IRQ_INIT(3);
397 #endif
398 #if DT_INST_IRQ_HAS_IDX(0, 4)
399 	IRQ_INIT(4);
400 #endif
401 #if DT_INST_IRQ_HAS_IDX(0, 5)
402 	IRQ_INIT(5);
403 #endif
404 #if DT_INST_IRQ_HAS_IDX(0, 6)
405 	IRQ_INIT(6);
406 #endif
407 #if DT_INST_IRQ_HAS_IDX(0, 7)
408 	IRQ_INIT(7);
409 #endif
410 #if DT_INST_IRQ_HAS_IDX(0, 8)
411 	IRQ_INIT(8);
412 #endif
413 #if DT_INST_IRQ_HAS_IDX(0, 9)
414 	IRQ_INIT(9);
415 #endif
416 #if DT_INST_IRQ_HAS_IDX(0, 10)
417 	IRQ_INIT(10);
418 #endif
419 #if DT_INST_IRQ_HAS_IDX(0, 11)
420 	IRQ_INIT(11);
421 #endif
422 #if DT_INST_IRQ_HAS_IDX(0, 12)
423 	IRQ_INIT(12);
424 #endif
425 #if DT_INST_IRQ_HAS_IDX(0, 13)
426 	IRQ_INIT(13);
427 #endif
428 #if DT_INST_IRQ_HAS_IDX(0, 14)
429 	IRQ_INIT(14);
430 #endif
431 #if DT_INST_IRQ_HAS_IDX(0, 15)
432 	IRQ_INIT(15);
433 #endif
434 #if DT_INST_IRQ_HAS_IDX(0, 16)
435 	IRQ_INIT(16);
436 #endif
437 #if DT_INST_IRQ_HAS_IDX(0, 17)
438 	IRQ_INIT(17);
439 #endif
440 #if DT_INST_IRQ_HAS_IDX(0, 18)
441 	IRQ_INIT(18);
442 #endif
443 #if DT_INST_IRQ_HAS_IDX(0, 19)
444 	IRQ_INIT(19);
445 #endif
446 #if DT_INST_IRQ_HAS_IDX(0, 20)
447 	IRQ_INIT(20);
448 #endif
449 #if DT_INST_IRQ_HAS_IDX(0, 21)
450 	IRQ_INIT(21);
451 #endif
452 #if DT_INST_IRQ_HAS_IDX(0, 22)
453 	IRQ_INIT(22);
454 #endif
455 #if DT_INST_IRQ_HAS_IDX(0, 23)
456 	IRQ_INIT(23);
457 #endif
458 #if DT_INST_IRQ_HAS_IDX(0, 24)
459 	IRQ_INIT(24);
460 #endif
461 #if DT_INST_IRQ_HAS_IDX(0, 25)
462 	IRQ_INIT(25);
463 #endif
464 #if DT_INST_IRQ_HAS_IDX(0, 26)
465 	IRQ_INIT(26);
466 #endif
467 #if DT_INST_IRQ_HAS_IDX(0, 27)
468 	IRQ_INIT(27);
469 #endif
470 #if DT_INST_IRQ_HAS_IDX(0, 28)
471 	IRQ_INIT(28);
472 #endif
473 #if DT_INST_IRQ_HAS_IDX(0, 29)
474 	IRQ_INIT(29);
475 #endif
476 #if DT_INST_IRQ_HAS_IDX(0, 30)
477 	IRQ_INIT(30);
478 #endif
479 #if DT_INST_IRQ_HAS_IDX(0, 31)
480 	IRQ_INIT(31);
481 #endif
482 }
483