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