1 /* $OpenBSD: rkgpio.c,v 1.10 2023/03/05 14:45:07 patrick Exp $ */ 2 /* 3 * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org> 4 * Copyright (c) 2019 Patrick Wildt <patrick@blueri.se> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/device.h> 22 #include <sys/malloc.h> 23 #include <sys/evcount.h> 24 25 #include <machine/intr.h> 26 #include <machine/bus.h> 27 #include <machine/fdt.h> 28 29 #include <dev/ofw/openfirm.h> 30 #include <dev/ofw/ofw_gpio.h> 31 #include <dev/ofw/fdt.h> 32 33 /* Registers. */ 34 35 #define GPIO_SWPORTA_DR 0x0000 36 #define GPIO_SWPORTA_DDR 0x0004 37 #define GPIO_INTEN 0x0030 38 #define GPIO_INTMASK 0x0034 39 #define GPIO_INTTYPE_LEVEL 0x0038 40 #define GPIO_INT_POLARITY 0x003c 41 #define GPIO_INT_STATUS 0x0040 42 #define GPIO_INT_RAWSTATUS 0x0044 43 #define GPIO_DEBOUNCE 0x0048 44 #define GPIO_PORTS_EOI 0x004c 45 #define GPIO_EXT_PORTA 0x0050 46 47 #define GPIO_SWPORT_DR_L 0x0000 48 #define GPIO_SWPORT_DR_H 0x0004 49 #define GPIO_SWPORT_DDR_L 0x0008 50 #define GPIO_SWPORT_DDR_H 0x000c 51 #define GPIO_INT_EN_L 0x0010 52 #define GPIO_INT_EN_H 0x0014 53 #define GPIO_INT_MASK_L 0x0018 54 #define GPIO_INT_MASK_H 0x001c 55 #define GPIO_INT_TYPE_L 0x0020 56 #define GPIO_INT_TYPE_H 0x0024 57 #define GPIO_INT_POLARITY_L 0x0028 58 #define GPIO_INT_POLARITY_H 0x002c 59 #define GPIO_EXT_PORT 0x0070 60 #define GPIO_VER_ID 0x0078 61 #define GPIO_VER_ID_1_0 0x00000000 62 #define GPIO_VER_ID_2_0 0x01000c2b 63 #define GPIO_VER_ID_2_1 0x0101157c 64 65 #define GPIO_NUM_PINS 32 66 67 #define HREAD4(sc, reg) \ 68 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 69 #define HWRITE4(sc, reg, val) \ 70 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 71 #define HSET4(sc, reg, bits) \ 72 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 73 #define HCLR4(sc, reg, bits) \ 74 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 75 76 struct intrhand { 77 int (*ih_func)(void *); /* handler */ 78 void *ih_arg; /* arg for handler */ 79 int ih_ipl; /* IPL_* */ 80 int ih_irq; /* IRQ number */ 81 int ih_level; /* GPIO level */ 82 struct evcount ih_count; 83 char *ih_name; 84 void *ih_sc; 85 }; 86 87 struct rkgpio_softc { 88 struct device sc_dev; 89 bus_space_tag_t sc_iot; 90 bus_space_handle_t sc_ioh; 91 int sc_node; 92 int sc_version; 93 94 void *sc_ih; 95 int sc_ipl; 96 int sc_irq; 97 struct intrhand *sc_handlers[GPIO_NUM_PINS]; 98 struct interrupt_controller sc_ic; 99 100 struct gpio_controller sc_gc; 101 }; 102 103 int rkgpio_match(struct device *, void *, void *); 104 void rkgpio_attach(struct device *, struct device *, void *); 105 106 const struct cfattach rkgpio_ca = { 107 sizeof (struct rkgpio_softc), rkgpio_match, rkgpio_attach 108 }; 109 110 struct cfdriver rkgpio_cd = { 111 NULL, "rkgpio", DV_DULL 112 }; 113 114 void rkgpio_config_pin(void *, uint32_t *, int); 115 int rkgpio_get_pin(void *, uint32_t *); 116 void rkgpio_set_pin(void *, uint32_t *, int); 117 118 int rkgpio_intr(void *); 119 void *rkgpio_intr_establish(void *, int *, int, struct cpu_info *, 120 int (*)(void *), void *, char *); 121 void rkgpio_intr_disestablish(void *); 122 void rkgpio_recalc_ipl(struct rkgpio_softc *); 123 void rkgpio_intr_enable(void *); 124 void rkgpio_intr_disable(void *); 125 void rkgpio_intr_barrier(void *); 126 127 int 128 rkgpio_match(struct device *parent, void *match, void *aux) 129 { 130 struct fdt_attach_args *faa = aux; 131 132 return OF_is_compatible(faa->fa_node, "rockchip,gpio-bank"); 133 } 134 135 void 136 rkgpio_attach(struct device *parent, struct device *self, void *aux) 137 { 138 struct rkgpio_softc *sc = (struct rkgpio_softc *)self; 139 struct fdt_attach_args *faa = aux; 140 uint32_t ver_id; 141 142 if (faa->fa_nreg < 1) { 143 printf(": no registers\n"); 144 return; 145 } 146 147 sc->sc_node = faa->fa_node; 148 sc->sc_iot = faa->fa_iot; 149 150 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 151 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 152 printf(": can't map registers\n"); 153 return; 154 } 155 156 ver_id = HREAD4(sc, GPIO_VER_ID); 157 switch (ver_id) { 158 case GPIO_VER_ID_1_0: 159 sc->sc_version = 1; 160 break; 161 case GPIO_VER_ID_2_0: 162 case GPIO_VER_ID_2_1: 163 sc->sc_version = 2; 164 break; 165 default: 166 printf(": unknown version 0x%08x\n", ver_id); 167 return; 168 } 169 170 sc->sc_gc.gc_node = faa->fa_node; 171 sc->sc_gc.gc_cookie = sc; 172 sc->sc_gc.gc_config_pin = rkgpio_config_pin; 173 sc->sc_gc.gc_get_pin = rkgpio_get_pin; 174 sc->sc_gc.gc_set_pin = rkgpio_set_pin; 175 gpio_controller_register(&sc->sc_gc); 176 177 sc->sc_ipl = IPL_NONE; 178 if (sc->sc_version == 2) { 179 HWRITE4(sc, GPIO_INT_MASK_L, ~0); 180 HWRITE4(sc, GPIO_INT_MASK_H, ~0); 181 HWRITE4(sc, GPIO_INT_EN_L, ~0); 182 HWRITE4(sc, GPIO_INT_EN_H, ~0); 183 } else { 184 HWRITE4(sc, GPIO_INTMASK, ~0); 185 HWRITE4(sc, GPIO_INTEN, ~0); 186 } 187 188 sc->sc_ic.ic_node = faa->fa_node; 189 sc->sc_ic.ic_cookie = sc; 190 sc->sc_ic.ic_establish = rkgpio_intr_establish; 191 sc->sc_ic.ic_disestablish = rkgpio_intr_disestablish; 192 sc->sc_ic.ic_enable = rkgpio_intr_enable; 193 sc->sc_ic.ic_disable = rkgpio_intr_disable; 194 sc->sc_ic.ic_barrier = rkgpio_intr_barrier; 195 fdt_intr_register(&sc->sc_ic); 196 197 printf("\n"); 198 } 199 200 void 201 rkgpio_config_pin(void *cookie, uint32_t *cells, int config) 202 { 203 struct rkgpio_softc *sc = cookie; 204 uint32_t pin = cells[0]; 205 uint32_t reg; 206 207 if (pin >= GPIO_NUM_PINS) 208 return; 209 210 if (sc->sc_version == 2) { 211 reg = (1 << (pin % 16)) << 16; 212 if (config & GPIO_CONFIG_OUTPUT) 213 reg |= (1 << (pin % 16)); 214 HWRITE4(sc, GPIO_SWPORT_DDR_L + (pin / 16) * 4, reg); 215 } else { 216 if (config & GPIO_CONFIG_OUTPUT) 217 HSET4(sc, GPIO_SWPORTA_DDR, (1 << pin)); 218 else 219 HCLR4(sc, GPIO_SWPORTA_DDR, (1 << pin)); 220 } 221 } 222 223 int 224 rkgpio_get_pin(void *cookie, uint32_t *cells) 225 { 226 struct rkgpio_softc *sc = cookie; 227 uint32_t pin = cells[0]; 228 uint32_t flags = cells[1]; 229 uint32_t reg; 230 int val; 231 232 if (pin >= GPIO_NUM_PINS) 233 return 0; 234 235 if (sc->sc_version == 2) 236 reg = HREAD4(sc, GPIO_EXT_PORT); 237 else 238 reg = HREAD4(sc, GPIO_EXT_PORTA); 239 val = (reg >> pin) & 1; 240 if (flags & GPIO_ACTIVE_LOW) 241 val = !val; 242 return val; 243 } 244 245 void 246 rkgpio_set_pin(void *cookie, uint32_t *cells, int val) 247 { 248 struct rkgpio_softc *sc = cookie; 249 uint32_t pin = cells[0]; 250 uint32_t flags = cells[1]; 251 uint32_t reg; 252 253 if (pin >= GPIO_NUM_PINS) 254 return; 255 256 if (flags & GPIO_ACTIVE_LOW) 257 val = !val; 258 if (sc->sc_version == 2) { 259 reg = (1 << (pin % 16)) << 16; 260 if (val) 261 reg |= (1 << (pin % 16)); 262 HWRITE4(sc, GPIO_SWPORT_DR_L + (pin / 16) * 4, reg); 263 } else { 264 if (val) 265 HSET4(sc, GPIO_SWPORTA_DR, (1 << pin)); 266 else 267 HCLR4(sc, GPIO_SWPORTA_DR, (1 << pin)); 268 } 269 } 270 271 int 272 rkgpio_intr(void *cookie) 273 { 274 struct rkgpio_softc *sc = (struct rkgpio_softc *)cookie; 275 struct intrhand *ih; 276 uint32_t status, pending; 277 int pin, s; 278 279 status = HREAD4(sc, GPIO_INT_STATUS); 280 pending = status; 281 282 while (pending) { 283 pin = ffs(pending) - 1; 284 285 if ((ih = sc->sc_handlers[pin]) != NULL) { 286 s = splraise(ih->ih_ipl); 287 if (ih->ih_func(ih->ih_arg)) 288 ih->ih_count.ec_count++; 289 splx(s); 290 } 291 292 pending &= ~(1 << pin); 293 } 294 295 HWRITE4(sc, GPIO_PORTS_EOI, status); 296 297 return 1; 298 } 299 300 void * 301 rkgpio_intr_establish(void *cookie, int *cells, int ipl, 302 struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 303 { 304 struct rkgpio_softc *sc = (struct rkgpio_softc *)cookie; 305 struct intrhand *ih; 306 int irqno = cells[0]; 307 int level = cells[1]; 308 int s; 309 310 if (irqno < 0 || irqno >= GPIO_NUM_PINS) 311 panic("%s: bogus irqnumber %d: %s", __func__, 312 irqno, name); 313 314 if (sc->sc_handlers[irqno] != NULL) 315 panic("%s: irqnumber %d reused: %s", __func__, 316 irqno, name); 317 318 if (ci != NULL && !CPU_IS_PRIMARY(ci)) 319 return NULL; 320 321 ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK); 322 ih->ih_func = func; 323 ih->ih_arg = arg; 324 ih->ih_ipl = ipl & IPL_IRQMASK; 325 ih->ih_irq = irqno; 326 ih->ih_name = name; 327 ih->ih_level = level; 328 ih->ih_sc = sc; 329 330 s = splhigh(); 331 332 sc->sc_handlers[irqno] = ih; 333 334 if (name != NULL) 335 evcount_attach(&ih->ih_count, name, &ih->ih_irq); 336 337 #ifdef DEBUG_INTC 338 printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl, 339 ih->ih_name); 340 #endif 341 342 rkgpio_recalc_ipl(sc); 343 344 if (sc->sc_version == 2) { 345 uint32_t bit = (1 << (irqno % 16)); 346 uint32_t mask = bit << 16; 347 bus_size_t off = (irqno / 16) * 4; 348 349 switch (level) { 350 case 1: /* rising */ 351 HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask | bit); 352 HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask | bit); 353 break; 354 case 2: /* falling */ 355 HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask | bit); 356 HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask); 357 break; 358 case 4: /* high */ 359 HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask); 360 HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask | bit); 361 break; 362 case 8: /* low */ 363 HWRITE4(sc, GPIO_INT_TYPE_L + off * 4, mask); 364 HWRITE4(sc, GPIO_INT_POLARITY_L + off * 4, mask); 365 break; 366 default: 367 panic("%s: unsupported trigger type", __func__); 368 } 369 370 HWRITE4(sc, GPIO_SWPORT_DDR_L + off, mask); 371 HWRITE4(sc, GPIO_INT_MASK_L + off, mask); 372 } else { 373 switch (level) { 374 case 1: /* rising */ 375 HSET4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno); 376 HSET4(sc, GPIO_INT_POLARITY, 1 << irqno); 377 break; 378 case 2: /* falling */ 379 HSET4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno); 380 HCLR4(sc, GPIO_INT_POLARITY, 1 << irqno); 381 break; 382 case 4: /* high */ 383 HCLR4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno); 384 HSET4(sc, GPIO_INT_POLARITY, 1 << irqno); 385 break; 386 case 8: /* low */ 387 HCLR4(sc, GPIO_INTTYPE_LEVEL, 1 << irqno); 388 HCLR4(sc, GPIO_INT_POLARITY, 1 << irqno); 389 break; 390 default: 391 panic("%s: unsupported trigger type", __func__); 392 } 393 394 HCLR4(sc, GPIO_SWPORTA_DDR, 1 << irqno); 395 HCLR4(sc, GPIO_INTMASK, 1 << irqno); 396 } 397 398 splx(s); 399 return (ih); 400 } 401 402 void 403 rkgpio_intr_disestablish(void *cookie) 404 { 405 struct intrhand *ih = cookie; 406 struct rkgpio_softc *sc = ih->ih_sc; 407 uint32_t bit = (1 << (ih->ih_irq % 16)); 408 uint32_t mask = bit << 16; 409 bus_size_t off = (ih->ih_irq / 16) * 4; 410 int s; 411 412 s = splhigh(); 413 414 #ifdef DEBUG_INTC 415 printf("%s: irq %d ipl %d [%s]\n", __func__, ih->ih_irq, ih->ih_ipl, 416 ih->ih_name); 417 #endif 418 419 if (sc->sc_version == 2) 420 HWRITE4(sc, GPIO_INT_MASK_L + off, mask | bit); 421 else 422 HSET4(sc, GPIO_INTMASK, 1 << ih->ih_irq); 423 424 sc->sc_handlers[ih->ih_irq] = NULL; 425 if (ih->ih_name != NULL) 426 evcount_detach(&ih->ih_count); 427 free(ih, M_DEVBUF, sizeof(*ih)); 428 429 rkgpio_recalc_ipl(sc); 430 431 splx(s); 432 } 433 434 void 435 rkgpio_recalc_ipl(struct rkgpio_softc *sc) 436 { 437 struct intrhand *ih; 438 int max = IPL_NONE; 439 int min = IPL_HIGH; 440 int pin; 441 442 for (pin = 0; pin < GPIO_NUM_PINS; pin++) { 443 ih = sc->sc_handlers[pin]; 444 if (ih == NULL) 445 continue; 446 447 if (ih->ih_ipl > max) 448 max = ih->ih_ipl; 449 450 if (ih->ih_ipl < min) 451 min = ih->ih_ipl; 452 } 453 454 if (max == IPL_NONE) 455 min = IPL_NONE; 456 457 if (sc->sc_ipl != max) { 458 sc->sc_ipl = max; 459 460 if (sc->sc_ih != NULL) 461 fdt_intr_disestablish(sc->sc_ih); 462 463 if (sc->sc_ipl != IPL_NONE) 464 sc->sc_ih = fdt_intr_establish(sc->sc_node, 465 sc->sc_ipl, rkgpio_intr, sc, sc->sc_dev.dv_xname); 466 } 467 } 468 469 void 470 rkgpio_intr_enable(void *cookie) 471 { 472 struct intrhand *ih = cookie; 473 struct rkgpio_softc *sc = ih->ih_sc; 474 uint32_t bit = (1 << (ih->ih_irq % 16)); 475 uint32_t mask = bit << 16; 476 bus_size_t off = (ih->ih_irq / 16) * 4; 477 int s; 478 479 s = splhigh(); 480 if (sc->sc_version == 2) 481 HWRITE4(sc, GPIO_INT_MASK_L + off, mask); 482 else 483 HCLR4(sc, GPIO_INTMASK, 1 << ih->ih_irq); 484 splx(s); 485 } 486 487 void 488 rkgpio_intr_disable(void *cookie) 489 { 490 struct intrhand *ih = cookie; 491 struct rkgpio_softc *sc = ih->ih_sc; 492 uint32_t bit = (1 << (ih->ih_irq % 16)); 493 uint32_t mask = bit << 16; 494 bus_size_t off = (ih->ih_irq / 16) * 4; 495 int s; 496 497 s = splhigh(); 498 if (sc->sc_version == 2) 499 HWRITE4(sc, GPIO_INT_MASK_L + off, mask | bit); 500 else 501 HSET4(sc, GPIO_INTMASK, 1 << ih->ih_irq); 502 splx(s); 503 } 504 505 void 506 rkgpio_intr_barrier(void *cookie) 507 { 508 struct intrhand *ih = cookie; 509 struct rkgpio_softc *sc = ih->ih_sc; 510 511 intr_barrier(sc->sc_ih); 512 } 513