xref: /openbsd/sys/dev/fdt/rkgpio.c (revision 80663c26)
1 /*	$OpenBSD: rkgpio.c,v 1.11 2023/07/10 13:48:02 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_INT_STATUS_V2	0x0050
60 #define GPIO_PORT_EOI_L		0x0060
61 #define GPIO_PORT_EOI_H		0x0064
62 #define GPIO_EXT_PORT		0x0070
63 #define GPIO_VER_ID		0x0078
64 #define  GPIO_VER_ID_1_0	0x00000000
65 #define  GPIO_VER_ID_2_0	0x01000c2b
66 #define  GPIO_VER_ID_2_1	0x0101157c
67 
68 #define GPIO_NUM_PINS		32
69 
70 #define HREAD4(sc, reg)							\
71 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
72 #define HWRITE4(sc, reg, val)						\
73 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
74 #define HSET4(sc, reg, bits)						\
75 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
76 #define HCLR4(sc, reg, bits)						\
77 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
78 
79 struct intrhand {
80 	int (*ih_func)(void *);		/* handler */
81 	void *ih_arg;			/* arg for handler */
82 	int ih_ipl;			/* IPL_* */
83 	int ih_irq;			/* IRQ number */
84 	int ih_level;			/* GPIO level */
85 	struct evcount	ih_count;
86 	char *ih_name;
87 	void *ih_sc;
88 };
89 
90 struct rkgpio_softc {
91 	struct device		sc_dev;
92 	bus_space_tag_t		sc_iot;
93 	bus_space_handle_t	sc_ioh;
94 	int			sc_node;
95 	int			sc_version;
96 
97 	void			*sc_ih;
98 	int			sc_ipl;
99 	int			sc_irq;
100 	struct intrhand		*sc_handlers[GPIO_NUM_PINS];
101 	struct interrupt_controller sc_ic;
102 
103 	struct gpio_controller	sc_gc;
104 };
105 
106 int rkgpio_match(struct device *, void *, void *);
107 void rkgpio_attach(struct device *, struct device *, void *);
108 
109 const struct cfattach	rkgpio_ca = {
110 	sizeof (struct rkgpio_softc), rkgpio_match, rkgpio_attach
111 };
112 
113 struct cfdriver rkgpio_cd = {
114 	NULL, "rkgpio", DV_DULL
115 };
116 
117 void	rkgpio_config_pin(void *, uint32_t *, int);
118 int	rkgpio_get_pin(void *, uint32_t *);
119 void	rkgpio_set_pin(void *, uint32_t *, int);
120 
121 int	rkgpio_intr(void *);
122 void	*rkgpio_intr_establish(void *, int *, int, struct cpu_info *,
123 	    int (*)(void *), void *, char *);
124 void	rkgpio_intr_disestablish(void *);
125 void	rkgpio_recalc_ipl(struct rkgpio_softc *);
126 void	rkgpio_intr_enable(void *);
127 void	rkgpio_intr_disable(void *);
128 void	rkgpio_intr_barrier(void *);
129 
130 int
rkgpio_match(struct device * parent,void * match,void * aux)131 rkgpio_match(struct device *parent, void *match, void *aux)
132 {
133 	struct fdt_attach_args *faa = aux;
134 
135 	return OF_is_compatible(faa->fa_node, "rockchip,gpio-bank");
136 }
137 
138 void
rkgpio_attach(struct device * parent,struct device * self,void * aux)139 rkgpio_attach(struct device *parent, struct device *self, void *aux)
140 {
141 	struct rkgpio_softc *sc = (struct rkgpio_softc *)self;
142 	struct fdt_attach_args *faa = aux;
143 	uint32_t ver_id;
144 
145 	if (faa->fa_nreg < 1) {
146 		printf(": no registers\n");
147 		return;
148 	}
149 
150 	sc->sc_node = faa->fa_node;
151 	sc->sc_iot = faa->fa_iot;
152 
153 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
154 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
155 		printf(": can't map registers\n");
156 		return;
157 	}
158 
159 	ver_id = HREAD4(sc, GPIO_VER_ID);
160 	switch (ver_id) {
161 	case GPIO_VER_ID_1_0:
162 		sc->sc_version = 1;
163 		break;
164 	case GPIO_VER_ID_2_0:
165 	case GPIO_VER_ID_2_1:
166 		sc->sc_version = 2;
167 		break;
168 	default:
169 		printf(": unknown version 0x%08x\n", ver_id);
170 		return;
171 	}
172 
173 	sc->sc_gc.gc_node = faa->fa_node;
174 	sc->sc_gc.gc_cookie = sc;
175 	sc->sc_gc.gc_config_pin = rkgpio_config_pin;
176 	sc->sc_gc.gc_get_pin = rkgpio_get_pin;
177 	sc->sc_gc.gc_set_pin = rkgpio_set_pin;
178 	gpio_controller_register(&sc->sc_gc);
179 
180 	sc->sc_ipl = IPL_NONE;
181 	if (sc->sc_version == 2) {
182 		HWRITE4(sc, GPIO_INT_MASK_L, ~0);
183 		HWRITE4(sc, GPIO_INT_MASK_H, ~0);
184 		HWRITE4(sc, GPIO_INT_EN_L, ~0);
185 		HWRITE4(sc, GPIO_INT_EN_H, ~0);
186 	} else {
187 		HWRITE4(sc, GPIO_INTMASK, ~0);
188 		HWRITE4(sc, GPIO_INTEN, ~0);
189 	}
190 
191 	sc->sc_ic.ic_node = faa->fa_node;
192 	sc->sc_ic.ic_cookie = sc;
193 	sc->sc_ic.ic_establish = rkgpio_intr_establish;
194 	sc->sc_ic.ic_disestablish = rkgpio_intr_disestablish;
195 	sc->sc_ic.ic_enable = rkgpio_intr_enable;
196 	sc->sc_ic.ic_disable = rkgpio_intr_disable;
197 	sc->sc_ic.ic_barrier = rkgpio_intr_barrier;
198 	fdt_intr_register(&sc->sc_ic);
199 
200 	printf("\n");
201 }
202 
203 void
rkgpio_config_pin(void * cookie,uint32_t * cells,int config)204 rkgpio_config_pin(void *cookie, uint32_t *cells, int config)
205 {
206 	struct rkgpio_softc *sc = cookie;
207 	uint32_t pin = cells[0];
208 	uint32_t reg;
209 
210 	if (pin >= GPIO_NUM_PINS)
211 		return;
212 
213 	if (sc->sc_version == 2) {
214 		reg = (1 << (pin % 16)) << 16;
215 		if (config & GPIO_CONFIG_OUTPUT)
216 			reg |= (1 << (pin % 16));
217 		HWRITE4(sc, GPIO_SWPORT_DDR_L + (pin / 16) * 4, reg);
218 	} else {
219 		if (config & GPIO_CONFIG_OUTPUT)
220 			HSET4(sc, GPIO_SWPORTA_DDR, (1 << pin));
221 		else
222 			HCLR4(sc, GPIO_SWPORTA_DDR, (1 << pin));
223 	}
224 }
225 
226 int
rkgpio_get_pin(void * cookie,uint32_t * cells)227 rkgpio_get_pin(void *cookie, uint32_t *cells)
228 {
229 	struct rkgpio_softc *sc = cookie;
230 	uint32_t pin = cells[0];
231 	uint32_t flags = cells[1];
232 	uint32_t reg;
233 	int val;
234 
235 	if (pin >= GPIO_NUM_PINS)
236 		return 0;
237 
238 	if (sc->sc_version == 2)
239 		reg = HREAD4(sc, GPIO_EXT_PORT);
240 	else
241 		reg = HREAD4(sc, GPIO_EXT_PORTA);
242 	val = (reg >> pin) & 1;
243 	if (flags & GPIO_ACTIVE_LOW)
244 		val = !val;
245 	return val;
246 }
247 
248 void
rkgpio_set_pin(void * cookie,uint32_t * cells,int val)249 rkgpio_set_pin(void *cookie, uint32_t *cells, int val)
250 {
251 	struct rkgpio_softc *sc = cookie;
252 	uint32_t pin = cells[0];
253 	uint32_t flags = cells[1];
254 	uint32_t reg;
255 
256 	if (pin >= GPIO_NUM_PINS)
257 		return;
258 
259 	if (flags & GPIO_ACTIVE_LOW)
260 		val = !val;
261 	if (sc->sc_version == 2) {
262 		reg = (1 << (pin % 16)) << 16;
263 		if (val)
264 			reg |= (1 << (pin % 16));
265 		HWRITE4(sc, GPIO_SWPORT_DR_L + (pin / 16) * 4, reg);
266 	} else {
267 		if (val)
268 			HSET4(sc, GPIO_SWPORTA_DR, (1 << pin));
269 		else
270 			HCLR4(sc, GPIO_SWPORTA_DR, (1 << pin));
271 	}
272 }
273 
274 int
rkgpio_intr(void * cookie)275 rkgpio_intr(void *cookie)
276 {
277 	struct rkgpio_softc	*sc = (struct rkgpio_softc *)cookie;
278 	struct intrhand		*ih;
279 	uint32_t		 status, pending;
280 	int			 pin, s;
281 
282 	if (sc->sc_version == 2)
283 		status = HREAD4(sc, GPIO_INT_STATUS_V2);
284 	else
285 		status = HREAD4(sc, GPIO_INT_STATUS);
286 	pending = status;
287 
288 	while (pending) {
289 		pin = ffs(pending) - 1;
290 
291 		if ((ih = sc->sc_handlers[pin]) != NULL) {
292 			s = splraise(ih->ih_ipl);
293 			if (ih->ih_func(ih->ih_arg))
294 				ih->ih_count.ec_count++;
295 			splx(s);
296 		}
297 
298 		pending &= ~(1 << pin);
299 	}
300 
301 	if (sc->sc_version == 2) {
302 		HWRITE4(sc, GPIO_PORT_EOI_L,
303 		    (status & 0xffff) << 16 | (status & 0xffff));
304 		HWRITE4(sc, GPIO_PORT_EOI_H,
305 		    status >> 16 | (status & 0xffff0000));
306 	} else
307 		HWRITE4(sc, GPIO_PORTS_EOI, status);
308 
309 	return 1;
310 }
311 
312 void *
rkgpio_intr_establish(void * cookie,int * cells,int ipl,struct cpu_info * ci,int (* func)(void *),void * arg,char * name)313 rkgpio_intr_establish(void *cookie, int *cells, int ipl,
314     struct cpu_info *ci, int (*func)(void *), void *arg, char *name)
315 {
316 	struct rkgpio_softc *sc = (struct rkgpio_softc *)cookie;
317 	struct intrhand *ih;
318 	int irqno = cells[0];
319 	int level = cells[1];
320 	int s;
321 
322 	if (irqno < 0 || irqno >= GPIO_NUM_PINS)
323 		panic("%s: bogus irqnumber %d: %s", __func__,
324 		     irqno, name);
325 
326 	if (sc->sc_handlers[irqno] != NULL)
327 		panic("%s: irqnumber %d reused: %s", __func__,
328 		     irqno, name);
329 
330 	if (ci != NULL && !CPU_IS_PRIMARY(ci))
331 		return NULL;
332 
333 	ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK);
334 	ih->ih_func = func;
335 	ih->ih_arg = arg;
336 	ih->ih_ipl = ipl & IPL_IRQMASK;
337 	ih->ih_irq = irqno;
338 	ih->ih_name = name;
339 	ih->ih_level = level;
340 	ih->ih_sc = sc;
341 
342 	s = splhigh();
343 
344 	sc->sc_handlers[irqno] = ih;
345 
346 	if (name != NULL)
347 		evcount_attach(&ih->ih_count, name, &ih->ih_irq);
348 
349 #ifdef DEBUG_INTC
350 	printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl,
351 	    ih->ih_name);
352 #endif
353 
354 	rkgpio_recalc_ipl(sc);
355 
356 	if (sc->sc_version == 2) {
357 		uint32_t bit = (1 << (irqno % 16));
358 		uint32_t mask = bit << 16;
359 		bus_size_t off = (irqno / 16) * 4;
360 
361 		switch (level) {
362 		case 1: /* rising */
363 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask | bit);
364 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask | bit);
365 			break;
366 		case 2: /* falling */
367 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask | bit);
368 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask);
369 			break;
370 		case 4: /* high */
371 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask);
372 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask | bit);
373 			break;
374 		case 8: /* low */
375 			HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask);
376 			HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask);
377 			break;
378 		default:
379 			panic("%s: unsupported trigger type", __func__);
380 		}
381 
382 		HWRITE4(sc, GPIO_SWPORT_DDR_L + off, mask);
383 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask);
384 	} else {
385 		switch (level) {
386 		case 1: /* rising */
387 			HSET4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
388 			HSET4(sc, GPIO_INT_POLARITY, 1 << irqno);
389 			break;
390 		case 2: /* falling */
391 			HSET4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
392 			HCLR4(sc, GPIO_INT_POLARITY, 1 << irqno);
393 			break;
394 		case 4: /* high */
395 			HCLR4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
396 			HSET4(sc, GPIO_INT_POLARITY, 1 << irqno);
397 			break;
398 		case 8: /* low */
399 			HCLR4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno);
400 			HCLR4(sc, GPIO_INT_POLARITY, 1 << irqno);
401 			break;
402 		default:
403 			panic("%s: unsupported trigger type", __func__);
404 		}
405 
406 		HCLR4(sc, GPIO_SWPORTA_DDR, 1 << irqno);
407 		HCLR4(sc, GPIO_INTMASK, 1 << irqno);
408 	}
409 
410 	splx(s);
411 	return (ih);
412 }
413 
414 void
rkgpio_intr_disestablish(void * cookie)415 rkgpio_intr_disestablish(void *cookie)
416 {
417 	struct intrhand *ih = cookie;
418 	struct rkgpio_softc *sc = ih->ih_sc;
419 	uint32_t bit = (1 << (ih->ih_irq % 16));
420 	uint32_t mask = bit << 16;
421 	bus_size_t off = (ih->ih_irq / 16) * 4;
422 	int s;
423 
424 	s = splhigh();
425 
426 #ifdef DEBUG_INTC
427 	printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl,
428 	    ih->ih_name);
429 #endif
430 
431 	if (sc->sc_version == 2)
432 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask | bit);
433 	else
434 		HSET4(sc, GPIO_INTMASK, 1 << ih->ih_irq);
435 
436 	sc->sc_handlers[ih->ih_irq] = NULL;
437 	if (ih->ih_name != NULL)
438 		evcount_detach(&ih->ih_count);
439 	free(ih, M_DEVBUF, sizeof(*ih));
440 
441 	rkgpio_recalc_ipl(sc);
442 
443 	splx(s);
444 }
445 
446 void
rkgpio_recalc_ipl(struct rkgpio_softc * sc)447 rkgpio_recalc_ipl(struct rkgpio_softc *sc)
448 {
449 	struct intrhand	*ih;
450 	int max = IPL_NONE;
451 	int min = IPL_HIGH;
452 	int pin;
453 
454 	for (pin = 0; pin < GPIO_NUM_PINS; pin++) {
455 		ih = sc->sc_handlers[pin];
456 		if (ih == NULL)
457 			continue;
458 
459 		if (ih->ih_ipl > max)
460 			max = ih->ih_ipl;
461 
462 		if (ih->ih_ipl < min)
463 			min = ih->ih_ipl;
464 	}
465 
466 	if (max == IPL_NONE)
467 		min = IPL_NONE;
468 
469 	if (sc->sc_ipl != max) {
470 		sc->sc_ipl = max;
471 
472 		if (sc->sc_ih != NULL)
473 			fdt_intr_disestablish(sc->sc_ih);
474 
475 		if (sc->sc_ipl != IPL_NONE)
476 			sc->sc_ih = fdt_intr_establish(sc->sc_node,
477 			    sc->sc_ipl, rkgpio_intr, sc, sc->sc_dev.dv_xname);
478 	}
479 }
480 
481 void
rkgpio_intr_enable(void * cookie)482 rkgpio_intr_enable(void *cookie)
483 {
484 	struct intrhand	*ih = cookie;
485 	struct rkgpio_softc *sc = ih->ih_sc;
486 	uint32_t bit = (1 << (ih->ih_irq % 16));
487 	uint32_t mask = bit << 16;
488 	bus_size_t off = (ih->ih_irq / 16) * 4;
489 	int s;
490 
491 	s = splhigh();
492 	if (sc->sc_version == 2)
493 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask);
494 	else
495 		HCLR4(sc, GPIO_INTMASK, 1 << ih->ih_irq);
496 	splx(s);
497 }
498 
499 void
rkgpio_intr_disable(void * cookie)500 rkgpio_intr_disable(void *cookie)
501 {
502 	struct intrhand *ih = cookie;
503 	struct rkgpio_softc *sc = ih->ih_sc;
504 	uint32_t bit = (1 << (ih->ih_irq % 16));
505 	uint32_t mask = bit << 16;
506 	bus_size_t off = (ih->ih_irq / 16) * 4;
507 	int s;
508 
509 	s = splhigh();
510 	if (sc->sc_version == 2)
511 		HWRITE4(sc, GPIO_INT_MASK_L + off, mask | bit);
512 	else
513 		HSET4(sc, GPIO_INTMASK, 1 << ih->ih_irq);
514 	splx(s);
515 }
516 
517 void
rkgpio_intr_barrier(void * cookie)518 rkgpio_intr_barrier(void *cookie)
519 {
520 	struct intrhand *ih = cookie;
521 	struct rkgpio_softc *sc = ih->ih_sc;
522 
523 	intr_barrier(sc->sc_ih);
524 }
525