1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2013 Thomas Skibo
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 /*
30 * A GPIO driver for Xilinx Zynq-7000.
31 *
32 * The GPIO peripheral on Zynq allows controlling 114 general purpose I/Os.
33 *
34 * Pins 53-0 are sent to the MIO. Any MIO pins not used by a PS peripheral are
35 * available as a GPIO pin. Pins 64-127 are sent to the PL (FPGA) section of
36 * Zynq as EMIO signals.
37 *
38 * The hardware provides a way to use IOs as interrupt sources but the
39 * gpio framework doesn't seem to have hooks for this.
40 *
41 * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
42 * (v1.4) November 16, 2012. Xilinx doc UG585. GPIO is covered in
43 * chater 14. Register definitions are in appendix B.19.
44 */
45
46 #include <sys/cdefs.h>
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/conf.h>
50 #include <sys/bus.h>
51 #include <sys/kernel.h>
52 #include <sys/module.h>
53 #include <sys/lock.h>
54 #include <sys/mutex.h>
55 #include <sys/resource.h>
56 #include <sys/rman.h>
57 #include <sys/gpio.h>
58
59 #include <machine/bus.h>
60 #include <machine/resource.h>
61 #include <machine/stdarg.h>
62
63 #include <dev/gpio/gpiobusvar.h>
64 #include <dev/ofw/ofw_bus.h>
65 #include <dev/ofw/ofw_bus_subr.h>
66
67 #include "gpio_if.h"
68
69 #define ZYNQ7_MAX_BANK 4
70 #define ZYNQMP_MAX_BANK 6
71
72 /* Zynq 7000 */
73 #define ZYNQ7_BANK0_PIN_MIN 0
74 #define ZYNQ7_BANK0_NPIN 32
75 #define ZYNQ7_BANK1_PIN_MIN 32
76 #define ZYNQ7_BANK1_NPIN 22
77 #define ZYNQ7_BANK2_PIN_MIN 64
78 #define ZYNQ7_BANK2_NPIN 32
79 #define ZYNQ7_BANK3_PIN_MIN 96
80 #define ZYNQ7_BANK3_NPIN 32
81 #define ZYNQ7_PIN_MIO_MIN 0
82 #define ZYNQ7_PIN_MIO_MAX 54
83 #define ZYNQ7_PIN_EMIO_MIN 64
84 #define ZYNQ7_PIN_EMIO_MAX 118
85
86 /* ZynqMP */
87 #define ZYNQMP_BANK0_PIN_MIN 0
88 #define ZYNQMP_BANK0_NPIN 26
89 #define ZYNQMP_BANK1_PIN_MIN 26
90 #define ZYNQMP_BANK1_NPIN 26
91 #define ZYNQMP_BANK2_PIN_MIN 52
92 #define ZYNQMP_BANK2_NPIN 26
93 #define ZYNQMP_BANK3_PIN_MIN 78
94 #define ZYNQMP_BANK3_NPIN 32
95 #define ZYNQMP_BANK4_PIN_MIN 110
96 #define ZYNQMP_BANK4_NPIN 32
97 #define ZYNQMP_BANK5_PIN_MIN 142
98 #define ZYNQMP_BANK5_NPIN 32
99 #define ZYNQMP_PIN_MIO_MIN 0
100 #define ZYNQMP_PIN_MIO_MAX 77
101 #define ZYNQMP_PIN_EMIO_MIN 78
102 #define ZYNQMP_PIN_EMIO_MAX 174
103
104 #define ZYNQ_BANK_NPIN(type, bank) (ZYNQ##type##_BANK##bank##_NPIN)
105 #define ZYNQ_BANK_PIN_MIN(type, bank) (ZYNQ##type##_BANK##bank##_PIN_MIN)
106 #define ZYNQ_BANK_PIN_MAX(type, bank) (ZYNQ##type##_BANK##bank##_PIN_MIN + ZYNQ##type##_BANK##bank##_NPIN - 1)
107
108 #define ZYNQ_PIN_IS_MIO(type, pin) (pin >= ZYNQ##type##_PIN_MIO_MIN && \
109 pin <= ZYNQ##type##_PIN_MIO_MAX)
110 #define ZYNQ_PIN_IS_EMIO(type, pin) (pin >= ZYNQ##type##_PIN_EMIO_MIN && \
111 pin <= ZYNQ##type##_PIN_EMIO_MAX)
112
113 #define ZGPIO_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
114 #define ZGPIO_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
115 #define ZGPIO_LOCK_INIT(sc) \
116 mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), \
117 "gpio", MTX_DEF)
118 #define ZGPIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
119
120 enum zynq_gpio_type {
121 ZYNQ_7000 = 0,
122 ZYNQMP,
123 };
124
125 struct zynq_gpio_conf {
126 char *name;
127 enum zynq_gpio_type type;
128 uint32_t nbanks;
129 uint32_t maxpin;
130 uint32_t bank_min[ZYNQMP_MAX_BANK];
131 uint32_t bank_max[ZYNQMP_MAX_BANK];
132 };
133
134 struct zy7_gpio_softc {
135 device_t dev;
136 device_t busdev;
137 struct mtx sc_mtx;
138 struct resource *mem_res; /* Memory resource */
139 struct zynq_gpio_conf *conf;
140 };
141
142 static struct zynq_gpio_conf z7_gpio_conf = {
143 .name = "Zynq-7000 GPIO Controller",
144 .type = ZYNQ_7000,
145 .nbanks = ZYNQ7_MAX_BANK,
146 .maxpin = ZYNQ7_PIN_EMIO_MAX,
147 .bank_min[0] = ZYNQ_BANK_PIN_MIN(7, 0),
148 .bank_max[0] = ZYNQ_BANK_PIN_MAX(7, 0),
149 .bank_min[1] = ZYNQ_BANK_PIN_MIN(7, 1),
150 .bank_max[1] = ZYNQ_BANK_PIN_MAX(7, 1),
151 .bank_min[2] = ZYNQ_BANK_PIN_MIN(7, 2),
152 .bank_max[2] = ZYNQ_BANK_PIN_MAX(7, 2),
153 .bank_min[3] = ZYNQ_BANK_PIN_MIN(7, 3),
154 .bank_max[3] = ZYNQ_BANK_PIN_MAX(7, 3),
155 };
156
157 static struct zynq_gpio_conf zynqmp_gpio_conf = {
158 .name = "ZynqMP GPIO Controller",
159 .type = ZYNQMP,
160 .nbanks = ZYNQMP_MAX_BANK,
161 .maxpin = ZYNQMP_PIN_EMIO_MAX,
162 .bank_min[0] = ZYNQ_BANK_PIN_MIN(MP, 0),
163 .bank_max[0] = ZYNQ_BANK_PIN_MAX(MP, 0),
164 .bank_min[1] = ZYNQ_BANK_PIN_MIN(MP, 1),
165 .bank_max[1] = ZYNQ_BANK_PIN_MAX(MP, 1),
166 .bank_min[2] = ZYNQ_BANK_PIN_MIN(MP, 2),
167 .bank_max[2] = ZYNQ_BANK_PIN_MAX(MP, 2),
168 .bank_min[3] = ZYNQ_BANK_PIN_MIN(MP, 3),
169 .bank_max[3] = ZYNQ_BANK_PIN_MAX(MP, 3),
170 .bank_min[4] = ZYNQ_BANK_PIN_MIN(MP, 4),
171 .bank_max[4] = ZYNQ_BANK_PIN_MAX(MP, 4),
172 .bank_min[5] = ZYNQ_BANK_PIN_MIN(MP, 5),
173 .bank_max[5] = ZYNQ_BANK_PIN_MAX(MP, 5),
174 };
175
176 static struct ofw_compat_data compat_data[] = {
177 {"xlnx,zy7_gpio", (uintptr_t)&z7_gpio_conf},
178 {"xlnx,zynqmp-gpio-1.0", (uintptr_t)&zynqmp_gpio_conf},
179 {NULL, 0},
180 };
181
182 #define WR4(sc, off, val) bus_write_4((sc)->mem_res, (off), (val))
183 #define RD4(sc, off) bus_read_4((sc)->mem_res, (off))
184
185 /* Xilinx Zynq-7000 GPIO register definitions:
186 */
187 #define ZY7_GPIO_MASK_DATA_LSW(b) (0x0000+8*(b)) /* maskable wr lo */
188 #define ZY7_GPIO_MASK_DATA_MSW(b) (0x0004+8*(b)) /* maskable wr hi */
189 #define ZY7_GPIO_DATA(b) (0x0040+4*(b)) /* in/out data */
190 #define ZY7_GPIO_DATA_RO(b) (0x0060+4*(b)) /* input data */
191
192 #define ZY7_GPIO_DIRM(b) (0x0204+0x40*(b)) /* direction mode */
193 #define ZY7_GPIO_OEN(b) (0x0208+0x40*(b)) /* output enable */
194 #define ZY7_GPIO_INT_MASK(b) (0x020c+0x40*(b)) /* int mask */
195 #define ZY7_GPIO_INT_EN(b) (0x0210+0x40*(b)) /* int enable */
196 #define ZY7_GPIO_INT_DIS(b) (0x0214+0x40*(b)) /* int disable */
197 #define ZY7_GPIO_INT_STAT(b) (0x0218+0x40*(b)) /* int status */
198 #define ZY7_GPIO_INT_TYPE(b) (0x021c+0x40*(b)) /* int type */
199 #define ZY7_GPIO_INT_POLARITY(b) (0x0220+0x40*(b)) /* int polarity */
200 #define ZY7_GPIO_INT_ANY(b) (0x0224+0x40*(b)) /* any edge */
201
202 static device_t
zy7_gpio_get_bus(device_t dev)203 zy7_gpio_get_bus(device_t dev)
204 {
205 struct zy7_gpio_softc *sc;
206
207 sc = device_get_softc(dev);
208
209 return (sc->busdev);
210 }
211
212 static int
zy7_gpio_pin_max(device_t dev,int * maxpin)213 zy7_gpio_pin_max(device_t dev, int *maxpin)
214 {
215 struct zy7_gpio_softc *sc;
216
217 sc = device_get_softc(dev);
218 *maxpin = sc->conf->maxpin;
219 return (0);
220 }
221
222 static inline bool
zy7_pin_valid(device_t dev,uint32_t pin)223 zy7_pin_valid(device_t dev, uint32_t pin)
224 {
225 struct zy7_gpio_softc *sc;
226 int i;
227 bool found = false;
228
229 sc = device_get_softc(dev);
230 for (i = 0; i < sc->conf->nbanks; i++) {
231 if (pin >= sc->conf->bank_min[i] && pin <= sc->conf->bank_max[i]) {
232 found = true;
233 break;
234 }
235 }
236
237 return (found);
238 }
239
240 /* Get a specific pin's capabilities. */
241 static int
zy7_gpio_pin_getcaps(device_t dev,uint32_t pin,uint32_t * caps)242 zy7_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
243 {
244
245 if (!zy7_pin_valid(dev, pin))
246 return (EINVAL);
247
248 *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
249
250 return (0);
251 }
252
253 /* Get a specific pin's name. */
254 static int
zy7_gpio_pin_getname(device_t dev,uint32_t pin,char * name)255 zy7_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
256 {
257 struct zy7_gpio_softc *sc;
258 uint32_t emio_min;
259 bool is_mio;
260
261 sc = device_get_softc(dev);
262 if (!zy7_pin_valid(dev, pin))
263 return (EINVAL);
264
265 switch (sc->conf->type) {
266 case ZYNQ_7000:
267 is_mio = ZYNQ_PIN_IS_MIO(7, pin);
268 emio_min = ZYNQ7_PIN_EMIO_MIN;
269 break;
270 case ZYNQMP:
271 is_mio = ZYNQ_PIN_IS_MIO(MP, pin);
272 emio_min = ZYNQMP_PIN_EMIO_MIN;
273 break;
274 default:
275 return (EINVAL);
276 }
277 if (is_mio) {
278 snprintf(name, GPIOMAXNAME, "MIO_%d", pin);
279 name[GPIOMAXNAME - 1] = '\0';
280 } else {
281 snprintf(name, GPIOMAXNAME, "EMIO_%d", pin - emio_min);
282 name[GPIOMAXNAME - 1] = '\0';
283 }
284
285 return (0);
286 }
287
288 /* Get a specific pin's current in/out/tri state. */
289 static int
zy7_gpio_pin_getflags(device_t dev,uint32_t pin,uint32_t * flags)290 zy7_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
291 {
292 struct zy7_gpio_softc *sc = device_get_softc(dev);
293
294 if (!zy7_pin_valid(dev, pin))
295 return (EINVAL);
296
297 ZGPIO_LOCK(sc);
298
299 if ((RD4(sc, ZY7_GPIO_DIRM(pin >> 5)) & (1 << (pin & 31))) != 0) {
300 /* output */
301 if ((RD4(sc, ZY7_GPIO_OEN(pin >> 5)) & (1 << (pin & 31))) == 0)
302 *flags = (GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
303 else
304 *flags = GPIO_PIN_OUTPUT;
305 } else
306 /* input */
307 *flags = GPIO_PIN_INPUT;
308
309 ZGPIO_UNLOCK(sc);
310
311 return (0);
312 }
313
314 /* Set a specific pin's in/out/tri state. */
315 static int
zy7_gpio_pin_setflags(device_t dev,uint32_t pin,uint32_t flags)316 zy7_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
317 {
318 struct zy7_gpio_softc *sc = device_get_softc(dev);
319
320 if (!zy7_pin_valid(dev, pin))
321 return (EINVAL);
322
323 ZGPIO_LOCK(sc);
324
325 if ((flags & GPIO_PIN_OUTPUT) != 0) {
326 /* Output. Set or reset OEN too. */
327 WR4(sc, ZY7_GPIO_DIRM(pin >> 5),
328 RD4(sc, ZY7_GPIO_DIRM(pin >> 5)) | (1 << (pin & 31)));
329
330 if ((flags & GPIO_PIN_TRISTATE) != 0)
331 WR4(sc, ZY7_GPIO_OEN(pin >> 5),
332 RD4(sc, ZY7_GPIO_OEN(pin >> 5)) &
333 ~(1 << (pin & 31)));
334 else
335 WR4(sc, ZY7_GPIO_OEN(pin >> 5),
336 RD4(sc, ZY7_GPIO_OEN(pin >> 5)) |
337 (1 << (pin & 31)));
338 } else {
339 /* Input. Turn off OEN. */
340 WR4(sc, ZY7_GPIO_DIRM(pin >> 5),
341 RD4(sc, ZY7_GPIO_DIRM(pin >> 5)) & ~(1 << (pin & 31)));
342 WR4(sc, ZY7_GPIO_OEN(pin >> 5),
343 RD4(sc, ZY7_GPIO_OEN(pin >> 5)) & ~(1 << (pin & 31)));
344 }
345
346 ZGPIO_UNLOCK(sc);
347
348 return (0);
349 }
350
351 /* Set a specific output pin's value. */
352 static int
zy7_gpio_pin_set(device_t dev,uint32_t pin,unsigned int value)353 zy7_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
354 {
355 struct zy7_gpio_softc *sc = device_get_softc(dev);
356
357 if (!zy7_pin_valid(dev, pin) || value > 1)
358 return (EINVAL);
359
360 /* Fancy register tricks allow atomic set or reset. */
361 if ((pin & 16) != 0)
362 WR4(sc, ZY7_GPIO_MASK_DATA_MSW(pin >> 5),
363 (0xffff0000 ^ (0x10000 << (pin & 15))) |
364 (value << (pin & 15)));
365 else
366 WR4(sc, ZY7_GPIO_MASK_DATA_LSW(pin >> 5),
367 (0xffff0000 ^ (0x10000 << (pin & 15))) |
368 (value << (pin & 15)));
369
370 return (0);
371 }
372
373 /* Get a specific pin's input value. */
374 static int
zy7_gpio_pin_get(device_t dev,uint32_t pin,unsigned int * value)375 zy7_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
376 {
377 struct zy7_gpio_softc *sc = device_get_softc(dev);
378
379 if (!zy7_pin_valid(dev, pin))
380 return (EINVAL);
381
382 *value = (RD4(sc, ZY7_GPIO_DATA_RO(pin >> 5)) >> (pin & 31)) & 1;
383
384 return (0);
385 }
386
387 /* Toggle a pin's output value. */
388 static int
zy7_gpio_pin_toggle(device_t dev,uint32_t pin)389 zy7_gpio_pin_toggle(device_t dev, uint32_t pin)
390 {
391 struct zy7_gpio_softc *sc = device_get_softc(dev);
392
393 if (!zy7_pin_valid(dev, pin))
394 return (EINVAL);
395
396 ZGPIO_LOCK(sc);
397
398 WR4(sc, ZY7_GPIO_DATA(pin >> 5),
399 RD4(sc, ZY7_GPIO_DATA(pin >> 5)) ^ (1 << (pin & 31)));
400
401 ZGPIO_UNLOCK(sc);
402
403 return (0);
404 }
405
406 static int
zy7_gpio_probe(device_t dev)407 zy7_gpio_probe(device_t dev)
408 {
409 struct zynq_gpio_conf *conf;
410
411 if (!ofw_bus_status_okay(dev))
412 return (ENXIO);
413
414 conf = (struct zynq_gpio_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
415 if (conf == 0)
416 return (ENXIO);
417
418 device_set_desc(dev, conf->name);
419 return (0);
420 }
421
422 static int zy7_gpio_detach(device_t dev);
423
424 static int
zy7_gpio_attach(device_t dev)425 zy7_gpio_attach(device_t dev)
426 {
427 struct zy7_gpio_softc *sc = device_get_softc(dev);
428 int rid;
429
430 sc->dev = dev;
431 sc->conf = (struct zynq_gpio_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
432
433 ZGPIO_LOCK_INIT(sc);
434
435 /* Allocate memory. */
436 rid = 0;
437 sc->mem_res = bus_alloc_resource_any(dev,
438 SYS_RES_MEMORY, &rid, RF_ACTIVE);
439 if (sc->mem_res == NULL) {
440 device_printf(dev, "Can't allocate memory for device");
441 zy7_gpio_detach(dev);
442 return (ENOMEM);
443 }
444
445 sc->busdev = gpiobus_attach_bus(dev);
446 if (sc->busdev == NULL) {
447 zy7_gpio_detach(dev);
448 return (ENOMEM);
449 }
450
451 return (0);
452 }
453
454 static int
zy7_gpio_detach(device_t dev)455 zy7_gpio_detach(device_t dev)
456 {
457 struct zy7_gpio_softc *sc = device_get_softc(dev);
458
459 gpiobus_detach_bus(dev);
460
461 if (sc->mem_res != NULL) {
462 /* Release memory resource. */
463 bus_release_resource(dev, SYS_RES_MEMORY,
464 rman_get_rid(sc->mem_res), sc->mem_res);
465 }
466
467 ZGPIO_LOCK_DESTROY(sc);
468
469 return (0);
470 }
471
472 static device_method_t zy7_gpio_methods[] = {
473 /* device_if */
474 DEVMETHOD(device_probe, zy7_gpio_probe),
475 DEVMETHOD(device_attach, zy7_gpio_attach),
476 DEVMETHOD(device_detach, zy7_gpio_detach),
477
478 /* GPIO protocol */
479 DEVMETHOD(gpio_get_bus, zy7_gpio_get_bus),
480 DEVMETHOD(gpio_pin_max, zy7_gpio_pin_max),
481 DEVMETHOD(gpio_pin_getname, zy7_gpio_pin_getname),
482 DEVMETHOD(gpio_pin_getflags, zy7_gpio_pin_getflags),
483 DEVMETHOD(gpio_pin_getcaps, zy7_gpio_pin_getcaps),
484 DEVMETHOD(gpio_pin_setflags, zy7_gpio_pin_setflags),
485 DEVMETHOD(gpio_pin_get, zy7_gpio_pin_get),
486 DEVMETHOD(gpio_pin_set, zy7_gpio_pin_set),
487 DEVMETHOD(gpio_pin_toggle, zy7_gpio_pin_toggle),
488
489 DEVMETHOD_END
490 };
491
492 static driver_t zy7_gpio_driver = {
493 "gpio",
494 zy7_gpio_methods,
495 sizeof(struct zy7_gpio_softc),
496 };
497
498 EARLY_DRIVER_MODULE(zy7_gpio, simplebus, zy7_gpio_driver, 0, 0,
499 BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
500