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/fdt.h> 48 #include <machine/intr.h> 49 50 #include <dev/fdt/fdt_common.h> 51 #include <dev/ofw/ofw_bus.h> 52 #include <dev/ofw/ofw_bus_subr.h> 53 54 #include <arm/mv/mvvar.h> 55 #include <arm/mv/mvreg.h> 56 57 #define GPIO_MAX_INTR_COUNT 8 58 #define GPIO_PINS_PER_REG 32 59 60 struct mv_gpio_softc { 61 struct resource * res[GPIO_MAX_INTR_COUNT + 1]; 62 void *ih_cookie[GPIO_MAX_INTR_COUNT]; 63 bus_space_tag_t bst; 64 bus_space_handle_t bsh; 65 uint8_t pin_num; /* number of GPIO pins */ 66 uint8_t irq_num; /* number of real IRQs occupied by GPIO controller */ 67 }; 68 69 extern struct resource_spec mv_gpio_res[]; 70 71 static struct mv_gpio_softc *mv_gpio_softc = NULL; 72 static uint32_t gpio_setup[MV_GPIO_MAX_NPINS]; 73 74 static int mv_gpio_probe(device_t); 75 static int mv_gpio_attach(device_t); 76 static int mv_gpio_intr(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 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_is_compatible(dev, "mrvl,gpio")) 129 return (ENXIO); 130 131 device_set_desc(dev, "Marvell Integrated GPIO Controller"); 132 return (0); 133 } 134 135 static int 136 mv_gpio_attach(device_t dev) 137 { 138 int error, i; 139 struct mv_gpio_softc *sc; 140 uint32_t dev_id, rev_id; 141 142 sc = (struct mv_gpio_softc *)device_get_softc(dev); 143 if (sc == NULL) 144 return (ENXIO); 145 146 mv_gpio_softc = sc; 147 148 /* Get chip id and revision */ 149 soc_id(&dev_id, &rev_id); 150 151 if (dev_id == MV_DEV_88F5182 || 152 dev_id == MV_DEV_88F5281 || 153 dev_id == MV_DEV_MV78100 || 154 dev_id == MV_DEV_MV78100_Z0 ) { 155 sc->pin_num = 32; 156 sc->irq_num = 4; 157 158 } else if (dev_id == MV_DEV_88F6281) { 159 sc->pin_num = 50; 160 sc->irq_num = 7; 161 162 } else { 163 device_printf(dev, "unknown chip id=0x%x\n", dev_id); 164 return (ENXIO); 165 } 166 167 error = bus_alloc_resources(dev, mv_gpio_res, sc->res); 168 if (error) { 169 device_printf(dev, "could not allocate resources\n"); 170 return (ENXIO); 171 } 172 173 sc->bst = rman_get_bustag(sc->res[0]); 174 sc->bsh = rman_get_bushandle(sc->res[0]); 175 176 /* Disable and clear all interrupts */ 177 bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_EDGE_MASK, 0); 178 bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_LEV_MASK, 0); 179 bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_CAUSE, 0); 180 181 if (sc->pin_num > GPIO_PINS_PER_REG) { 182 bus_space_write_4(sc->bst, sc->bsh, 183 GPIO_HI_INT_EDGE_MASK, 0); 184 bus_space_write_4(sc->bst, sc->bsh, 185 GPIO_HI_INT_LEV_MASK, 0); 186 bus_space_write_4(sc->bst, sc->bsh, 187 GPIO_HI_INT_CAUSE, 0); 188 } 189 190 for (i = 0; i < sc->irq_num; i++) { 191 if (bus_setup_intr(dev, sc->res[1 + i], 192 INTR_TYPE_MISC, mv_gpio_intr, NULL, 193 sc, &sc->ih_cookie[i]) != 0) { 194 bus_release_resources(dev, mv_gpio_res, sc->res); 195 device_printf(dev, "could not set up intr %d\n", i); 196 return (ENXIO); 197 } 198 } 199 200 /* 201 * GPIO lines setup is already done at this stage (see mv_machdep.c). 202 */ 203 return (0); 204 } 205 206 static int 207 mv_gpio_intr(void *arg) 208 { 209 uint32_t int_cause, gpio_val; 210 uint32_t int_cause_hi, gpio_val_hi = 0; 211 int i; 212 213 int_cause = mv_gpio_reg_read(GPIO_INT_CAUSE); 214 gpio_val = mv_gpio_reg_read(GPIO_DATA_IN); 215 gpio_val &= int_cause; 216 if (mv_gpio_softc->pin_num > GPIO_PINS_PER_REG) { 217 int_cause_hi = mv_gpio_reg_read(GPIO_HI_INT_CAUSE); 218 gpio_val_hi = mv_gpio_reg_read(GPIO_HI_DATA_IN); 219 gpio_val_hi &= int_cause_hi; 220 } 221 222 i = 0; 223 while (gpio_val != 0) { 224 if (gpio_val & 1) 225 mv_gpio_intr_handler(i); 226 gpio_val >>= 1; 227 i++; 228 } 229 230 if (mv_gpio_softc->pin_num > GPIO_PINS_PER_REG) { 231 i = 0; 232 while (gpio_val_hi != 0) { 233 if (gpio_val_hi & 1) 234 mv_gpio_intr_handler(i + GPIO_PINS_PER_REG); 235 gpio_val_hi >>= 1; 236 i++; 237 } 238 } 239 240 return (FILTER_HANDLED); 241 } 242 243 /* 244 * GPIO interrupt handling 245 */ 246 247 static struct intr_event *gpio_events[MV_GPIO_MAX_NPINS]; 248 249 int 250 mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt, 251 void (*hand)(void *), void *arg, int pin, int flags, void **cookiep) 252 { 253 struct intr_event *event; 254 int error; 255 256 if (pin < 0 || pin >= mv_gpio_softc->pin_num) 257 return (ENXIO); 258 event = gpio_events[pin]; 259 if (event == NULL) { 260 error = intr_event_create(&event, (void *)pin, 0, pin, 261 (void (*)(void *))mv_gpio_intr_mask, 262 (void (*)(void *))mv_gpio_intr_unmask, 263 (void (*)(void *))mv_gpio_int_ack, 264 NULL, 265 "gpio%d:", pin); 266 if (error != 0) 267 return (error); 268 gpio_events[pin] = event; 269 } 270 271 intr_event_add_handler(event, name, filt, hand, arg, 272 intr_priority(flags), flags, cookiep); 273 return (0); 274 } 275 276 void 277 mv_gpio_intr_mask(int pin) 278 { 279 280 if (pin >= mv_gpio_softc->pin_num) 281 return; 282 283 if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE) 284 mv_gpio_edge(pin, 0); 285 else 286 mv_gpio_level(pin, 0); 287 } 288 289 void 290 mv_gpio_intr_unmask(int pin) 291 { 292 293 if (pin >= mv_gpio_softc->pin_num) 294 return; 295 296 if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE) 297 mv_gpio_edge(pin, 1); 298 else 299 mv_gpio_level(pin, 1); 300 } 301 302 static void 303 mv_gpio_intr_handler(int pin) 304 { 305 struct intr_event *event; 306 307 event = gpio_events[pin]; 308 if (event == NULL || TAILQ_EMPTY(&event->ie_handlers)) 309 return; 310 311 intr_event_handle(event, NULL); 312 } 313 314 static int 315 mv_gpio_configure(uint32_t pin, uint32_t flags) 316 { 317 318 if (pin >= mv_gpio_softc->pin_num) 319 return (EINVAL); 320 321 if (flags & MV_GPIO_OUT_BLINK) 322 mv_gpio_blink(pin, 1); 323 if (flags & MV_GPIO_IN_POL_LOW) 324 mv_gpio_polarity(pin, 1); 325 if (flags & MV_GPIO_IN_IRQ_EDGE) 326 mv_gpio_edge(pin, 1); 327 if (flags & MV_GPIO_IN_IRQ_LEVEL) 328 mv_gpio_level(pin, 1); 329 330 gpio_setup[pin] = flags; 331 332 return (0); 333 } 334 335 void 336 mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable) 337 { 338 339 mv_gpio_value_set(pin, val); 340 mv_gpio_out_en(pin, enable); 341 } 342 343 uint8_t 344 mv_gpio_in(uint32_t pin) 345 { 346 347 return (mv_gpio_value_get(pin) ? 1 : 0); 348 } 349 350 static uint32_t 351 mv_gpio_reg_read(uint32_t reg) 352 { 353 354 return (bus_space_read_4(mv_gpio_softc->bst, 355 mv_gpio_softc->bsh, reg)); 356 } 357 358 static void 359 mv_gpio_reg_write(uint32_t reg, uint32_t val) 360 { 361 362 bus_space_write_4(mv_gpio_softc->bst, 363 mv_gpio_softc->bsh, reg, val); 364 } 365 366 static void 367 mv_gpio_reg_set(uint32_t reg, uint32_t pin) 368 { 369 uint32_t reg_val; 370 371 reg_val = mv_gpio_reg_read(reg); 372 reg_val |= GPIO(pin); 373 mv_gpio_reg_write(reg, reg_val); 374 } 375 376 static void 377 mv_gpio_reg_clear(uint32_t reg, uint32_t pin) 378 { 379 uint32_t reg_val; 380 381 reg_val = mv_gpio_reg_read(reg); 382 reg_val &= ~(GPIO(pin)); 383 mv_gpio_reg_write(reg, reg_val); 384 } 385 386 static void 387 mv_gpio_out_en(uint32_t pin, uint8_t enable) 388 { 389 uint32_t reg; 390 391 if (pin >= mv_gpio_softc->pin_num) 392 return; 393 394 if (pin >= GPIO_PINS_PER_REG) { 395 reg = GPIO_HI_DATA_OUT_EN_CTRL; 396 pin -= GPIO_PINS_PER_REG; 397 } else 398 reg = GPIO_DATA_OUT_EN_CTRL; 399 400 if (enable) 401 mv_gpio_reg_clear(reg, pin); 402 else 403 mv_gpio_reg_set(reg, pin); 404 } 405 406 static void 407 mv_gpio_blink(uint32_t pin, uint8_t enable) 408 { 409 uint32_t reg; 410 411 if (pin >= mv_gpio_softc->pin_num) 412 return; 413 414 if (pin >= GPIO_PINS_PER_REG) { 415 reg = GPIO_HI_BLINK_EN; 416 pin -= GPIO_PINS_PER_REG; 417 } else 418 reg = GPIO_BLINK_EN; 419 420 if (enable) 421 mv_gpio_reg_set(reg, pin); 422 else 423 mv_gpio_reg_clear(reg, pin); 424 } 425 426 static void 427 mv_gpio_polarity(uint32_t pin, uint8_t enable) 428 { 429 uint32_t reg; 430 431 if (pin >= mv_gpio_softc->pin_num) 432 return; 433 434 if (pin >= GPIO_PINS_PER_REG) { 435 reg = GPIO_HI_DATA_IN_POLAR; 436 pin -= GPIO_PINS_PER_REG; 437 } else 438 reg = GPIO_DATA_IN_POLAR; 439 440 if (enable) 441 mv_gpio_reg_set(reg, pin); 442 else 443 mv_gpio_reg_clear(reg, pin); 444 } 445 446 static void 447 mv_gpio_level(uint32_t pin, uint8_t enable) 448 { 449 uint32_t reg; 450 451 if (pin >= mv_gpio_softc->pin_num) 452 return; 453 454 if (pin >= GPIO_PINS_PER_REG) { 455 reg = GPIO_HI_INT_LEV_MASK; 456 pin -= GPIO_PINS_PER_REG; 457 } else 458 reg = GPIO_INT_LEV_MASK; 459 460 if (enable) 461 mv_gpio_reg_set(reg, pin); 462 else 463 mv_gpio_reg_clear(reg, pin); 464 } 465 466 static void 467 mv_gpio_edge(uint32_t pin, uint8_t enable) 468 { 469 uint32_t reg; 470 471 if (pin >= mv_gpio_softc->pin_num) 472 return; 473 474 if (pin >= GPIO_PINS_PER_REG) { 475 reg = GPIO_HI_INT_EDGE_MASK; 476 pin -= GPIO_PINS_PER_REG; 477 } else 478 reg = GPIO_INT_EDGE_MASK; 479 480 if (enable) 481 mv_gpio_reg_set(reg, pin); 482 else 483 mv_gpio_reg_clear(reg, pin); 484 } 485 486 static void 487 mv_gpio_int_ack(uint32_t pin) 488 { 489 uint32_t reg; 490 491 if (pin >= mv_gpio_softc->pin_num) 492 return; 493 494 if (pin >= GPIO_PINS_PER_REG) { 495 reg = GPIO_HI_INT_CAUSE; 496 pin -= GPIO_PINS_PER_REG; 497 } else 498 reg = GPIO_INT_CAUSE; 499 500 mv_gpio_reg_clear(reg, pin); 501 } 502 503 static uint32_t 504 mv_gpio_value_get(uint32_t pin) 505 { 506 uint32_t reg, reg_val; 507 508 if (pin >= mv_gpio_softc->pin_num) 509 return (0); 510 511 if (pin >= GPIO_PINS_PER_REG) { 512 reg = GPIO_HI_DATA_IN; 513 pin -= GPIO_PINS_PER_REG; 514 } else 515 reg = GPIO_DATA_IN; 516 517 reg_val = mv_gpio_reg_read(reg); 518 519 return (reg_val & GPIO(pin)); 520 } 521 522 static void 523 mv_gpio_value_set(uint32_t pin, uint8_t val) 524 { 525 uint32_t reg; 526 527 if (pin >= mv_gpio_softc->pin_num) 528 return; 529 530 if (pin >= GPIO_PINS_PER_REG) { 531 reg = GPIO_HI_DATA_OUT; 532 pin -= GPIO_PINS_PER_REG; 533 } else 534 reg = GPIO_DATA_OUT; 535 536 if (val) 537 mv_gpio_reg_set(reg, pin); 538 else 539 mv_gpio_reg_clear(reg, pin); 540 } 541 542 int 543 mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len) 544 { 545 pcell_t gpio_cells, pincnt; 546 int inc, t, tuples, tuple_size; 547 int dir, flags, pin; 548 u_long gpio_ctrl, size; 549 struct mv_gpio_softc sc; 550 551 pincnt = 0; 552 if (OF_getproplen(ctrl, "gpio-controller") <= 0) 553 /* Node is not a GPIO controller. */ 554 return (ENXIO); 555 556 if (OF_getprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0) 557 return (ENXIO); 558 559 gpio_cells = fdt32_to_cpu(gpio_cells); 560 if (gpio_cells != 3) 561 return (ENXIO); 562 563 tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t); 564 tuples = len / tuple_size; 565 566 if (fdt_regsize(ctrl, &gpio_ctrl, &size)) 567 return (ENXIO); 568 /* 569 * Since to set up GPIO we use the same functions as GPIO driver, and 570 * mv_gpio_softc is NULL at this early stage, we need to create a fake 571 * softc and set mv_gpio_softc pointer to that newly created object. 572 * After successful GPIO setup, the [shared] pointer will be set back 573 * to NULL. 574 */ 575 mv_gpio_softc = ≻ 576 577 sc.bst = fdtbus_bs_tag; 578 gpio_ctrl += fdt_immr_va; 579 580 if (bus_space_map(sc.bst, gpio_ctrl, size, 0, &sc.bsh) != 0) 581 return (ENXIO); 582 583 if (OF_getprop(ctrl, "pin-count", &pincnt, sizeof(pcell_t)) < 0) 584 return (ENXIO); 585 sc.pin_num = fdt32_to_cpu(pincnt); 586 587 /* 588 * Skip controller reference, since controller's phandle is given 589 * explicitly (in a function argument). 590 */ 591 inc = sizeof(ihandle_t) / sizeof(pcell_t); 592 gpios += inc; 593 594 for (t = 0; t < tuples; t++) { 595 pin = fdt32_to_cpu(gpios[0]); 596 dir = fdt32_to_cpu(gpios[1]); 597 flags = fdt32_to_cpu(gpios[2]); 598 599 mv_gpio_configure(pin, flags); 600 601 if (dir == 1) 602 /* Input. */ 603 mv_gpio_out_en(pin, 0); 604 else { 605 /* Output. */ 606 if (flags & MV_GPIO_OUT_OPEN_DRAIN) 607 mv_gpio_out(pin, 0, 1); 608 609 if (flags & MV_GPIO_OUT_OPEN_SRC) 610 mv_gpio_out(pin, 1, 1); 611 } 612 gpios += gpio_cells + inc; 613 } 614 615 /* Reset pointer. */ 616 mv_gpio_softc = NULL; 617 return (0); 618 } 619 620 #define MAX_PINS_PER_NODE 5 621 #define GPIOS_PROP_CELLS 4 622 int 623 platform_gpio_init(void) 624 { 625 phandle_t child, parent, root, ctrl; 626 ihandle_t ctrl_ihandle; 627 pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS]; 628 struct gpio_ctrl_entry *e; 629 int len, rv; 630 631 root = OF_finddevice("/"); 632 len = 0; 633 parent = root; 634 635 /* Traverse through entire tree to find nodes with 'gpios' prop */ 636 for (child = OF_child(parent); child != 0; child = OF_peer(child)) { 637 638 /* Find a 'leaf'. Start the search from this node. */ 639 while (OF_child(child)) { 640 parent = child; 641 child = OF_child(child); 642 } 643 if ((len = OF_getproplen(child, "gpios")) > 0) { 644 645 if (len > sizeof(gpios)) 646 return (ENXIO); 647 648 /* Get 'gpios' property. */ 649 OF_getprop(child, "gpios", &gpios, len); 650 651 e = (struct gpio_ctrl_entry *)&gpio_controllers; 652 653 /* Find and call a handler. */ 654 for (; e->compat; e++) { 655 /* 656 * First cell of 'gpios' property should 657 * contain a ref. to a node defining GPIO 658 * controller. 659 */ 660 ctrl_ihandle = (ihandle_t)gpios[0]; 661 ctrl_ihandle = fdt32_to_cpu(ctrl_ihandle); 662 ctrl = OF_instance_to_package(ctrl_ihandle); 663 664 if (fdt_is_compatible(ctrl, e->compat)) 665 /* Call a handler. */ 666 if ((rv = e->handler(ctrl, 667 (pcell_t *)&gpios, len))) 668 return (rv); 669 } 670 } 671 672 if (OF_peer(child) == 0) { 673 /* No more siblings. */ 674 child = parent; 675 parent = OF_parent(child); 676 } 677 } 678 return (0); 679 } 680