1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2006 Benno Rice. 5 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 6 * All rights reserved. 7 * 8 * Adapted and extended for Marvell SoCs by Semihalf. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_gpio.c, rev 1 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/bus.h> 39 #include <sys/kernel.h> 40 #include <sys/lock.h> 41 #include <sys/interrupt.h> 42 #include <sys/module.h> 43 #include <sys/malloc.h> 44 #include <sys/mutex.h> 45 #include <sys/rman.h> 46 #include <sys/queue.h> 47 #include <sys/timetc.h> 48 #include <machine/bus.h> 49 #include <machine/intr.h> 50 51 #include <dev/fdt/fdt_common.h> 52 #include <dev/ofw/ofw_bus.h> 53 #include <dev/ofw/ofw_bus_subr.h> 54 55 #include <arm/mv/mvvar.h> 56 #include <arm/mv/mvreg.h> 57 58 #define GPIO_MAX_INTR_COUNT 8 59 #define GPIO_PINS_PER_REG 32 60 61 struct mv_gpio_softc { 62 struct resource * res[GPIO_MAX_INTR_COUNT + 1]; 63 void *ih_cookie[GPIO_MAX_INTR_COUNT]; 64 bus_space_tag_t bst; 65 bus_space_handle_t bsh; 66 uint8_t pin_num; /* number of GPIO pins */ 67 uint8_t irq_num; /* number of real IRQs occupied by GPIO controller */ 68 }; 69 70 extern struct resource_spec mv_gpio_res[]; 71 72 static struct mv_gpio_softc *mv_gpio_softc = NULL; 73 static uint32_t gpio_setup[MV_GPIO_MAX_NPINS]; 74 75 static int mv_gpio_probe(device_t); 76 static int mv_gpio_attach(device_t); 77 static int mv_gpio_intr(void *); 78 static int mv_gpio_init(void); 79 80 static void mv_gpio_intr_handler(int pin); 81 static uint32_t mv_gpio_reg_read(uint32_t reg); 82 static void mv_gpio_reg_write(uint32_t reg, uint32_t val); 83 static void mv_gpio_reg_set(uint32_t reg, uint32_t val); 84 static void mv_gpio_reg_clear(uint32_t reg, uint32_t val); 85 86 static void mv_gpio_blink(uint32_t pin, uint8_t enable); 87 static void mv_gpio_polarity(uint32_t pin, uint8_t enable); 88 static void mv_gpio_level(uint32_t pin, uint8_t enable); 89 static void mv_gpio_edge(uint32_t pin, uint8_t enable); 90 static void mv_gpio_out_en(uint32_t pin, uint8_t enable); 91 static void mv_gpio_int_ack(uint32_t pin); 92 static void mv_gpio_value_set(uint32_t pin, uint8_t val); 93 static uint32_t mv_gpio_value_get(uint32_t pin); 94 95 static device_method_t mv_gpio_methods[] = { 96 DEVMETHOD(device_probe, mv_gpio_probe), 97 DEVMETHOD(device_attach, mv_gpio_attach), 98 { 0, 0 } 99 }; 100 101 static driver_t mv_gpio_driver = { 102 "gpio", 103 mv_gpio_methods, 104 sizeof(struct mv_gpio_softc), 105 }; 106 107 static devclass_t mv_gpio_devclass; 108 109 DRIVER_MODULE(gpio, simplebus, mv_gpio_driver, mv_gpio_devclass, 0, 0); 110 111 typedef int (*gpios_phandler_t)(phandle_t, pcell_t *, int); 112 113 struct gpio_ctrl_entry { 114 const char *compat; 115 gpios_phandler_t handler; 116 }; 117 118 static int mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len); 119 int gpio_get_config_from_dt(void); 120 121 struct gpio_ctrl_entry gpio_controllers[] = { 122 { "mrvl,gpio", &mv_handle_gpios_prop }, 123 { NULL, NULL } 124 }; 125 126 static int 127 mv_gpio_probe(device_t dev) 128 { 129 130 if (!ofw_bus_status_okay(dev)) 131 return (ENXIO); 132 133 if (!ofw_bus_is_compatible(dev, "mrvl,gpio")) 134 return (ENXIO); 135 136 device_set_desc(dev, "Marvell Integrated GPIO Controller"); 137 return (0); 138 } 139 140 static int 141 mv_gpio_attach(device_t dev) 142 { 143 int error, i; 144 struct mv_gpio_softc *sc; 145 uint32_t dev_id, rev_id; 146 147 sc = (struct mv_gpio_softc *)device_get_softc(dev); 148 if (sc == NULL) 149 return (ENXIO); 150 151 mv_gpio_softc = sc; 152 153 /* Get chip id and revision */ 154 soc_id(&dev_id, &rev_id); 155 156 if (dev_id == MV_DEV_88F5182 || 157 dev_id == MV_DEV_88F5281 || 158 dev_id == MV_DEV_MV78100 || 159 dev_id == MV_DEV_MV78100_Z0 ) { 160 sc->pin_num = 32; 161 sc->irq_num = 4; 162 163 } else if (dev_id == MV_DEV_88F6281 || 164 dev_id == MV_DEV_88F6282) { 165 sc->pin_num = 50; 166 sc->irq_num = 7; 167 168 } else { 169 device_printf(dev, "unknown chip id=0x%x\n", dev_id); 170 return (ENXIO); 171 } 172 173 error = bus_alloc_resources(dev, mv_gpio_res, sc->res); 174 if (error) { 175 device_printf(dev, "could not allocate resources\n"); 176 return (ENXIO); 177 } 178 179 sc->bst = rman_get_bustag(sc->res[0]); 180 sc->bsh = rman_get_bushandle(sc->res[0]); 181 182 /* Disable and clear all interrupts */ 183 bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_EDGE_MASK, 0); 184 bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_LEV_MASK, 0); 185 bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_CAUSE, 0); 186 187 if (sc->pin_num > GPIO_PINS_PER_REG) { 188 bus_space_write_4(sc->bst, sc->bsh, 189 GPIO_HI_INT_EDGE_MASK, 0); 190 bus_space_write_4(sc->bst, sc->bsh, 191 GPIO_HI_INT_LEV_MASK, 0); 192 bus_space_write_4(sc->bst, sc->bsh, 193 GPIO_HI_INT_CAUSE, 0); 194 } 195 196 for (i = 0; i < sc->irq_num; i++) { 197 if (bus_setup_intr(dev, sc->res[1 + i], 198 INTR_TYPE_MISC, mv_gpio_intr, NULL, 199 sc, &sc->ih_cookie[i]) != 0) { 200 bus_release_resources(dev, mv_gpio_res, sc->res); 201 device_printf(dev, "could not set up intr %d\n", i); 202 return (ENXIO); 203 } 204 } 205 206 return (mv_gpio_init()); 207 } 208 209 static int 210 mv_gpio_intr(void *arg) 211 { 212 uint32_t int_cause, gpio_val; 213 uint32_t int_cause_hi, gpio_val_hi = 0; 214 int i; 215 216 int_cause = mv_gpio_reg_read(GPIO_INT_CAUSE); 217 gpio_val = mv_gpio_reg_read(GPIO_DATA_IN); 218 gpio_val &= int_cause; 219 if (mv_gpio_softc->pin_num > GPIO_PINS_PER_REG) { 220 int_cause_hi = mv_gpio_reg_read(GPIO_HI_INT_CAUSE); 221 gpio_val_hi = mv_gpio_reg_read(GPIO_HI_DATA_IN); 222 gpio_val_hi &= int_cause_hi; 223 } 224 225 i = 0; 226 while (gpio_val != 0) { 227 if (gpio_val & 1) 228 mv_gpio_intr_handler(i); 229 gpio_val >>= 1; 230 i++; 231 } 232 233 if (mv_gpio_softc->pin_num > GPIO_PINS_PER_REG) { 234 i = 0; 235 while (gpio_val_hi != 0) { 236 if (gpio_val_hi & 1) 237 mv_gpio_intr_handler(i + GPIO_PINS_PER_REG); 238 gpio_val_hi >>= 1; 239 i++; 240 } 241 } 242 243 return (FILTER_HANDLED); 244 } 245 246 /* 247 * GPIO interrupt handling 248 */ 249 250 static struct intr_event *gpio_events[MV_GPIO_MAX_NPINS]; 251 252 int 253 mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt, 254 void (*hand)(void *), void *arg, int pin, int flags, void **cookiep) 255 { 256 struct intr_event *event; 257 int error; 258 259 if (pin < 0 || pin >= mv_gpio_softc->pin_num) 260 return (ENXIO); 261 event = gpio_events[pin]; 262 if (event == NULL) { 263 error = intr_event_create(&event, (void *)pin, 0, pin, 264 (void (*)(void *))mv_gpio_intr_mask, 265 (void (*)(void *))mv_gpio_intr_unmask, 266 (void (*)(void *))mv_gpio_int_ack, 267 NULL, 268 "gpio%d:", pin); 269 if (error != 0) 270 return (error); 271 gpio_events[pin] = event; 272 } 273 274 intr_event_add_handler(event, name, filt, hand, arg, 275 intr_priority(flags), flags, cookiep); 276 return (0); 277 } 278 279 void 280 mv_gpio_intr_mask(int pin) 281 { 282 283 if (pin >= mv_gpio_softc->pin_num) 284 return; 285 286 if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE) 287 mv_gpio_edge(pin, 0); 288 else 289 mv_gpio_level(pin, 0); 290 } 291 292 void 293 mv_gpio_intr_unmask(int pin) 294 { 295 296 if (pin >= mv_gpio_softc->pin_num) 297 return; 298 299 if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE) 300 mv_gpio_edge(pin, 1); 301 else 302 mv_gpio_level(pin, 1); 303 } 304 305 static void 306 mv_gpio_intr_handler(int pin) 307 { 308 struct intr_event *event; 309 310 event = gpio_events[pin]; 311 if (event == NULL || TAILQ_EMPTY(&event->ie_handlers)) 312 return; 313 314 intr_event_handle(event, NULL); 315 } 316 317 static int 318 mv_gpio_configure(uint32_t pin, uint32_t flags) 319 { 320 321 if (pin >= mv_gpio_softc->pin_num) 322 return (EINVAL); 323 324 if (flags & MV_GPIO_OUT_BLINK) 325 mv_gpio_blink(pin, 1); 326 if (flags & MV_GPIO_IN_POL_LOW) 327 mv_gpio_polarity(pin, 1); 328 if (flags & MV_GPIO_IN_IRQ_EDGE) 329 mv_gpio_edge(pin, 1); 330 if (flags & MV_GPIO_IN_IRQ_LEVEL) 331 mv_gpio_level(pin, 1); 332 333 gpio_setup[pin] = flags; 334 335 return (0); 336 } 337 338 void 339 mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable) 340 { 341 342 mv_gpio_value_set(pin, val); 343 mv_gpio_out_en(pin, enable); 344 } 345 346 uint8_t 347 mv_gpio_in(uint32_t pin) 348 { 349 350 return (mv_gpio_value_get(pin) ? 1 : 0); 351 } 352 353 static uint32_t 354 mv_gpio_reg_read(uint32_t reg) 355 { 356 357 return (bus_space_read_4(mv_gpio_softc->bst, 358 mv_gpio_softc->bsh, reg)); 359 } 360 361 static void 362 mv_gpio_reg_write(uint32_t reg, uint32_t val) 363 { 364 365 bus_space_write_4(mv_gpio_softc->bst, 366 mv_gpio_softc->bsh, reg, val); 367 } 368 369 static void 370 mv_gpio_reg_set(uint32_t reg, uint32_t pin) 371 { 372 uint32_t reg_val; 373 374 reg_val = mv_gpio_reg_read(reg); 375 reg_val |= GPIO(pin); 376 mv_gpio_reg_write(reg, reg_val); 377 } 378 379 static void 380 mv_gpio_reg_clear(uint32_t reg, uint32_t pin) 381 { 382 uint32_t reg_val; 383 384 reg_val = mv_gpio_reg_read(reg); 385 reg_val &= ~(GPIO(pin)); 386 mv_gpio_reg_write(reg, reg_val); 387 } 388 389 static void 390 mv_gpio_out_en(uint32_t pin, uint8_t enable) 391 { 392 uint32_t reg; 393 394 if (pin >= mv_gpio_softc->pin_num) 395 return; 396 397 if (pin >= GPIO_PINS_PER_REG) { 398 reg = GPIO_HI_DATA_OUT_EN_CTRL; 399 pin -= GPIO_PINS_PER_REG; 400 } else 401 reg = GPIO_DATA_OUT_EN_CTRL; 402 403 if (enable) 404 mv_gpio_reg_clear(reg, pin); 405 else 406 mv_gpio_reg_set(reg, pin); 407 } 408 409 static void 410 mv_gpio_blink(uint32_t pin, uint8_t enable) 411 { 412 uint32_t reg; 413 414 if (pin >= mv_gpio_softc->pin_num) 415 return; 416 417 if (pin >= GPIO_PINS_PER_REG) { 418 reg = GPIO_HI_BLINK_EN; 419 pin -= GPIO_PINS_PER_REG; 420 } else 421 reg = GPIO_BLINK_EN; 422 423 if (enable) 424 mv_gpio_reg_set(reg, pin); 425 else 426 mv_gpio_reg_clear(reg, pin); 427 } 428 429 static void 430 mv_gpio_polarity(uint32_t pin, uint8_t enable) 431 { 432 uint32_t reg; 433 434 if (pin >= mv_gpio_softc->pin_num) 435 return; 436 437 if (pin >= GPIO_PINS_PER_REG) { 438 reg = GPIO_HI_DATA_IN_POLAR; 439 pin -= GPIO_PINS_PER_REG; 440 } else 441 reg = GPIO_DATA_IN_POLAR; 442 443 if (enable) 444 mv_gpio_reg_set(reg, pin); 445 else 446 mv_gpio_reg_clear(reg, pin); 447 } 448 449 static void 450 mv_gpio_level(uint32_t pin, uint8_t enable) 451 { 452 uint32_t reg; 453 454 if (pin >= mv_gpio_softc->pin_num) 455 return; 456 457 if (pin >= GPIO_PINS_PER_REG) { 458 reg = GPIO_HI_INT_LEV_MASK; 459 pin -= GPIO_PINS_PER_REG; 460 } else 461 reg = GPIO_INT_LEV_MASK; 462 463 if (enable) 464 mv_gpio_reg_set(reg, pin); 465 else 466 mv_gpio_reg_clear(reg, pin); 467 } 468 469 static void 470 mv_gpio_edge(uint32_t pin, uint8_t enable) 471 { 472 uint32_t reg; 473 474 if (pin >= mv_gpio_softc->pin_num) 475 return; 476 477 if (pin >= GPIO_PINS_PER_REG) { 478 reg = GPIO_HI_INT_EDGE_MASK; 479 pin -= GPIO_PINS_PER_REG; 480 } else 481 reg = GPIO_INT_EDGE_MASK; 482 483 if (enable) 484 mv_gpio_reg_set(reg, pin); 485 else 486 mv_gpio_reg_clear(reg, pin); 487 } 488 489 static void 490 mv_gpio_int_ack(uint32_t pin) 491 { 492 uint32_t reg; 493 494 if (pin >= mv_gpio_softc->pin_num) 495 return; 496 497 if (pin >= GPIO_PINS_PER_REG) { 498 reg = GPIO_HI_INT_CAUSE; 499 pin -= GPIO_PINS_PER_REG; 500 } else 501 reg = GPIO_INT_CAUSE; 502 503 mv_gpio_reg_clear(reg, pin); 504 } 505 506 static uint32_t 507 mv_gpio_value_get(uint32_t pin) 508 { 509 uint32_t reg, reg_val; 510 511 if (pin >= mv_gpio_softc->pin_num) 512 return (0); 513 514 if (pin >= GPIO_PINS_PER_REG) { 515 reg = GPIO_HI_DATA_IN; 516 pin -= GPIO_PINS_PER_REG; 517 } else 518 reg = GPIO_DATA_IN; 519 520 reg_val = mv_gpio_reg_read(reg); 521 522 return (reg_val & GPIO(pin)); 523 } 524 525 static void 526 mv_gpio_value_set(uint32_t pin, uint8_t val) 527 { 528 uint32_t reg; 529 530 if (pin >= mv_gpio_softc->pin_num) 531 return; 532 533 if (pin >= GPIO_PINS_PER_REG) { 534 reg = GPIO_HI_DATA_OUT; 535 pin -= GPIO_PINS_PER_REG; 536 } else 537 reg = GPIO_DATA_OUT; 538 539 if (val) 540 mv_gpio_reg_set(reg, pin); 541 else 542 mv_gpio_reg_clear(reg, pin); 543 } 544 545 static int 546 mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len) 547 { 548 pcell_t gpio_cells, pincnt; 549 int inc, t, tuples, tuple_size; 550 int dir, flags, pin; 551 u_long gpio_ctrl, size; 552 struct mv_gpio_softc sc; 553 554 pincnt = 0; 555 if (!OF_hasprop(ctrl, "gpio-controller")) 556 /* Node is not a GPIO controller. */ 557 return (ENXIO); 558 559 if (OF_getencprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0) 560 return (ENXIO); 561 if (gpio_cells != 3) 562 return (ENXIO); 563 564 tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t); 565 tuples = len / tuple_size; 566 567 if (fdt_regsize(ctrl, &gpio_ctrl, &size)) 568 return (ENXIO); 569 570 if (OF_getencprop(ctrl, "pin-count", &pincnt, sizeof(pcell_t)) < 0) 571 return (ENXIO); 572 sc.pin_num = pincnt; 573 574 /* 575 * Skip controller reference, since controller's phandle is given 576 * explicitly (in a function argument). 577 */ 578 inc = sizeof(ihandle_t) / sizeof(pcell_t); 579 gpios += inc; 580 581 for (t = 0; t < tuples; t++) { 582 pin = gpios[0]; 583 dir = gpios[1]; 584 flags = gpios[2]; 585 586 mv_gpio_configure(pin, flags); 587 588 if (dir == 1) 589 /* Input. */ 590 mv_gpio_out_en(pin, 0); 591 else { 592 /* Output. */ 593 if (flags & MV_GPIO_OUT_OPEN_DRAIN) 594 mv_gpio_out(pin, 0, 1); 595 596 if (flags & MV_GPIO_OUT_OPEN_SRC) 597 mv_gpio_out(pin, 1, 1); 598 } 599 gpios += gpio_cells + inc; 600 } 601 602 return (0); 603 } 604 605 #define MAX_PINS_PER_NODE 5 606 #define GPIOS_PROP_CELLS 4 607 static int 608 mv_gpio_init(void) 609 { 610 phandle_t child, parent, root, ctrl; 611 pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS]; 612 struct gpio_ctrl_entry *e; 613 int len, rv; 614 615 root = OF_finddevice("/"); 616 len = 0; 617 parent = root; 618 619 /* Traverse through entire tree to find nodes with 'gpios' prop */ 620 for (child = OF_child(parent); child != 0; child = OF_peer(child)) { 621 622 /* Find a 'leaf'. Start the search from this node. */ 623 while (OF_child(child)) { 624 parent = child; 625 child = OF_child(child); 626 } 627 if ((len = OF_getproplen(child, "gpios")) > 0) { 628 629 if (len > sizeof(gpios)) 630 return (ENXIO); 631 632 /* Get 'gpios' property. */ 633 OF_getencprop(child, "gpios", gpios, len); 634 635 e = (struct gpio_ctrl_entry *)&gpio_controllers; 636 637 /* Find and call a handler. */ 638 for (; e->compat; e++) { 639 /* 640 * First cell of 'gpios' property should 641 * contain a ref. to a node defining GPIO 642 * controller. 643 */ 644 ctrl = OF_node_from_xref(gpios[0]); 645 646 if (ofw_bus_node_is_compatible(ctrl, e->compat)) 647 /* Call a handler. */ 648 if ((rv = e->handler(ctrl, 649 (pcell_t *)&gpios, len))) 650 return (rv); 651 } 652 } 653 654 if (OF_peer(child) == 0) { 655 /* No more siblings. */ 656 child = parent; 657 parent = OF_parent(child); 658 } 659 } 660 return (0); 661 } 662