1 /* $OpenBSD: rkpinctrl.c,v 1.9 2022/10/09 20:30:59 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2017, 2018 Mark Kettenis <kettenis@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/device.h> 21 #include <sys/malloc.h> 22 23 #include <machine/intr.h> 24 #include <machine/bus.h> 25 #include <machine/fdt.h> 26 27 #include <dev/ofw/openfirm.h> 28 #include <dev/ofw/ofw_misc.h> 29 #include <dev/ofw/ofw_pinctrl.h> 30 #include <dev/ofw/fdt.h> 31 32 #ifdef __armv7__ 33 #include <arm/simplebus/simplebusvar.h> 34 #else 35 #include <arm64/dev/simplebusvar.h> 36 #endif 37 38 /* RK3288 registers */ 39 #define RK3288_GRF_GPIO1A_IOMUX 0x0000 40 #define RK3288_PMUGRF_GPIO0A_IOMUX 0x0084 41 42 /* RK3308 registers */ 43 #define RK3308_GRF_GPIO0A_IOMUX 0x0000 44 45 /* RK3328 registers */ 46 #define RK3328_GRF_GPIO0A_IOMUX 0x0000 47 48 /* RK3399 registers */ 49 #define RK3399_GRF_GPIO2A_IOMUX 0xe000 50 #define RK3399_PMUGRF_GPIO0A_IOMUX 0x0000 51 52 /* RK3568 registers */ 53 #define RK3568_GRF_GPIO1A_IOMUX_L 0x0000 54 #define RK3568_GRF_GPIO1A_P 0x0080 55 #define RK3568_GRF_GPIO1A_IE 0x00c0 56 #define RK3568_GRF_GPIO1A_DS_0 0x0200 57 #define RK3568_PMUGRF_GPIO0A_IOMUX_L 0x0000 58 #define RK3568_PMUGRF_GPIO0A_P 0x0020 59 #define RK3568_PMUGRF_GPIO0A_IE 0x0030 60 #define RK3568_PMUGRF_GPIO0A_DS_0 0x0070 61 62 struct rkpinctrl_softc { 63 struct simplebus_softc sc_sbus; 64 65 struct regmap *sc_grf; 66 struct regmap *sc_pmu; 67 }; 68 69 int rkpinctrl_match(struct device *, void *, void *); 70 void rkpinctrl_attach(struct device *, struct device *, void *); 71 72 const struct cfattach rkpinctrl_ca = { 73 sizeof (struct rkpinctrl_softc), rkpinctrl_match, rkpinctrl_attach 74 }; 75 76 struct cfdriver rkpinctrl_cd = { 77 NULL, "rkpinctrl", DV_DULL 78 }; 79 80 int rk3288_pinctrl(uint32_t, void *); 81 int rk3308_pinctrl(uint32_t, void *); 82 int rk3328_pinctrl(uint32_t, void *); 83 int rk3399_pinctrl(uint32_t, void *); 84 int rk3568_pinctrl(uint32_t, void *); 85 86 int 87 rkpinctrl_match(struct device *parent, void *match, void *aux) 88 { 89 struct fdt_attach_args *faa = aux; 90 91 return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl") || 92 OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl") || 93 OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl") || 94 OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl") || 95 OF_is_compatible(faa->fa_node, "rockchip,rk3568-pinctrl")); 96 } 97 98 void 99 rkpinctrl_attach(struct device *parent, struct device *self, void *aux) 100 { 101 struct rkpinctrl_softc *sc = (struct rkpinctrl_softc *)self; 102 struct fdt_attach_args *faa = aux; 103 uint32_t grf, pmu; 104 105 grf = OF_getpropint(faa->fa_node, "rockchip,grf", 0); 106 pmu = OF_getpropint(faa->fa_node, "rockchip,pmu", 0); 107 sc->sc_grf = regmap_byphandle(grf); 108 sc->sc_pmu = regmap_byphandle(pmu); 109 110 if (sc->sc_grf == NULL && sc->sc_pmu == NULL) { 111 printf(": no registers\n"); 112 return; 113 } 114 115 if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl")) 116 pinctrl_register(faa->fa_node, rk3288_pinctrl, sc); 117 else if (OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl")) 118 pinctrl_register(faa->fa_node, rk3308_pinctrl, sc); 119 else if (OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl")) 120 pinctrl_register(faa->fa_node, rk3328_pinctrl, sc); 121 else if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl")) 122 pinctrl_register(faa->fa_node, rk3399_pinctrl, sc); 123 else 124 pinctrl_register(faa->fa_node, rk3568_pinctrl, sc); 125 126 /* Attach GPIO banks. */ 127 simplebus_attach(parent, &sc->sc_sbus.sc_dev, faa); 128 } 129 130 /* 131 * Rockchip RK3288 132 */ 133 134 int 135 rk3288_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 136 { 137 int node; 138 139 node = OF_getnodebyphandle(phandle); 140 if (node == 0) 141 return -1; 142 143 /* XXX */ 144 if (bank == 0) 145 return -1; 146 147 if (OF_getproplen(node, "bias-disable") == 0) 148 return 0; 149 if (OF_getproplen(node, "bias-pull-up") == 0) 150 return 1; 151 if (OF_getproplen(node, "bias-pull-down") == 0) 152 return 2; 153 154 return -1; 155 } 156 157 int 158 rk3288_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 159 { 160 int strength, level; 161 int levels[4] = { 2, 4, 8, 12 }; 162 int node; 163 164 node = OF_getnodebyphandle(phandle); 165 if (node == 0) 166 return -1; 167 168 /* XXX */ 169 if (bank == 0) 170 return -1; 171 172 strength = OF_getpropint(node, "drive-strength", -1); 173 if (strength == -1) 174 return -1; 175 176 /* Convert drive strength to level. */ 177 for (level = 3; level >= 0; level--) { 178 if (strength >= levels[level]) 179 break; 180 } 181 return level; 182 } 183 184 int 185 rk3288_pinctrl(uint32_t phandle, void *cookie) 186 { 187 struct rkpinctrl_softc *sc = cookie; 188 uint32_t *pins; 189 int node, len, i; 190 191 KASSERT(sc->sc_grf); 192 KASSERT(sc->sc_pmu); 193 194 node = OF_getnodebyphandle(phandle); 195 if (node == 0) 196 return -1; 197 198 len = OF_getproplen(node, "rockchip,pins"); 199 if (len <= 0) 200 return -1; 201 202 pins = malloc(len, M_TEMP, M_WAITOK); 203 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 204 goto fail; 205 206 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 207 struct regmap *rm; 208 bus_size_t base, off; 209 uint32_t bank, idx, mux; 210 int pull, strength; 211 uint32_t mask, bits; 212 int s; 213 214 bank = pins[i]; 215 idx = pins[i + 1]; 216 mux = pins[i + 2]; 217 pull = rk3288_pull(bank, idx, pins[i + 3]); 218 strength = rk3288_strength(bank, idx, pins[i + 3]); 219 220 if (bank > 8 || idx > 32 || mux > 7) 221 continue; 222 223 /* Bank 0 lives in the PMU. */ 224 if (bank < 1) { 225 rm = sc->sc_pmu; 226 base = RK3288_PMUGRF_GPIO0A_IOMUX; 227 } else { 228 rm = sc->sc_grf; 229 base = RK3288_GRF_GPIO1A_IOMUX - 0x10; 230 } 231 232 s = splhigh(); 233 234 /* IOMUX control */ 235 off = bank * 0x10 + (idx / 8) * 0x04; 236 237 /* GPIO3D, GPIO4A and GPIO4B are special. */ 238 if ((bank == 3 && idx >= 24) || (bank == 4 && idx < 16)) { 239 mask = (0x7 << ((idx % 4) * 4)); 240 bits = (mux << ((idx % 4) * 4)); 241 } else { 242 mask = (0x3 << ((idx % 8) * 2)); 243 bits = (mux << ((idx % 8) * 2)); 244 } 245 if (bank > 3 || (bank == 3 && idx >= 28)) 246 off += 0x04; 247 if (bank > 4 || (bank == 4 && idx >= 4)) 248 off += 0x04; 249 if (bank > 4 || (bank == 4 && idx >= 12)) 250 off += 0x04; 251 regmap_write_4(rm, base + off, mask << 16 | bits); 252 253 /* GPIO pad pull down and pull up control */ 254 if (pull >= 0) { 255 off = 0x140 + bank * 0x10 + (idx / 8) * 0x04; 256 mask = (0x3 << ((idx % 8) * 2)); 257 bits = (pull << ((idx % 8) * 2)); 258 regmap_write_4(rm, base + off, mask << 16 | bits); 259 } 260 261 /* GPIO drive strength control */ 262 if (strength >= 0) { 263 off = 0x1c0 + bank * 0x10 + (idx / 8) * 0x04; 264 mask = (0x3 << ((idx % 8) * 2)); 265 bits = (strength << ((idx % 8) * 2)); 266 regmap_write_4(rm, base + off, mask << 16 | bits); 267 } 268 269 splx(s); 270 } 271 272 free(pins, M_TEMP, len); 273 return 0; 274 275 fail: 276 free(pins, M_TEMP, len); 277 return -1; 278 } 279 280 /* 281 * Rockchip RK3308 282 */ 283 284 int 285 rk3308_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 286 { 287 int node; 288 289 node = OF_getnodebyphandle(phandle); 290 if (node == 0) 291 return -1; 292 293 if (OF_getproplen(node, "bias-disable") == 0) 294 return 0; 295 if (OF_getproplen(node, "bias-pull-up") == 0) 296 return 1; 297 if (OF_getproplen(node, "bias-pull-down") == 0) 298 return 2; 299 300 return -1; 301 } 302 303 int 304 rk3308_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 305 { 306 int strength, level; 307 int levels[4] = { 2, 4, 8, 12 }; 308 int node; 309 310 node = OF_getnodebyphandle(phandle); 311 if (node == 0) 312 return -1; 313 314 strength = OF_getpropint(node, "drive-strength", -1); 315 if (strength == -1) 316 return -1; 317 318 /* Convert drive strength to level. */ 319 for (level = 3; level >= 0; level--) { 320 if (strength >= levels[level]) 321 break; 322 } 323 return level; 324 } 325 326 int 327 rk3308_pinctrl(uint32_t phandle, void *cookie) 328 { 329 struct rkpinctrl_softc *sc = cookie; 330 uint32_t *pins; 331 int node, len, i; 332 333 KASSERT(sc->sc_grf); 334 335 node = OF_getnodebyphandle(phandle); 336 if (node == 0) 337 return -1; 338 339 len = OF_getproplen(node, "rockchip,pins"); 340 if (len <= 0) 341 return -1; 342 343 pins = malloc(len, M_TEMP, M_WAITOK); 344 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 345 goto fail; 346 347 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 348 struct regmap *rm = sc->sc_grf; 349 bus_size_t base, off; 350 uint32_t bank, idx, mux; 351 int pull, strength; 352 uint32_t mask, bits; 353 int s; 354 355 bank = pins[i]; 356 idx = pins[i + 1]; 357 mux = pins[i + 2]; 358 pull = rk3308_pull(bank, idx, pins[i + 3]); 359 strength = rk3308_strength(bank, idx, pins[i + 3]); 360 361 if (bank > 4 || idx > 32 || mux > 7) 362 continue; 363 364 base = RK3308_GRF_GPIO0A_IOMUX; 365 366 s = splhigh(); 367 368 /* IOMUX control */ 369 off = bank * 0x20 + (idx / 8) * 0x08; 370 371 /* GPIO1B, GPIO1C and GPIO3B are special. */ 372 if ((bank == 1) && (idx == 14)) { 373 mask = (0xf << 12); 374 bits = (mux << 12); 375 } else if ((bank == 1) && (idx == 15)) { 376 off += 4; 377 mask = 0x3; 378 bits = mux; 379 } else if ((bank == 1) && (idx >= 16 && idx <= 17)) { 380 mask = (0x3 << ((idx - 16) * 2)); 381 bits = (mux << ((idx - 16) * 2)); 382 } else if ((bank == 1) && (idx >= 18 && idx <= 20)) { 383 mask = (0xf << (((idx - 18) * 4) + 4)); 384 bits = (mux << (((idx - 18) * 4) + 4)); 385 } else if ((bank == 1) && (idx >= 21 && idx <= 23)) { 386 off += 4; 387 mask = (0xf << ((idx - 21) * 4)); 388 bits = (mux << ((idx - 21) * 4)); 389 } else if ((bank == 3) && (idx >= 12 && idx <= 13)) { 390 mask = (0xf << (((idx - 12) * 4) + 8)); 391 bits = (mux << (((idx - 12) * 4) + 8)); 392 } else { 393 mask = (0x3 << ((idx % 8) * 2)); 394 bits = (mux << ((idx % 8) * 2)); 395 } 396 regmap_write_4(rm, base + off, mask << 16 | bits); 397 398 /* GPIO pad pull down and pull up control */ 399 if (pull >= 0) { 400 off = 0xa0 + bank * 0x10 + (idx / 8) * 0x04; 401 mask = (0x3 << ((idx % 8) * 2)); 402 bits = (pull << ((idx % 8) * 2)); 403 regmap_write_4(rm, base + off, mask << 16 | bits); 404 } 405 406 /* GPIO drive strength control */ 407 if (strength >= 0) { 408 off = 0x100 + bank * 0x10 + (idx / 8) * 0x04; 409 mask = (0x3 << ((idx % 8) * 2)); 410 bits = (strength << ((idx % 8) * 2)); 411 regmap_write_4(rm, base + off, mask << 16 | bits); 412 } 413 414 splx(s); 415 } 416 417 free(pins, M_TEMP, len); 418 return 0; 419 420 fail: 421 free(pins, M_TEMP, len); 422 return -1; 423 } 424 425 /* 426 * Rockchip RK3328 427 */ 428 429 int 430 rk3328_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 431 { 432 int node; 433 434 node = OF_getnodebyphandle(phandle); 435 if (node == 0) 436 return -1; 437 438 if (OF_getproplen(node, "bias-disable") == 0) 439 return 0; 440 if (OF_getproplen(node, "bias-pull-up") == 0) 441 return 1; 442 if (OF_getproplen(node, "bias-pull-down") == 0) 443 return 2; 444 445 return -1; 446 } 447 448 int 449 rk3328_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 450 { 451 int strength, level; 452 int levels[4] = { 2, 4, 8, 12 }; 453 int node; 454 455 node = OF_getnodebyphandle(phandle); 456 if (node == 0) 457 return -1; 458 459 strength = OF_getpropint(node, "drive-strength", -1); 460 if (strength == -1) 461 return -1; 462 463 /* Convert drive strength to level. */ 464 for (level = 3; level >= 0; level--) { 465 if (strength >= levels[level]) 466 break; 467 } 468 return level; 469 } 470 471 int 472 rk3328_pinctrl(uint32_t phandle, void *cookie) 473 { 474 struct rkpinctrl_softc *sc = cookie; 475 uint32_t *pins; 476 int node, len, i; 477 478 KASSERT(sc->sc_grf); 479 480 node = OF_getnodebyphandle(phandle); 481 if (node == 0) 482 return -1; 483 484 len = OF_getproplen(node, "rockchip,pins"); 485 if (len <= 0) 486 return -1; 487 488 pins = malloc(len, M_TEMP, M_WAITOK); 489 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 490 goto fail; 491 492 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 493 struct regmap *rm = sc->sc_grf; 494 bus_size_t base, off; 495 uint32_t bank, idx, mux; 496 int pull, strength; 497 uint32_t mask, bits; 498 int s; 499 500 bank = pins[i]; 501 idx = pins[i + 1]; 502 mux = pins[i + 2]; 503 pull = rk3288_pull(bank, idx, pins[i + 3]); 504 strength = rk3288_strength(bank, idx, pins[i + 3]); 505 506 if (bank > 3 || idx > 32 || mux > 3) 507 continue; 508 509 base = RK3328_GRF_GPIO0A_IOMUX; 510 511 s = splhigh(); 512 513 /* IOMUX control */ 514 off = bank * 0x10 + (idx / 8) * 0x04; 515 516 /* GPIO2B, GPIO2C, GPIO3A and GPIO3B are special. */ 517 if (bank == 2 && idx == 15) { 518 mask = 0x7; 519 bits = mux; 520 } else if (bank == 2 && idx >= 16 && idx <= 20) { 521 mask = (0x7 << ((idx - 16) * 3)); 522 bits = (mux << ((idx - 16) * 3)); 523 } else if (bank == 2 && idx >= 21 && idx <= 23) { 524 mask = (0x7 << ((idx - 21) * 3)); 525 bits = (mux << ((idx - 21) * 3)); 526 } else if (bank == 3 && idx <= 4) { 527 mask = (0x7 << (idx * 3)); 528 bits = (mux << (idx * 3)); 529 } else if (bank == 3 && idx >= 5 && idx <= 7) { 530 mask = (0x7 << ((idx - 5) * 3)); 531 bits = (mux << ((idx - 5) * 3)); 532 } else if (bank == 3 && idx >= 8 && idx <= 12) { 533 mask = (0x7 << ((idx - 8) * 3)); 534 bits = (mux << ((idx - 8) * 3)); 535 } else if (bank == 3 && idx >= 13 && idx <= 15) { 536 mask = (0x7 << ((idx - 13) * 3)); 537 bits = (mux << ((idx - 13) * 3)); 538 } else { 539 mask = (0x3 << ((idx % 8) * 2)); 540 bits = (mux << ((idx % 8) * 2)); 541 } 542 if (bank > 2 || (bank == 2 && idx >= 15)) 543 off += 0x04; 544 if (bank > 2 || (bank == 2 && idx >= 21)) 545 off += 0x04; 546 if (bank > 3 || (bank == 3 && idx >= 5)) 547 off += 0x04; 548 if (bank > 3 || (bank == 3 && idx >= 13)) 549 off += 0x04; 550 regmap_write_4(rm, base + off, mask << 16 | bits); 551 552 /* GPIO pad pull down and pull up control */ 553 if (pull >= 0) { 554 off = 0x100 + bank * 0x10 + (idx / 8) * 0x04; 555 mask = (0x3 << ((idx % 8) * 2)); 556 bits = (pull << ((idx % 8) * 2)); 557 regmap_write_4(rm, base + off, mask << 16 | bits); 558 } 559 560 /* GPIO drive strength control */ 561 if (strength >= 0) { 562 off = 0x200 + bank * 0x10 + (idx / 8) * 0x04; 563 mask = (0x3 << ((idx % 8) * 2)); 564 bits = (strength << ((idx % 8) * 2)); 565 regmap_write_4(rm, base + off, mask << 16 | bits); 566 } 567 568 splx(s); 569 } 570 571 free(pins, M_TEMP, len); 572 return 0; 573 574 fail: 575 free(pins, M_TEMP, len); 576 return -1; 577 } 578 579 /* 580 * Rockchip RK3399 581 */ 582 583 int 584 rk3399_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 585 { 586 int pull_up, pull_down; 587 int node; 588 589 node = OF_getnodebyphandle(phandle); 590 if (node == 0) 591 return -1; 592 593 if (bank == 2 && idx >= 16) { 594 pull_up = 3; 595 pull_down = 1; 596 } else { 597 pull_up = 1; 598 pull_down = 2; 599 } 600 601 if (OF_getproplen(node, "bias-disable") == 0) 602 return 0; 603 if (OF_getproplen(node, "bias-pull-up") == 0) 604 return pull_up; 605 if (OF_getproplen(node, "bias-pull-down") == 0) 606 return pull_down; 607 608 return -1; 609 } 610 611 /* Magic because the drive strength configurations vary wildly. */ 612 613 const int rk3399_strength_levels[][8] = { 614 { 2, 4, 8, 12 }, /* default */ 615 { 3, 6, 9, 12 }, /* 1.8V or 3.0V */ 616 { 5, 10, 15, 20 }, /* 1.8V only */ 617 { 4, 6, 8, 10, 12, 14, 16, 18 }, /* 1.8V or 3.0V auto */ 618 { 4, 7, 10, 13, 16, 19, 22, 26 }, /* 3.3V */ 619 }; 620 621 const int rk3399_strength_types[][4] = { 622 { 2, 2, 0, 0 }, 623 { 1, 1, 1, 1 }, 624 { 1, 1, 2, 2 }, 625 { 4, 4, 4, 1 }, 626 { 1, 3, 1, 1 }, 627 }; 628 629 const int rk3399_strength_regs[][4] = { 630 { 0x0080, 0x0088, 0x0090, 0x0098 }, 631 { 0x00a0, 0x00a8, 0x00b0, 0x00b8 }, 632 { 0x0100, 0x0104, 0x0108, 0x010c }, 633 { 0x0110, 0x0118, 0x0120, 0x0128 }, 634 { 0x012c, 0x0130, 0x0138, 0x013c }, 635 }; 636 637 int 638 rk3399_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 639 { 640 int strength, type, level; 641 const int *levels; 642 int node; 643 644 node = OF_getnodebyphandle(phandle); 645 if (node == 0) 646 return -1; 647 648 strength = OF_getpropint(node, "drive-strength", -1); 649 if (strength == -1) 650 return -1; 651 652 /* Convert drive strength to level. */ 653 type = rk3399_strength_types[bank][idx / 8]; 654 levels = rk3399_strength_levels[type]; 655 for (level = 7; level >= 0; level--) { 656 if (strength >= levels[level] && levels[level] > 0) 657 break; 658 } 659 return level; 660 } 661 662 int 663 rk3399_pinctrl(uint32_t phandle, void *cookie) 664 { 665 struct rkpinctrl_softc *sc = cookie; 666 uint32_t *pins; 667 int node, len, i; 668 669 KASSERT(sc->sc_grf); 670 KASSERT(sc->sc_pmu); 671 672 node = OF_getnodebyphandle(phandle); 673 if (node == 0) 674 return -1; 675 676 len = OF_getproplen(node, "rockchip,pins"); 677 if (len <= 0) 678 return -1; 679 680 pins = malloc(len, M_TEMP, M_WAITOK); 681 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 682 goto fail; 683 684 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 685 struct regmap *rm; 686 bus_size_t base, off; 687 uint32_t bank, idx, mux; 688 int pull, strength, type, shift; 689 uint32_t mask, bits; 690 int s; 691 692 bank = pins[i]; 693 idx = pins[i + 1]; 694 mux = pins[i + 2]; 695 pull = rk3399_pull(bank, idx, pins[i + 3]); 696 strength = rk3399_strength(bank, idx, pins[i + 3]); 697 698 if (bank > 5 || idx > 32 || mux > 3) 699 continue; 700 701 /* Bank 0 and 1 live in the PMU. */ 702 if (bank < 2) { 703 rm = sc->sc_pmu; 704 base = RK3399_PMUGRF_GPIO0A_IOMUX; 705 } else { 706 rm = sc->sc_grf; 707 base = RK3399_GRF_GPIO2A_IOMUX - 0x20; 708 } 709 710 s = splhigh(); 711 712 /* IOMUX control */ 713 off = bank * 0x10 + (idx / 8) * 0x04; 714 mask = (0x3 << ((idx % 8) * 2)); 715 bits = (mux << ((idx % 8) * 2)); 716 regmap_write_4(rm, base + off, mask << 16 | bits); 717 718 /* GPIO pad pull down and pull up control */ 719 if (pull >= 0) { 720 off = 0x40 + bank * 0x10 + (idx / 8) * 0x04; 721 mask = (0x3 << ((idx % 8) * 2)); 722 bits = (pull << ((idx % 8) * 2)); 723 regmap_write_4(rm, base + off, mask << 16 | bits); 724 } 725 726 /* GPIO drive strength control */ 727 if (strength >= 0) { 728 off = rk3399_strength_regs[bank][idx / 8]; 729 type = rk3399_strength_types[bank][idx / 8]; 730 shift = (type > 2) ? 3 : 2; 731 mask = (((1 << shift) - 1) << ((idx % 8) * shift)); 732 bits = (strength << ((idx % 8) * shift)); 733 if (mask & 0x0000ffff) { 734 regmap_write_4(rm, base + off, 735 mask << 16 | (bits & 0x0000ffff)); 736 } 737 if (mask & 0xffff0000) { 738 regmap_write_4(rm, base + off + 0x04, 739 (mask & 0xffff0000) | bits >> 16); 740 } 741 } 742 743 splx(s); 744 } 745 746 free(pins, M_TEMP, len); 747 return 0; 748 749 fail: 750 free(pins, M_TEMP, len); 751 return -1; 752 } 753 754 /* 755 * Rockchip RK3568 756 */ 757 758 int 759 rk3568_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 760 { 761 int node; 762 763 node = OF_getnodebyphandle(phandle); 764 if (node == 0) 765 return -1; 766 767 if (OF_getproplen(node, "bias-disable") == 0) 768 return 0; 769 if (OF_getproplen(node, "bias-pull-up") == 0) 770 return 1; 771 if (OF_getproplen(node, "bias-pull-down") == 0) 772 return 2; 773 774 return -1; 775 } 776 777 int 778 rk3568_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 779 { 780 int node; 781 782 node = OF_getnodebyphandle(phandle); 783 if (node == 0) 784 return -1; 785 786 return OF_getpropint(node, "drive-strength", -1); 787 } 788 789 int 790 rk3568_schmitt(uint32_t bank, uint32_t idx, uint32_t phandle) 791 { 792 int node; 793 794 node = OF_getnodebyphandle(phandle); 795 if (node == 0) 796 return -1; 797 798 if (OF_getproplen(node, "input-schmitt-disable") == 0) 799 return 1; 800 if (OF_getproplen(node, "input-schmitt-enable") == 0) 801 return 2; 802 803 return -1; 804 } 805 806 int 807 rk3568_pinctrl(uint32_t phandle, void *cookie) 808 { 809 struct rkpinctrl_softc *sc = cookie; 810 uint32_t *pins; 811 int node, len, i; 812 813 KASSERT(sc->sc_grf); 814 KASSERT(sc->sc_pmu); 815 816 node = OF_getnodebyphandle(phandle); 817 if (node == 0) 818 return -1; 819 820 len = OF_getproplen(node, "rockchip,pins"); 821 if (len <= 0) 822 return -1; 823 824 pins = malloc(len, M_TEMP, M_WAITOK); 825 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 826 goto fail; 827 828 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 829 struct regmap *rm; 830 bus_size_t iomux_base, p_base, ds_base, ie_base, off; 831 uint32_t bank, idx, mux; 832 int pull, strength, schmitt; 833 uint32_t mask, bits; 834 int s; 835 836 bank = pins[i]; 837 idx = pins[i + 1]; 838 mux = pins[i + 2]; 839 pull = rk3568_pull(bank, idx, pins[i + 3]); 840 strength = rk3568_strength(bank, idx, pins[i + 3]); 841 schmitt = rk3568_schmitt(bank, idx, pins[i + 3]); 842 843 if (bank > 5 || idx > 32 || mux > 7) 844 continue; 845 846 /* Bank 0 lives in the PMU. */ 847 if (bank < 1) { 848 rm = sc->sc_pmu; 849 iomux_base = RK3568_PMUGRF_GPIO0A_IOMUX_L; 850 p_base = RK3568_PMUGRF_GPIO0A_P; 851 ds_base = RK3568_PMUGRF_GPIO0A_DS_0; 852 ie_base = RK3568_PMUGRF_GPIO0A_IE; 853 } else { 854 rm = sc->sc_grf; 855 iomux_base = RK3568_GRF_GPIO1A_IOMUX_L; 856 p_base = RK3568_GRF_GPIO1A_P; 857 ds_base = RK3568_GRF_GPIO1A_DS_0; 858 ie_base = RK3568_GRF_GPIO1A_IE; 859 bank = bank - 1; 860 } 861 862 s = splhigh(); 863 864 /* IOMUX control */ 865 off = bank * 0x20 + (idx / 4) * 0x04; 866 mask = (0x7 << ((idx % 4) * 4)); 867 bits = (mux << ((idx % 4) * 4)); 868 regmap_write_4(rm, iomux_base + off, mask << 16 | bits); 869 870 /* GPIO pad pull down and pull up control */ 871 if (pull >= 0) { 872 off = bank * 0x10 + (idx / 8) * 0x04; 873 mask = (0x3 << ((idx % 8) * 2)); 874 bits = (pull << ((idx % 8) * 2)); 875 regmap_write_4(rm, p_base + off, mask << 16 | bits); 876 } 877 878 /* GPIO drive strength control */ 879 if (strength >= 0) { 880 off = bank * 0x40 + (idx / 2) * 0x04; 881 mask = (0x3f << ((idx % 2) * 8)); 882 bits = ((1 << (strength + 1)) - 1) << ((idx % 2) * 8); 883 regmap_write_4(rm, ds_base + off, mask << 16 | bits); 884 } 885 886 /* GPIO Schmitt trigger. */ 887 if (schmitt >= 0) { 888 off = bank * 0x10 + (idx / 8) * 0x04; 889 mask = (0x3 << ((idx % 8) * 2)); 890 bits = schmitt << ((idx % 8) * 2); 891 regmap_write_4(rm, ie_base + off, mask << 16 | bits); 892 } 893 894 splx(s); 895 } 896 897 free(pins, M_TEMP, len); 898 return 0; 899 900 fail: 901 free(pins, M_TEMP, len); 902 return -1; 903 } 904