xref: /openbsd-src/sys/dev/fdt/rkgpio.c (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
1 /*	$OpenBSD: rkgpio.c,v 1.10 2023/03/05 14:45:07 patrick Exp $	*/
2 /*
3  * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
4  * Copyright (c) 2019 Patrick Wildt <patrick@blueri.se>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 #include <sys/malloc.h>
23 #include <sys/evcount.h>
24 
25 #include <machine/intr.h>
26 #include <machine/bus.h>
27 #include <machine/fdt.h>
28 
29 #include <dev/ofw/openfirm.h>
30 #include <dev/ofw/ofw_gpio.h>
31 #include <dev/ofw/fdt.h>
32 
33 /* Registers. */
34 
35 #define GPIO_SWPORTA_DR		0x0000
36 #define GPIO_SWPORTA_DDR	0x0004
37 #define GPIO_INTEN		0x0030
38 #define GPIO_INTMASK		0x0034
39 #define GPIO_INTTYPE_LEVEL	0x0038
40 #define GPIO_INT_POLARITY	0x003c
41 #define GPIO_INT_STATUS		0x0040
42 #define GPIO_INT_RAWSTATUS	0x0044
43 #define GPIO_DEBOUNCE		0x0048
44 #define GPIO_PORTS_EOI		0x004c
45 #define GPIO_EXT_PORTA		0x0050
46 
47 #define GPIO_SWPORT_DR_L	0x0000
48 #define GPIO_SWPORT_DR_H	0x0004
49 #define GPIO_SWPORT_DDR_L	0x0008
50 #define GPIO_SWPORT_DDR_H	0x000c
51 #define GPIO_INT_EN_L		0x0010
52 #define GPIO_INT_EN_H		0x0014
53 #define GPIO_INT_MASK_L		0x0018
54 #define GPIO_INT_MASK_H		0x001c
55 #define GPIO_INT_TYPE_L		0x0020
56 #define GPIO_INT_TYPE_H		0x0024
57 #define GPIO_INT_POLARITY_L	0x0028
58 #define GPIO_INT_POLARITY_H	0x002c
59 #define GPIO_EXT_PORT		0x0070
60 #define GPIO_VER_ID		0x0078
61 #define  GPIO_VER_ID_1_0	0x00000000
62 #define  GPIO_VER_ID_2_0	0x01000c2b
63 #define  GPIO_VER_ID_2_1	0x0101157c
64 
65 #define GPIO_NUM_PINS		32
66 
67 #define HREAD4(sc, reg)							\
68 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
69 #define HWRITE4(sc, reg, val)						\
70 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
71 #define HSET4(sc, reg, bits)						\
72 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
73 #define HCLR4(sc, reg, bits)						\
74 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
75 
76 struct intrhand {
77 	int (*ih_func)(void *);		/* handler */
78 	void *ih_arg;			/* arg for handler */
79 	int ih_ipl;			/* IPL_* */
80 	int ih_irq;			/* IRQ number */
81 	int ih_level;			/* GPIO level */
82 	struct evcount	ih_count;
83 	char *ih_name;
84 	void *ih_sc;
85 };
86 
87 struct rkgpio_softc {
88 	struct device		sc_dev;
89 	bus_space_tag_t		sc_iot;
90 	bus_space_handle_t	sc_ioh;
91 	int			sc_node;
92 	int			sc_version;
93 
94 	void			*sc_ih;
95 	int			sc_ipl;
96 	int			sc_irq;
97 	struct intrhand		*sc_handlers[GPIO_NUM_PINS];
98 	struct interrupt_controller sc_ic;
99 
100 	struct gpio_controller	sc_gc;
101 };
102 
103 int rkgpio_match(struct device *, void *, void *);
104 void rkgpio_attach(struct device *, struct device *, void *);
105 
106 const struct cfattach	rkgpio_ca = {
107 	sizeof (struct rkgpio_softc), rkgpio_match, rkgpio_attach
108 };
109 
110 struct cfdriver rkgpio_cd = {
111 	NULL, "rkgpio", DV_DULL
112 };
113 
114 void	rkgpio_config_pin(void *, uint32_t *, int);
115 int	rkgpio_get_pin(void *, uint32_t *);
116 void	rkgpio_set_pin(void *, uint32_t *, int);
117 
118 int	rkgpio_intr(void *);
119 void	*rkgpio_intr_establish(void *, int *, int, struct cpu_info *,
120 	    int (*)(void *), void *, char *);
121 void	rkgpio_intr_disestablish(void *);
122 void	rkgpio_recalc_ipl(struct rkgpio_softc *);
123 void	rkgpio_intr_enable(void *);
124 void	rkgpio_intr_disable(void *);
125 void	rkgpio_intr_barrier(void *);
126 
127 int
128 rkgpio_match(struct device *parent, void *match, void *aux)
129 {
130 	struct fdt_attach_args *faa = aux;
131 
132 	return OF_is_compatible(faa->fa_node, "rockchip,gpio-bank");
133 }
134 
135 void
136 rkgpio_attach(struct device *parent, struct device *self, void *aux)
137 {
138 	struct rkgpio_softc *sc = (struct rkgpio_softc *)self;
139 	struct fdt_attach_args *faa = aux;
140 	uint32_t ver_id;
141 
142 	if (faa->fa_nreg < 1) {
143 		printf(": no registers\n");
144 		return;
145 	}
146 
147 	sc->sc_node = faa->fa_node;
148 	sc->sc_iot = faa->fa_iot;
149 
150 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
151 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
152 		printf(": can't map registers\n");
153 		return;
154 	}
155 
156 	ver_id = HREAD4(sc, GPIO_VER_ID);
157 	switch (ver_id) {
158 	case GPIO_VER_ID_1_0:
159 		sc->sc_version = 1;
160 		break;
161 	case GPIO_VER_ID_2_0:
162 	case GPIO_VER_ID_2_1:
163 		sc->sc_version = 2;
164 		break;
165 	default:
166 		printf(": unknown version 0x%08x\n", ver_id);
167 		return;
168 	}
169 
170 	sc->sc_gc.gc_node = faa->fa_node;
171 	sc->sc_gc.gc_cookie = sc;
172 	sc->sc_gc.gc_config_pin = rkgpio_config_pin;
173 	sc->sc_gc.gc_get_pin = rkgpio_get_pin;
174 	sc->sc_gc.gc_set_pin = rkgpio_set_pin;
175 	gpio_controller_register(&sc->sc_gc);
176 
177 	sc->sc_ipl = IPL_NONE;
178 	if (sc->sc_version == 2) {
179 		HWRITE4(sc, GPIO_INT_MASK_L, ~0);
180 		HWRITE4(sc, GPIO_INT_MASK_H, ~0);
181 		HWRITE4(sc, GPIO_INT_EN_L, ~0);
182 		HWRITE4(sc, GPIO_INT_EN_H, ~0);
183 	} else {
184 		HWRITE4(sc, GPIO_INTMASK, ~0);
185 		HWRITE4(sc, GPIO_INTEN, ~0);
186 	}
187 
188 	sc->sc_ic.ic_node = faa->fa_node;
189 	sc->sc_ic.ic_cookie = sc;
190 	sc->sc_ic.ic_establish = rkgpio_intr_establish;
191 	sc->sc_ic.ic_disestablish = rkgpio_intr_disestablish;
192 	sc->sc_ic.ic_enable = rkgpio_intr_enable;
193 	sc->sc_ic.ic_disable = rkgpio_intr_disable;
194 	sc->sc_ic.ic_barrier = rkgpio_intr_barrier;
195 	fdt_intr_register(&sc->sc_ic);
196 
197 	printf("\n");
198 }
199 
200 void
201 rkgpio_config_pin(void *cookie, uint32_t *cells, int config)
202 {
203 	struct rkgpio_softc *sc = cookie;
204 	uint32_t pin = cells[0];
205 	uint32_t reg;
206 
207 	if (pin >= GPIO_NUM_PINS)
208 		return;
209 
210 	if (sc->sc_version == 2) {
211 		reg = (1 << (pin % 16)) << 16;
212 		if (config & GPIO_CONFIG_OUTPUT)
213 			reg |= (1 << (pin % 16));
214 		HWRITE4(sc, GPIO_SWPORT_DDR_L + (pin / 16) * 4, reg);
215 	} else {
216 		if (config & GPIO_CONFIG_OUTPUT)
217 			HSET4(sc, GPIO_SWPORTA_DDR, (1 << pin));
218 		else
219 			HCLR4(sc, GPIO_SWPORTA_DDR, (1 << pin));
220 	}
221 }
222 
223 int
224 rkgpio_get_pin(void *cookie, uint32_t *cells)
225 {
226 	struct rkgpio_softc *sc = cookie;
227 	uint32_t pin = cells[0];
228 	uint32_t flags = cells[1];
229 	uint32_t reg;
230 	int val;
231 
232 	if (pin >= GPIO_NUM_PINS)
233 		return 0;
234 
235 	if (sc->sc_version == 2)
236 		reg = HREAD4(sc, GPIO_EXT_PORT);
237 	else
238 		reg = HREAD4(sc, GPIO_EXT_PORTA);
239 	val = (reg >> pin) & 1;
240 	if (flags & GPIO_ACTIVE_LOW)
241 		val = !val;
242 	return val;
243 }
244 
245 void
246 rkgpio_set_pin(void *cookie, uint32_t *cells, int val)
247 {
248 	struct rkgpio_softc *sc = cookie;
249 	uint32_t pin = cells[0];
250 	uint32_t flags = cells[1];
251 	uint32_t reg;
252 
253 	if (pin >= GPIO_NUM_PINS)
254 		return;
255 
256 	if (flags & GPIO_ACTIVE_LOW)
257 		val = !val;
258 	if (sc->sc_version == 2) {
259 		reg = (1 << (pin % 16)) << 16;
260 		if (val)
261 			reg |= (1 << (pin % 16));
262 		HWRITE4(sc, GPIO_SWPORT_DR_L + (pin / 16) * 4, reg);
263 	} else {
264 		if (val)
265 			HSET4(sc, GPIO_SWPORTA_DR, (1 << pin));
266 		else
267 			HCLR4(sc, GPIO_SWPORTA_DR, (1 << pin));
268 	}
269 }
270 
271 int
272 rkgpio_intr(void *cookie)
273 {
274 	struct rkgpio_softc	*sc = (struct rkgpio_softc *)cookie;
275 	struct intrhand		*ih;
276 	uint32_t		 status, pending;
277 	int			 pin, s;
278 
279 	status = HREAD4(sc, GPIO_INT_STATUS);
280 	pending = status;
281 
282 	while (pending) {
283 		pin = ffs(pending) - 1;
284 
285 		if ((ih = sc->sc_handlers[pin]) != NULL) {
286 			s = splraise(ih->ih_ipl);
287 			if (ih->ih_func(ih->ih_arg))
288 				ih->ih_count.ec_count++;
289 			splx(s);
290 		}
291 
292 		pending &= ~(1 << pin);
293 	}
294 
295 	HWRITE4(sc, GPIO_PORTS_EOI, status);
296 
297 	return 1;
298 }
299 
300 void *
301 rkgpio_intr_establish(void *cookie, int *cells, int ipl,
302     struct cpu_info *ci, int (*func)(void *), void *arg, char *name)
303 {
304 	struct rkgpio_softc *sc = (struct rkgpio_softc *)cookie;
305 	struct intrhand *ih;
306 	int irqno = cells[0];
307 	int level = cells[1];
308 	int s;
309 
310 	if (irqno < 0 || irqno >= GPIO_NUM_PINS)
311 		panic("%s: bogus irqnumber %d: %s", __func__,
312 		     irqno, name);
313 
314 	if (sc->sc_handlers[irqno] != NULL)
315 		panic("%s: irqnumber %d reused: %s", __func__,
316 		     irqno, name);
317 
318 	if (ci != NULL && !CPU_IS_PRIMARY(ci))
319 		return NULL;
320 
321 	ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK);
322 	ih->ih_func = func;
323 	ih->ih_arg = arg;
324 	ih->ih_ipl = ipl & IPL_IRQMASK;
325 	ih->ih_irq = irqno;
326 	ih->ih_name = name;
327 	ih->ih_level = level;
328 	ih->ih_sc = sc;
329 
330 	s = splhigh();
331 
332 	sc->sc_handlers[irqno] = ih;
333 
334 	if (name != NULL)
335 		evcount_attach(&ih->ih_count, name, &ih->ih_irq);
336 
337 #ifdef DEBUG_INTC
338 	printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl,
339 	    ih->ih_name);
340 #endif
341 
342 	rkgpio_recalc_ipl(sc);
343 
344 	if (sc->sc_version == 2) {
345 		uint32_t bit = (1 << (irqno % 16));
346 		uint32_t mask = bit << 16;
347 		bus_size_t off = (irqno / 16) * 4;
348 
349 		switch (level) {
350 		case 1: /* rising */
351 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask | bit);
352 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask | bit);
353 			break;
354 		case 2: /* falling */
355 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask | bit);
356 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask);
357 			break;
358 		case 4: /* high */
359 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask);
360 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask | bit);
361 			break;
362 		case 8: /* low */
363 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask);
364 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask);
365 			break;
366 		default:
367 			panic("%s: unsupported trigger type", __func__);
368 		}
369 
370 		HWRITE4(sc, GPIO_SWPORT_DDR_L + off, mask);
371 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask);
372 	} else {
373 		switch (level) {
374 		case 1: /* rising */
375 			HSET4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
376 			HSET4(sc, GPIO_INT_POLARITY, 1 << irqno);
377 			break;
378 		case 2: /* falling */
379 			HSET4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
380 			HCLR4(sc, GPIO_INT_POLARITY, 1 << irqno);
381 			break;
382 		case 4: /* high */
383 			HCLR4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
384 			HSET4(sc, GPIO_INT_POLARITY, 1 << irqno);
385 			break;
386 		case 8: /* low */
387 			HCLR4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
388 			HCLR4(sc, GPIO_INT_POLARITY, 1 << irqno);
389 			break;
390 		default:
391 			panic("%s: unsupported trigger type", __func__);
392 		}
393 
394 		HCLR4(sc, GPIO_SWPORTA_DDR, 1 << irqno);
395 		HCLR4(sc, GPIO_INTMASK, 1 << irqno);
396 	}
397 
398 	splx(s);
399 	return (ih);
400 }
401 
402 void
403 rkgpio_intr_disestablish(void *cookie)
404 {
405 	struct intrhand *ih = cookie;
406 	struct rkgpio_softc *sc = ih->ih_sc;
407 	uint32_t bit = (1 << (ih->ih_irq % 16));
408 	uint32_t mask = bit << 16;
409 	bus_size_t off = (ih->ih_irq / 16) * 4;
410 	int s;
411 
412 	s = splhigh();
413 
414 #ifdef DEBUG_INTC
415 	printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl,
416 	    ih->ih_name);
417 #endif
418 
419 	if (sc->sc_version == 2)
420 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask | bit);
421 	else
422 		HSET4(sc, GPIO_INTMASK, 1 << ih->ih_irq);
423 
424 	sc->sc_handlers[ih->ih_irq] = NULL;
425 	if (ih->ih_name != NULL)
426 		evcount_detach(&ih->ih_count);
427 	free(ih, M_DEVBUF, sizeof(*ih));
428 
429 	rkgpio_recalc_ipl(sc);
430 
431 	splx(s);
432 }
433 
434 void
435 rkgpio_recalc_ipl(struct rkgpio_softc *sc)
436 {
437 	struct intrhand	*ih;
438 	int max = IPL_NONE;
439 	int min = IPL_HIGH;
440 	int pin;
441 
442 	for (pin = 0; pin < GPIO_NUM_PINS; pin++) {
443 		ih = sc->sc_handlers[pin];
444 		if (ih == NULL)
445 			continue;
446 
447 		if (ih->ih_ipl > max)
448 			max = ih->ih_ipl;
449 
450 		if (ih->ih_ipl < min)
451 			min = ih->ih_ipl;
452 	}
453 
454 	if (max == IPL_NONE)
455 		min = IPL_NONE;
456 
457 	if (sc->sc_ipl != max) {
458 		sc->sc_ipl = max;
459 
460 		if (sc->sc_ih != NULL)
461 			fdt_intr_disestablish(sc->sc_ih);
462 
463 		if (sc->sc_ipl != IPL_NONE)
464 			sc->sc_ih = fdt_intr_establish(sc->sc_node,
465 			    sc->sc_ipl, rkgpio_intr, sc, sc->sc_dev.dv_xname);
466 	}
467 }
468 
469 void
470 rkgpio_intr_enable(void *cookie)
471 {
472 	struct intrhand	*ih = cookie;
473 	struct rkgpio_softc *sc = ih->ih_sc;
474 	uint32_t bit = (1 << (ih->ih_irq % 16));
475 	uint32_t mask = bit << 16;
476 	bus_size_t off = (ih->ih_irq / 16) * 4;
477 	int s;
478 
479 	s = splhigh();
480 	if (sc->sc_version == 2)
481 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask);
482 	else
483 		HCLR4(sc, GPIO_INTMASK, 1 << ih->ih_irq);
484 	splx(s);
485 }
486 
487 void
488 rkgpio_intr_disable(void *cookie)
489 {
490 	struct intrhand *ih = cookie;
491 	struct rkgpio_softc *sc = ih->ih_sc;
492 	uint32_t bit = (1 << (ih->ih_irq % 16));
493 	uint32_t mask = bit << 16;
494 	bus_size_t off = (ih->ih_irq / 16) * 4;
495 	int s;
496 
497 	s = splhigh();
498 	if (sc->sc_version == 2)
499 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask | bit);
500 	else
501 		HSET4(sc, GPIO_INTMASK, 1 << ih->ih_irq);
502 	splx(s);
503 }
504 
505 void
506 rkgpio_intr_barrier(void *cookie)
507 {
508 	struct intrhand *ih = cookie;
509 	struct rkgpio_softc *sc = ih->ih_sc;
510 
511 	intr_barrier(sc->sc_ih);
512 }
513