]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/qoriq/ls1046_gpio.c
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / sys / arm64 / qoriq / ls1046_gpio.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2020 Alstom Group.
5  * Copyright (c) 2020 Semihalf.
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 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33
34 #include <sys/bus.h>
35 #include <sys/endian.h>
36 #include <sys/gpio.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/mutex.h>
40
41 #include <dev/gpio/gpiobusvar.h>
42 #include <dev/ofw/ofw_bus.h>
43 #include <machine/bus.h>
44
45 #include "gpio_if.h"
46
47 /* constants */
48 enum {
49         DIRECTION  = 0x0,
50         OPEN_DRAIN = 0x4,
51         DATA       = 0x8,
52         INT_EV     = 0xC,
53         INT_MASK   = 0x10,
54         INT_CTRL   = 0x14
55 };
56
57 #define PIN_COUNT 32
58 #define DEFAULT_CAPS                            \
59         (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |     \
60         GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)
61 #define GPIO(n) (1 << (31 - (n)))
62
63 struct gpio_res {
64         int mem_rid;
65         struct resource *mem_res;
66 };
67
68 /* software context */
69 struct gpio_softc {
70         device_t           dev;
71         device_t           busdev;
72         struct gpio_res    res;
73         struct gpio_pin    setup[PIN_COUNT];
74         struct mtx         mutex;
75 };
76
77 #define QORIQ_GPIO_LOCK(_sc)          mtx_lock_spin(&(_sc)->mutex)
78 #define QORIQ_GPIO_UNLOCK(_sc)        mtx_unlock_spin(&(_sc)->mutex)
79 #define QORIQ_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mutex, MA_OWNED)
80
81 /* prototypes */
82 /* helpers */
83 static int qoriq_make_gpio_res(device_t, struct gpio_res*);
84 static uint32_t qoriq_gpio_reg_read(device_t, uint32_t);
85 static void qoriq_gpio_reg_write(device_t, uint32_t, uint32_t);
86 static void qoriq_gpio_reg_set(device_t, uint32_t, uint32_t);
87 static void qoriq_gpio_reg_clear(device_t, uint32_t, uint32_t);
88 static void qoriq_gpio_out_en(device_t, uint32_t, uint8_t);
89 static void qoriq_gpio_value_set(device_t, uint32_t, uint8_t);
90 static uint32_t qoriq_gpio_value_get(device_t, uint32_t);
91 static void qoriq_gpio_open_drain_set(device_t, uint32_t, uint8_t);
92 static int qoriq_gpio_configure(device_t, uint32_t, uint32_t);
93
94 /* GPIO API */
95 static int qoriq_gpio_probe(device_t);
96 static int qoriq_gpio_attach(device_t);
97 static device_t qoriq_gpio_get_bus(device_t);
98 static int qoriq_gpio_pin_max(device_t, int*);
99 static int qoriq_gpio_pin_getname(device_t, uint32_t, char*);
100 static int qoriq_gpio_pin_getflags(device_t, uint32_t, uint32_t*);
101 static int qoriq_gpio_pin_setflags(device_t, uint32_t, uint32_t);
102 static int qoriq_gpio_pin_getcaps(device_t, uint32_t, uint32_t*);
103 static int qoriq_gpio_pin_get(device_t, uint32_t, uint32_t*);
104 static int qoriq_gpio_pin_set(device_t, uint32_t, uint32_t);
105 static int qoriq_gpio_pin_toggle(device_t, uint32_t);
106 static int qoriq_gpio_map_gpios(device_t, phandle_t, phandle_t,
107     int, pcell_t*, uint32_t*, uint32_t*);
108 static int qoriq_gpio_pin_access_32(device_t, uint32_t, uint32_t, uint32_t,
109     uint32_t*);
110 static int qoriq_gpio_pin_config_32(device_t, uint32_t, uint32_t, uint32_t*);
111
112
113 static device_method_t qoriq_gpio_methods[] = {
114         DEVMETHOD(device_probe,         qoriq_gpio_probe),
115         DEVMETHOD(device_attach,        qoriq_gpio_attach),
116
117         /* GPIO protocol */
118         DEVMETHOD(gpio_get_bus,         qoriq_gpio_get_bus),
119         DEVMETHOD(gpio_pin_max,         qoriq_gpio_pin_max),
120         DEVMETHOD(gpio_pin_getname,     qoriq_gpio_pin_getname),
121         DEVMETHOD(gpio_pin_getflags,    qoriq_gpio_pin_getflags),
122         DEVMETHOD(gpio_pin_setflags,    qoriq_gpio_pin_setflags),
123         DEVMETHOD(gpio_pin_getcaps,     qoriq_gpio_pin_getcaps),
124         DEVMETHOD(gpio_pin_get,         qoriq_gpio_pin_get),
125         DEVMETHOD(gpio_pin_set,         qoriq_gpio_pin_set),
126         DEVMETHOD(gpio_pin_toggle,      qoriq_gpio_pin_toggle),
127         DEVMETHOD(gpio_map_gpios,       qoriq_gpio_map_gpios),
128         DEVMETHOD(gpio_pin_access_32,   qoriq_gpio_pin_access_32),
129         DEVMETHOD(gpio_pin_config_32,   qoriq_gpio_pin_config_32),
130
131         DEVMETHOD_END
132 };
133
134 static driver_t gpio_driver = {
135         "gpio",
136         qoriq_gpio_methods,
137         sizeof(struct gpio_softc),
138 };
139
140 static devclass_t gpio_devclass;
141
142 DRIVER_MODULE(gpio, simplebus, gpio_driver, gpio_devclass, 0, 0);
143 MODULE_VERSION(gpio, 1);
144
145 /*
146  * helpers
147  */
148 static int
149 qoriq_make_gpio_res(device_t dev, struct gpio_res *out)
150 {
151
152         out->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
153             &out->mem_rid, RF_ACTIVE | RF_SHAREABLE);
154
155         if(out->mem_res == NULL) {
156                 return (1);
157         } else {
158                 return (0);
159         }
160 }
161
162 static uint32_t
163 qoriq_gpio_reg_read(device_t dev, uint32_t reg)
164 {
165         struct gpio_softc *sc = device_get_softc(dev);
166         uint32_t result;
167
168         QORIQ_GPIO_ASSERT_LOCKED(sc);
169         result = bus_read_4(sc->res.mem_res, reg);
170         return be32toh(result);
171 }
172
173 static void
174 qoriq_gpio_reg_write(device_t dev, uint32_t reg, uint32_t val)
175 {
176         struct gpio_softc *sc = device_get_softc(dev);
177
178         QORIQ_GPIO_ASSERT_LOCKED(sc);
179         val = htobe32(val);
180
181         bus_write_4(sc->res.mem_res, reg, val);
182         bus_barrier(sc->res.mem_res, reg, 4, BUS_SPACE_BARRIER_READ
183             | BUS_SPACE_BARRIER_WRITE);
184 }
185
186 static void
187 qoriq_gpio_reg_set(device_t dev, uint32_t reg, uint32_t pin)
188 {
189         uint32_t reg_val;
190
191         reg_val = qoriq_gpio_reg_read(dev, reg);
192         reg_val |= GPIO(pin);
193         qoriq_gpio_reg_write(dev, reg, reg_val);
194 }
195
196 static void
197 qoriq_gpio_reg_clear(device_t dev, uint32_t reg, uint32_t pin)
198 {
199         uint32_t reg_val;
200
201         reg_val = qoriq_gpio_reg_read(dev, reg);
202         reg_val &= ~(GPIO(pin));
203         qoriq_gpio_reg_write(dev, reg, reg_val);
204 }
205
206 static void
207 qoriq_gpio_out_en(device_t dev, uint32_t pin, uint8_t enable)
208 {
209
210         if (pin >= PIN_COUNT)
211                 return;
212
213         if (enable) {
214                 qoriq_gpio_reg_set(dev, DIRECTION, pin);
215         } else {
216                 qoriq_gpio_reg_clear(dev, DIRECTION, pin);
217         }
218 }
219
220 static void
221 qoriq_gpio_value_set(device_t dev, uint32_t pin, uint8_t val)
222 {
223
224         if (pin >= PIN_COUNT)
225                 return;
226
227         if (val) {
228                 qoriq_gpio_reg_set(dev, DATA, pin);
229         } else {
230                 qoriq_gpio_reg_clear(dev, DATA, pin);
231         }
232 }
233
234 static uint32_t
235 qoriq_gpio_value_get(device_t dev, uint32_t pin)
236 {
237         uint32_t reg_val;
238
239         if (pin >= PIN_COUNT)
240                 return (0);
241
242         reg_val = qoriq_gpio_reg_read(dev, DATA);
243         return ((reg_val & GPIO(pin)) == 0 ? 0 : 1);
244 }
245
246 static void
247 qoriq_gpio_open_drain_set(device_t dev, uint32_t pin, uint8_t val)
248 {
249
250         if (pin >= PIN_COUNT) {
251                 return;
252         }
253
254         if (val) {
255                 qoriq_gpio_reg_set(dev, OPEN_DRAIN, pin);
256         } else {
257                 qoriq_gpio_reg_clear(dev, OPEN_DRAIN, pin);
258         }
259 }
260
261 static int
262 qoriq_gpio_configure(device_t dev, uint32_t pin, uint32_t flags)
263 {
264         struct gpio_softc *sc = device_get_softc(dev);
265         uint32_t newflags;
266
267         if (pin >= PIN_COUNT) {
268                 return (EINVAL);
269         }
270
271         /*
272          * Pin cannot function as input and output at the same time.
273          * The same applies to open-drain and push-pull functionality.
274          */
275         if (((flags & GPIO_PIN_INPUT) && (flags & GPIO_PIN_OUTPUT))
276             || ((flags & GPIO_PIN_OPENDRAIN) && (flags & GPIO_PIN_PUSHPULL))) {
277                 return (EINVAL);
278         }
279
280         QORIQ_GPIO_ASSERT_LOCKED(sc);
281
282         if (flags & GPIO_PIN_INPUT) {
283                 newflags = GPIO_PIN_INPUT;
284                 qoriq_gpio_out_en(dev, pin, 0);
285         }
286
287         if (flags & GPIO_PIN_OUTPUT) {
288                 newflags = GPIO_PIN_OUTPUT;
289                 qoriq_gpio_out_en(dev, pin, 1);
290
291                 if (flags & GPIO_PIN_OPENDRAIN) {
292                         newflags |= GPIO_PIN_OPENDRAIN;
293                         qoriq_gpio_open_drain_set(dev, pin, 1);
294                 } else {
295                         newflags |= GPIO_PIN_PUSHPULL;
296                         qoriq_gpio_open_drain_set(dev, pin, 0);
297                 }
298         }
299
300         sc->setup[pin].gp_flags = newflags;
301
302         return (0);
303 }
304
305 /* GPIO API */
306 static int
307 qoriq_gpio_probe(device_t dev)
308 {
309
310         if (!ofw_bus_status_okay(dev)) {
311                 return (ENXIO);
312         }
313
314         if (!ofw_bus_is_compatible(dev, "fsl,qoriq-gpio")) {
315                 return (ENXIO);
316         }
317
318         device_set_desc(dev, "Integrated GPIO Controller");
319         return (0);
320 }
321
322 static int
323 qoriq_gpio_attach(device_t dev)
324 {
325         struct gpio_softc *sc = device_get_softc(dev);
326         int i;
327
328         if(qoriq_make_gpio_res(dev, &sc->res) != 0) {
329                 return (ENXIO);
330         }
331
332         for(i = 0; i < PIN_COUNT; i++) {
333                 sc->setup[i].gp_caps = DEFAULT_CAPS;
334         }
335
336         sc->dev = dev;
337
338         sc->busdev = gpiobus_attach_bus(dev);
339         if(sc->busdev == NULL) {
340                 return (ENXIO);
341         }
342
343         return (0);
344 }
345
346 static device_t
347 qoriq_gpio_get_bus(device_t dev)
348 {
349         struct gpio_softc *softc = device_get_softc(dev);
350
351         return (softc->busdev);
352 }
353
354 static int
355 qoriq_gpio_pin_max(device_t dev, int *maxpin)
356 {
357
358         if(maxpin == NULL) {
359                 return (EINVAL);
360         }
361
362         *maxpin = PIN_COUNT - 1;
363         return (0);
364 }
365
366 static int
367 qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
368 {
369
370         if(name == NULL || pin >= PIN_COUNT) {
371                 return (EINVAL);
372         }
373
374         snprintf(name, GPIOMAXNAME, "pin %d", pin);
375
376         return (0);
377 }
378
379 static int
380 qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags)
381 {
382         struct gpio_softc *sc = device_get_softc(dev);
383
384         if (pflags == NULL || pin >= PIN_COUNT) {
385                 return (EINVAL);
386         }
387
388         QORIQ_GPIO_LOCK(sc);
389         *pflags = sc->setup[pin].gp_flags;
390         QORIQ_GPIO_UNLOCK(sc);
391
392         return (0);
393 }
394
395 static int
396 qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
397 {
398         struct gpio_softc *sc = device_get_softc(dev);
399         int ret;
400
401         if (pin >= PIN_COUNT)
402                 return (EINVAL);
403
404         /* Check for unwanted flags. */
405         QORIQ_GPIO_LOCK(sc);
406         if ((flags & sc->setup[pin].gp_caps) != flags) {
407                 QORIQ_GPIO_UNLOCK(sc);
408                 return (EINVAL);
409         }
410
411         ret = qoriq_gpio_configure(dev, pin, flags);
412
413         QORIQ_GPIO_UNLOCK(sc);
414         return (ret);
415 }
416
417 static int
418 qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
419 {
420         struct gpio_softc *sc = device_get_softc(dev);
421
422         if (caps == NULL || pin >= PIN_COUNT) {
423                 return (EINVAL);
424         }
425
426         QORIQ_GPIO_LOCK(sc);
427         *caps = sc->setup[pin].gp_caps;
428         QORIQ_GPIO_UNLOCK(sc);
429
430         return (0);
431 }
432
433 static int
434 qoriq_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
435 {
436         struct gpio_softc *sc = device_get_softc(dev);
437
438         if (value == NULL || pin >= PIN_COUNT) {
439                 return (EINVAL);
440         }
441
442         QORIQ_GPIO_LOCK(sc);
443         *value = qoriq_gpio_value_get(dev, pin);
444         QORIQ_GPIO_UNLOCK(sc);
445         return (0);
446 }
447
448 static int
449 qoriq_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
450 {
451         struct gpio_softc *sc = device_get_softc(dev);
452
453         if (pin >= PIN_COUNT) {
454                 return (EINVAL);
455         }
456
457         QORIQ_GPIO_LOCK(sc);
458         qoriq_gpio_value_set(dev, pin, value);
459         QORIQ_GPIO_UNLOCK(sc);
460         return (0);
461 }
462
463 static int
464 qoriq_gpio_pin_toggle(device_t dev, uint32_t pin)
465 {
466         struct gpio_softc *sc;
467         uint32_t value;
468
469         if (pin >= PIN_COUNT) {
470                 return (EINVAL);
471         }
472
473         sc = device_get_softc(dev);
474
475         QORIQ_GPIO_LOCK(sc);
476         value = qoriq_gpio_reg_read(dev, DATA);
477         if (value & (1 << pin))
478                 value &= ~(1 << pin);
479         else
480                 value |= (1 << pin);
481         qoriq_gpio_reg_write(dev, DATA, value);
482         QORIQ_GPIO_UNLOCK(sc);
483
484         return (0);
485 }
486
487 static int
488 qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
489     pcell_t *gpios, uint32_t *pin, uint32_t *flags)
490 {
491         struct gpio_softc *sc = device_get_softc(bus);
492         int err;
493
494         if (gpios[0] >= PIN_COUNT)
495                 return (EINVAL);
496
497         QORIQ_GPIO_LOCK(sc);
498         err = qoriq_gpio_configure(bus, gpios[0], gpios[1]);
499         QORIQ_GPIO_UNLOCK(sc);
500
501         if(err == 0) {
502                 *pin = gpios[0];
503                 *flags = gpios[1];
504         }
505
506         return (err);
507 }
508
509 static int
510 qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
511     uint32_t change_pins, uint32_t *orig_pins)
512 {
513         struct gpio_softc *sc;
514         uint32_t hwstate;
515
516         sc = device_get_softc(dev);
517
518         if (first_pin != 0)
519                 return (EINVAL);
520
521         QORIQ_GPIO_LOCK(sc);
522         hwstate = qoriq_gpio_reg_read(dev, DATA);
523         qoriq_gpio_reg_write(dev, DATA, (hwstate & ~clear_pins) ^ change_pins);
524         QORIQ_GPIO_UNLOCK(sc);
525
526         if (orig_pins != NULL)
527                 *orig_pins = hwstate;
528
529         return (0);
530 }
531
532 static int
533 qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
534     uint32_t *pin_flags)
535 {
536         uint32_t dir, odr, mask, reg;
537         struct gpio_softc *sc;
538         uint32_t newflags[32];
539         int i;
540
541         if (first_pin != 0 || num_pins > PIN_COUNT)
542                 return (EINVAL);
543
544         sc = device_get_softc(dev);
545
546         dir = 0;
547         odr = 0;
548         mask = 0;
549
550         for (i = 0; i < num_pins; i++) {
551                 newflags[i] = 0;
552                 mask |= (1 << i);
553
554                 if (pin_flags[i] & GPIO_PIN_INPUT) {
555                         newflags[i] = GPIO_PIN_INPUT;
556                         dir &= ~(1 << i);
557                 } else {
558                         newflags[i] = GPIO_PIN_OUTPUT;
559                         dir |= (1 << i);
560
561                         if (pin_flags[i] & GPIO_PIN_OPENDRAIN) {
562                                 newflags[i] |= GPIO_PIN_OPENDRAIN;
563                                 odr |= (1 << i);
564                         } else {
565                                 newflags[i] |= GPIO_PIN_PUSHPULL;
566                                 odr &= ~(1 << i);
567                         }
568                 }
569         }
570
571         QORIQ_GPIO_LOCK(sc);
572         reg = qoriq_gpio_reg_read(dev, DIRECTION);
573         reg &= ~mask;
574         reg |= dir;
575         qoriq_gpio_reg_write(dev, DIRECTION, reg);
576         reg = qoriq_gpio_reg_read(dev, OPEN_DRAIN);
577         reg &= ~mask;
578         reg |= odr;
579         qoriq_gpio_reg_write(dev, OPEN_DRAIN, reg);
580         for (i = 0; i < num_pins; i++) {
581                 sc->setup[i].gp_flags = newflags[i];
582         }
583         QORIQ_GPIO_UNLOCK(sc);
584
585         return (0);
586 }