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