1 /* $OpenBSD: rkpinctrl.c,v 1.15 2024/02/11 16:01:09 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 #include <machine/simplebusvar.h> 33 34 /* Pin numbers (from devicetree bindings) */ 35 #define RK_PA0 0 36 #define RK_PA1 1 37 #define RK_PA2 2 38 #define RK_PA3 3 39 #define RK_PA4 4 40 #define RK_PA5 5 41 #define RK_PA6 6 42 #define RK_PA7 7 43 #define RK_PB0 8 44 #define RK_PB1 9 45 #define RK_PB2 10 46 #define RK_PB3 11 47 #define RK_PB4 12 48 #define RK_PB5 13 49 #define RK_PB6 14 50 #define RK_PB7 15 51 #define RK_PC0 16 52 #define RK_PC1 17 53 #define RK_PC2 18 54 #define RK_PC3 19 55 #define RK_PC4 20 56 #define RK_PC5 21 57 #define RK_PC6 22 58 #define RK_PC7 23 59 #define RK_PD0 24 60 #define RK_PD1 25 61 #define RK_PD2 26 62 #define RK_PD3 27 63 #define RK_PD4 28 64 #define RK_PD5 29 65 #define RK_PD6 30 66 #define RK_PD7 31 67 68 /* RK3288 registers */ 69 #define RK3288_GRF_GPIO1A_IOMUX 0x0000 70 #define RK3288_PMUGRF_GPIO0A_IOMUX 0x0084 71 72 /* RK3308 registers */ 73 #define RK3308_GRF_GPIO0A_IOMUX 0x0000 74 75 /* RK3328 registers */ 76 #define RK3328_GRF_GPIO0A_IOMUX 0x0000 77 78 /* RK3399 registers */ 79 #define RK3399_GRF_GPIO2A_IOMUX 0xe000 80 #define RK3399_PMUGRF_GPIO0A_IOMUX 0x0000 81 82 /* RK3568 registers */ 83 #define RK3568_GRF_GPIO1A_IOMUX_L 0x0000 84 #define RK3568_GRF_GPIO1A_P 0x0080 85 #define RK3568_GRF_GPIO1A_IE 0x00c0 86 #define RK3568_GRF_GPIO1A_DS_0 0x0200 87 #define RK3568_PMUGRF_GPIO0A_IOMUX_L 0x0000 88 #define RK3568_PMUGRF_GPIO0A_P 0x0020 89 #define RK3568_PMUGRF_GPIO0A_IE 0x0030 90 #define RK3568_PMUGRF_GPIO0A_DS_0 0x0070 91 92 struct rockchip_route_table { 93 u_int bank : 3; 94 u_int idx : 5; 95 u_int mux : 3; 96 u_int grf : 1; 97 #define ROUTE_GRF 0 98 #define ROUTE_PMU 1 99 uint16_t reg; 100 uint32_t val; 101 #define ROUTE_VAL(bit, val) ((0x3 << (bit)) << 16 | ((val) << (bit))) 102 }; 103 104 struct rkpinctrl_softc { 105 struct simplebus_softc sc_sbus; 106 107 struct regmap *sc_grf; 108 struct regmap *sc_pmu; 109 }; 110 111 int rkpinctrl_match(struct device *, void *, void *); 112 void rkpinctrl_attach(struct device *, struct device *, void *); 113 114 const struct cfattach rkpinctrl_ca = { 115 sizeof (struct rkpinctrl_softc), rkpinctrl_match, rkpinctrl_attach 116 }; 117 118 struct cfdriver rkpinctrl_cd = { 119 NULL, "rkpinctrl", DV_DULL 120 }; 121 122 int rk3288_pinctrl(uint32_t, void *); 123 int rk3308_pinctrl(uint32_t, void *); 124 int rk3328_pinctrl(uint32_t, void *); 125 int rk3399_pinctrl(uint32_t, void *); 126 int rk3568_pinctrl(uint32_t, void *); 127 int rk3588_pinctrl(uint32_t, void *); 128 129 int 130 rkpinctrl_match(struct device *parent, void *match, void *aux) 131 { 132 struct fdt_attach_args *faa = aux; 133 134 return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl") || 135 OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl") || 136 OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl") || 137 OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl") || 138 OF_is_compatible(faa->fa_node, "rockchip,rk3568-pinctrl") || 139 OF_is_compatible(faa->fa_node, "rockchip,rk3588-pinctrl")); 140 } 141 142 void 143 rkpinctrl_attach(struct device *parent, struct device *self, void *aux) 144 { 145 struct rkpinctrl_softc *sc = (struct rkpinctrl_softc *)self; 146 struct fdt_attach_args *faa = aux; 147 uint32_t grf, pmu; 148 149 grf = OF_getpropint(faa->fa_node, "rockchip,grf", 0); 150 pmu = OF_getpropint(faa->fa_node, "rockchip,pmu", 0); 151 sc->sc_grf = regmap_byphandle(grf); 152 sc->sc_pmu = regmap_byphandle(pmu); 153 154 if (sc->sc_grf == NULL && sc->sc_pmu == NULL) { 155 printf(": no registers\n"); 156 return; 157 } 158 159 if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl")) 160 pinctrl_register(faa->fa_node, rk3288_pinctrl, sc); 161 else if (OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl")) 162 pinctrl_register(faa->fa_node, rk3308_pinctrl, sc); 163 else if (OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl")) 164 pinctrl_register(faa->fa_node, rk3328_pinctrl, sc); 165 else if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl")) 166 pinctrl_register(faa->fa_node, rk3399_pinctrl, sc); 167 else if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-pinctrl")) 168 pinctrl_register(faa->fa_node, rk3568_pinctrl, sc); 169 else 170 pinctrl_register(faa->fa_node, rk3588_pinctrl, sc); 171 172 /* Attach GPIO banks. */ 173 simplebus_attach(parent, &sc->sc_sbus.sc_dev, faa); 174 } 175 176 /* 177 * Rockchip RK3288 178 */ 179 180 int 181 rk3288_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 182 { 183 int node; 184 185 node = OF_getnodebyphandle(phandle); 186 if (node == 0) 187 return -1; 188 189 /* XXX */ 190 if (bank == 0) 191 return -1; 192 193 if (OF_getproplen(node, "bias-disable") == 0) 194 return 0; 195 if (OF_getproplen(node, "bias-pull-up") == 0) 196 return 1; 197 if (OF_getproplen(node, "bias-pull-down") == 0) 198 return 2; 199 200 return -1; 201 } 202 203 int 204 rk3288_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 205 { 206 int strength, level; 207 int levels[4] = { 2, 4, 8, 12 }; 208 int node; 209 210 node = OF_getnodebyphandle(phandle); 211 if (node == 0) 212 return -1; 213 214 /* XXX */ 215 if (bank == 0) 216 return -1; 217 218 strength = OF_getpropint(node, "drive-strength", -1); 219 if (strength == -1) 220 return -1; 221 222 /* Convert drive strength to level. */ 223 for (level = 3; level >= 0; level--) { 224 if (strength >= levels[level]) 225 break; 226 } 227 return level; 228 } 229 230 int 231 rk3288_pinctrl(uint32_t phandle, void *cookie) 232 { 233 struct rkpinctrl_softc *sc = cookie; 234 uint32_t *pins; 235 int node, len, i; 236 237 KASSERT(sc->sc_grf); 238 KASSERT(sc->sc_pmu); 239 240 node = OF_getnodebyphandle(phandle); 241 if (node == 0) 242 return -1; 243 244 len = OF_getproplen(node, "rockchip,pins"); 245 if (len <= 0) 246 return -1; 247 248 pins = malloc(len, M_TEMP, M_WAITOK); 249 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 250 goto fail; 251 252 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 253 struct regmap *rm; 254 bus_size_t base, off; 255 uint32_t bank, idx, mux; 256 int pull, strength; 257 uint32_t mask, bits; 258 int s; 259 260 bank = pins[i]; 261 idx = pins[i + 1]; 262 mux = pins[i + 2]; 263 264 if (bank > 8 || idx >= 32 || mux > 7) 265 continue; 266 267 pull = rk3288_pull(bank, idx, pins[i + 3]); 268 strength = rk3288_strength(bank, idx, pins[i + 3]); 269 270 /* Bank 0 lives in the PMU. */ 271 if (bank < 1) { 272 rm = sc->sc_pmu; 273 base = RK3288_PMUGRF_GPIO0A_IOMUX; 274 } else { 275 rm = sc->sc_grf; 276 base = RK3288_GRF_GPIO1A_IOMUX - 0x10; 277 } 278 279 s = splhigh(); 280 281 /* IOMUX control */ 282 off = bank * 0x10 + (idx / 8) * 0x04; 283 284 /* GPIO3D, GPIO4A and GPIO4B are special. */ 285 if ((bank == 3 && idx >= 24) || (bank == 4 && idx < 16)) { 286 mask = (0x7 << ((idx % 4) * 4)); 287 bits = (mux << ((idx % 4) * 4)); 288 } else { 289 mask = (0x3 << ((idx % 8) * 2)); 290 bits = (mux << ((idx % 8) * 2)); 291 } 292 if (bank > 3 || (bank == 3 && idx >= 28)) 293 off += 0x04; 294 if (bank > 4 || (bank == 4 && idx >= 4)) 295 off += 0x04; 296 if (bank > 4 || (bank == 4 && idx >= 12)) 297 off += 0x04; 298 regmap_write_4(rm, base + off, mask << 16 | bits); 299 300 /* GPIO pad pull down and pull up control */ 301 if (pull >= 0) { 302 off = 0x140 + bank * 0x10 + (idx / 8) * 0x04; 303 mask = (0x3 << ((idx % 8) * 2)); 304 bits = (pull << ((idx % 8) * 2)); 305 regmap_write_4(rm, base + off, mask << 16 | bits); 306 } 307 308 /* GPIO drive strength control */ 309 if (strength >= 0) { 310 off = 0x1c0 + bank * 0x10 + (idx / 8) * 0x04; 311 mask = (0x3 << ((idx % 8) * 2)); 312 bits = (strength << ((idx % 8) * 2)); 313 regmap_write_4(rm, base + off, mask << 16 | bits); 314 } 315 316 splx(s); 317 } 318 319 free(pins, M_TEMP, len); 320 return 0; 321 322 fail: 323 free(pins, M_TEMP, len); 324 return -1; 325 } 326 327 /* 328 * Rockchip RK3308 329 */ 330 331 int 332 rk3308_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 333 { 334 int node; 335 336 node = OF_getnodebyphandle(phandle); 337 if (node == 0) 338 return -1; 339 340 if (OF_getproplen(node, "bias-disable") == 0) 341 return 0; 342 if (OF_getproplen(node, "bias-pull-up") == 0) 343 return 1; 344 if (OF_getproplen(node, "bias-pull-down") == 0) 345 return 2; 346 347 return -1; 348 } 349 350 int 351 rk3308_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 352 { 353 int strength, level; 354 int levels[4] = { 2, 4, 8, 12 }; 355 int node; 356 357 node = OF_getnodebyphandle(phandle); 358 if (node == 0) 359 return -1; 360 361 strength = OF_getpropint(node, "drive-strength", -1); 362 if (strength == -1) 363 return -1; 364 365 /* Convert drive strength to level. */ 366 for (level = 3; level >= 0; level--) { 367 if (strength >= levels[level]) 368 break; 369 } 370 return level; 371 } 372 373 int 374 rk3308_pinctrl(uint32_t phandle, void *cookie) 375 { 376 struct rkpinctrl_softc *sc = cookie; 377 uint32_t *pins; 378 int node, len, i; 379 380 KASSERT(sc->sc_grf); 381 382 node = OF_getnodebyphandle(phandle); 383 if (node == 0) 384 return -1; 385 386 len = OF_getproplen(node, "rockchip,pins"); 387 if (len <= 0) 388 return -1; 389 390 pins = malloc(len, M_TEMP, M_WAITOK); 391 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 392 goto fail; 393 394 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 395 struct regmap *rm = sc->sc_grf; 396 bus_size_t base, off; 397 uint32_t bank, idx, mux; 398 int pull, strength; 399 uint32_t mask, bits; 400 int s; 401 402 bank = pins[i]; 403 idx = pins[i + 1]; 404 mux = pins[i + 2]; 405 406 if (bank > 4 || idx >= 32 || mux > 7) 407 continue; 408 409 pull = rk3308_pull(bank, idx, pins[i + 3]); 410 strength = rk3308_strength(bank, idx, pins[i + 3]); 411 412 base = RK3308_GRF_GPIO0A_IOMUX; 413 414 s = splhigh(); 415 416 /* IOMUX control */ 417 off = bank * 0x20 + (idx / 8) * 0x08; 418 419 /* GPIO1B, GPIO1C and GPIO3B are special. */ 420 if ((bank == 1) && (idx == 14)) { 421 mask = (0xf << 12); 422 bits = (mux << 12); 423 } else if ((bank == 1) && (idx == 15)) { 424 off += 4; 425 mask = 0x3; 426 bits = mux; 427 } else if ((bank == 1) && (idx >= 16 && idx <= 17)) { 428 mask = (0x3 << ((idx - 16) * 2)); 429 bits = (mux << ((idx - 16) * 2)); 430 } else if ((bank == 1) && (idx >= 18 && idx <= 20)) { 431 mask = (0xf << (((idx - 18) * 4) + 4)); 432 bits = (mux << (((idx - 18) * 4) + 4)); 433 } else if ((bank == 1) && (idx >= 21 && idx <= 23)) { 434 off += 4; 435 mask = (0xf << ((idx - 21) * 4)); 436 bits = (mux << ((idx - 21) * 4)); 437 } else if ((bank == 3) && (idx >= 12 && idx <= 13)) { 438 mask = (0xf << (((idx - 12) * 4) + 8)); 439 bits = (mux << (((idx - 12) * 4) + 8)); 440 } else { 441 mask = (0x3 << ((idx % 8) * 2)); 442 bits = (mux << ((idx % 8) * 2)); 443 } 444 regmap_write_4(rm, base + off, mask << 16 | bits); 445 446 /* GPIO pad pull down and pull up control */ 447 if (pull >= 0) { 448 off = 0xa0 + bank * 0x10 + (idx / 8) * 0x04; 449 mask = (0x3 << ((idx % 8) * 2)); 450 bits = (pull << ((idx % 8) * 2)); 451 regmap_write_4(rm, base + off, mask << 16 | bits); 452 } 453 454 /* GPIO drive strength control */ 455 if (strength >= 0) { 456 off = 0x100 + bank * 0x10 + (idx / 8) * 0x04; 457 mask = (0x3 << ((idx % 8) * 2)); 458 bits = (strength << ((idx % 8) * 2)); 459 regmap_write_4(rm, base + off, mask << 16 | bits); 460 } 461 462 splx(s); 463 } 464 465 free(pins, M_TEMP, len); 466 return 0; 467 468 fail: 469 free(pins, M_TEMP, len); 470 return -1; 471 } 472 473 /* 474 * Rockchip RK3328 475 */ 476 477 int 478 rk3328_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 479 { 480 int node; 481 482 node = OF_getnodebyphandle(phandle); 483 if (node == 0) 484 return -1; 485 486 if (OF_getproplen(node, "bias-disable") == 0) 487 return 0; 488 if (OF_getproplen(node, "bias-pull-up") == 0) 489 return 1; 490 if (OF_getproplen(node, "bias-pull-down") == 0) 491 return 2; 492 493 return -1; 494 } 495 496 int 497 rk3328_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 498 { 499 int strength, level; 500 int levels[4] = { 2, 4, 8, 12 }; 501 int node; 502 503 node = OF_getnodebyphandle(phandle); 504 if (node == 0) 505 return -1; 506 507 strength = OF_getpropint(node, "drive-strength", -1); 508 if (strength == -1) 509 return -1; 510 511 /* Convert drive strength to level. */ 512 for (level = 3; level >= 0; level--) { 513 if (strength >= levels[level]) 514 break; 515 } 516 return level; 517 } 518 519 int 520 rk3328_pinctrl(uint32_t phandle, void *cookie) 521 { 522 struct rkpinctrl_softc *sc = cookie; 523 uint32_t *pins; 524 int node, len, i; 525 526 KASSERT(sc->sc_grf); 527 528 node = OF_getnodebyphandle(phandle); 529 if (node == 0) 530 return -1; 531 532 len = OF_getproplen(node, "rockchip,pins"); 533 if (len <= 0) 534 return -1; 535 536 pins = malloc(len, M_TEMP, M_WAITOK); 537 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 538 goto fail; 539 540 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 541 struct regmap *rm = sc->sc_grf; 542 bus_size_t base, off; 543 uint32_t bank, idx, mux; 544 int pull, strength; 545 uint32_t mask, bits; 546 int s; 547 548 bank = pins[i]; 549 idx = pins[i + 1]; 550 mux = pins[i + 2]; 551 552 if (bank > 3 || idx >= 32 || mux > 3) 553 continue; 554 555 pull = rk3328_pull(bank, idx, pins[i + 3]); 556 strength = rk3328_strength(bank, idx, pins[i + 3]); 557 558 base = RK3328_GRF_GPIO0A_IOMUX; 559 560 s = splhigh(); 561 562 /* IOMUX control */ 563 off = bank * 0x10 + (idx / 8) * 0x04; 564 565 /* GPIO2B, GPIO2C, GPIO3A and GPIO3B are special. */ 566 if (bank == 2 && idx == 15) { 567 mask = 0x7; 568 bits = mux; 569 } else if (bank == 2 && idx >= 16 && idx <= 20) { 570 mask = (0x7 << ((idx - 16) * 3)); 571 bits = (mux << ((idx - 16) * 3)); 572 } else if (bank == 2 && idx >= 21 && idx <= 23) { 573 mask = (0x7 << ((idx - 21) * 3)); 574 bits = (mux << ((idx - 21) * 3)); 575 } else if (bank == 3 && idx <= 4) { 576 mask = (0x7 << (idx * 3)); 577 bits = (mux << (idx * 3)); 578 } else if (bank == 3 && idx >= 5 && idx <= 7) { 579 mask = (0x7 << ((idx - 5) * 3)); 580 bits = (mux << ((idx - 5) * 3)); 581 } else if (bank == 3 && idx >= 8 && idx <= 12) { 582 mask = (0x7 << ((idx - 8) * 3)); 583 bits = (mux << ((idx - 8) * 3)); 584 } else if (bank == 3 && idx >= 13 && idx <= 15) { 585 mask = (0x7 << ((idx - 13) * 3)); 586 bits = (mux << ((idx - 13) * 3)); 587 } else { 588 mask = (0x3 << ((idx % 8) * 2)); 589 bits = (mux << ((idx % 8) * 2)); 590 } 591 if (bank > 2 || (bank == 2 && idx >= 15)) 592 off += 0x04; 593 if (bank > 2 || (bank == 2 && idx >= 21)) 594 off += 0x04; 595 if (bank > 3 || (bank == 3 && idx >= 5)) 596 off += 0x04; 597 if (bank > 3 || (bank == 3 && idx >= 13)) 598 off += 0x04; 599 regmap_write_4(rm, base + off, mask << 16 | bits); 600 601 /* GPIO pad pull down and pull up control */ 602 if (pull >= 0) { 603 off = 0x100 + bank * 0x10 + (idx / 8) * 0x04; 604 mask = (0x3 << ((idx % 8) * 2)); 605 bits = (pull << ((idx % 8) * 2)); 606 regmap_write_4(rm, base + off, mask << 16 | bits); 607 } 608 609 /* GPIO drive strength control */ 610 if (strength >= 0) { 611 off = 0x200 + bank * 0x10 + (idx / 8) * 0x04; 612 mask = (0x3 << ((idx % 8) * 2)); 613 bits = (strength << ((idx % 8) * 2)); 614 regmap_write_4(rm, base + off, mask << 16 | bits); 615 } 616 617 splx(s); 618 } 619 620 free(pins, M_TEMP, len); 621 return 0; 622 623 fail: 624 free(pins, M_TEMP, len); 625 return -1; 626 } 627 628 /* 629 * Rockchip RK3399 630 */ 631 632 int 633 rk3399_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 634 { 635 int pull_up, pull_down; 636 int node; 637 638 node = OF_getnodebyphandle(phandle); 639 if (node == 0) 640 return -1; 641 642 if (bank == 2 && idx >= 16) { 643 pull_up = 3; 644 pull_down = 1; 645 } else { 646 pull_up = 1; 647 pull_down = 2; 648 } 649 650 if (OF_getproplen(node, "bias-disable") == 0) 651 return 0; 652 if (OF_getproplen(node, "bias-pull-up") == 0) 653 return pull_up; 654 if (OF_getproplen(node, "bias-pull-down") == 0) 655 return pull_down; 656 657 return -1; 658 } 659 660 /* Magic because the drive strength configurations vary wildly. */ 661 662 const int rk3399_strength_levels[][8] = { 663 { 2, 4, 8, 12 }, /* default */ 664 { 3, 6, 9, 12 }, /* 1.8V or 3.0V */ 665 { 5, 10, 15, 20 }, /* 1.8V only */ 666 { 4, 6, 8, 10, 12, 14, 16, 18 }, /* 1.8V or 3.0V auto */ 667 { 4, 7, 10, 13, 16, 19, 22, 26 }, /* 3.3V */ 668 }; 669 670 const int rk3399_strength_types[][4] = { 671 { 2, 2, 0, 0 }, 672 { 1, 1, 1, 1 }, 673 { 1, 1, 2, 2 }, 674 { 4, 4, 4, 1 }, 675 { 1, 3, 1, 1 }, 676 }; 677 678 const int rk3399_strength_regs[][4] = { 679 { 0x0080, 0x0088, 0x0090, 0x0098 }, 680 { 0x00a0, 0x00a8, 0x00b0, 0x00b8 }, 681 { 0x0100, 0x0104, 0x0108, 0x010c }, 682 { 0x0110, 0x0118, 0x0120, 0x0128 }, 683 { 0x012c, 0x0130, 0x0138, 0x013c }, 684 }; 685 686 int 687 rk3399_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 688 { 689 int strength, type, level; 690 const int *levels; 691 int node; 692 693 node = OF_getnodebyphandle(phandle); 694 if (node == 0) 695 return -1; 696 697 strength = OF_getpropint(node, "drive-strength", -1); 698 if (strength == -1) 699 return -1; 700 701 /* Convert drive strength to level. */ 702 type = rk3399_strength_types[bank][idx / 8]; 703 levels = rk3399_strength_levels[type]; 704 for (level = 7; level >= 0; level--) { 705 if (strength >= levels[level] && levels[level] > 0) 706 break; 707 } 708 return level; 709 } 710 711 int 712 rk3399_pinctrl(uint32_t phandle, void *cookie) 713 { 714 struct rkpinctrl_softc *sc = cookie; 715 uint32_t *pins; 716 int node, len, i; 717 718 KASSERT(sc->sc_grf); 719 KASSERT(sc->sc_pmu); 720 721 node = OF_getnodebyphandle(phandle); 722 if (node == 0) 723 return -1; 724 725 len = OF_getproplen(node, "rockchip,pins"); 726 if (len <= 0) 727 return -1; 728 729 pins = malloc(len, M_TEMP, M_WAITOK); 730 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 731 goto fail; 732 733 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 734 struct regmap *rm; 735 bus_size_t base, off; 736 uint32_t bank, idx, mux; 737 int pull, strength, type, shift; 738 uint32_t mask, bits; 739 int s; 740 741 bank = pins[i]; 742 idx = pins[i + 1]; 743 mux = pins[i + 2]; 744 745 if (bank > 4 || idx >= 32 || mux > 3) 746 continue; 747 748 pull = rk3399_pull(bank, idx, pins[i + 3]); 749 strength = rk3399_strength(bank, idx, pins[i + 3]); 750 751 /* Bank 0 and 1 live in the PMU. */ 752 if (bank < 2) { 753 rm = sc->sc_pmu; 754 base = RK3399_PMUGRF_GPIO0A_IOMUX; 755 } else { 756 rm = sc->sc_grf; 757 base = RK3399_GRF_GPIO2A_IOMUX - 0x20; 758 } 759 760 s = splhigh(); 761 762 /* IOMUX control */ 763 off = bank * 0x10 + (idx / 8) * 0x04; 764 mask = (0x3 << ((idx % 8) * 2)); 765 bits = (mux << ((idx % 8) * 2)); 766 regmap_write_4(rm, base + off, mask << 16 | bits); 767 768 /* GPIO pad pull down and pull up control */ 769 if (pull >= 0) { 770 off = 0x40 + bank * 0x10 + (idx / 8) * 0x04; 771 mask = (0x3 << ((idx % 8) * 2)); 772 bits = (pull << ((idx % 8) * 2)); 773 regmap_write_4(rm, base + off, mask << 16 | bits); 774 } 775 776 /* GPIO drive strength control */ 777 if (strength >= 0) { 778 off = rk3399_strength_regs[bank][idx / 8]; 779 type = rk3399_strength_types[bank][idx / 8]; 780 shift = (type > 2) ? 3 : 2; 781 mask = (((1 << shift) - 1) << ((idx % 8) * shift)); 782 bits = (strength << ((idx % 8) * shift)); 783 if (mask & 0x0000ffff) { 784 regmap_write_4(rm, base + off, 785 mask << 16 | (bits & 0x0000ffff)); 786 } 787 if (mask & 0xffff0000) { 788 regmap_write_4(rm, base + off + 0x04, 789 (mask & 0xffff0000) | bits >> 16); 790 } 791 } 792 793 splx(s); 794 } 795 796 free(pins, M_TEMP, len); 797 return 0; 798 799 fail: 800 free(pins, M_TEMP, len); 801 return -1; 802 } 803 804 /* 805 * Rockchip RK3568 806 */ 807 808 int 809 rk3568_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 810 { 811 int node; 812 813 node = OF_getnodebyphandle(phandle); 814 if (node == 0) 815 return -1; 816 817 if (OF_getproplen(node, "bias-disable") == 0) 818 return 0; 819 if (OF_getproplen(node, "bias-pull-up") == 0) 820 return 1; 821 if (OF_getproplen(node, "bias-pull-down") == 0) 822 return 2; 823 824 return -1; 825 } 826 827 int 828 rk3568_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 829 { 830 int node; 831 832 node = OF_getnodebyphandle(phandle); 833 if (node == 0) 834 return -1; 835 836 return OF_getpropint(node, "drive-strength", -1); 837 } 838 839 int 840 rk3568_schmitt(uint32_t bank, uint32_t idx, uint32_t phandle) 841 { 842 int node; 843 844 node = OF_getnodebyphandle(phandle); 845 if (node == 0) 846 return -1; 847 848 if (OF_getproplen(node, "input-schmitt-disable") == 0) 849 return 1; 850 if (OF_getproplen(node, "input-schmitt-enable") == 0) 851 return 2; 852 853 return -1; 854 } 855 856 struct rockchip_route_table rk3568_route_table[] = { 857 { 0, RK_PB7, 1, ROUTE_PMU, 0x0110, ROUTE_VAL(0, 0) }, /* PWM0 M0 */ 858 { 0, RK_PC7, 2, ROUTE_PMU, 0x0110, ROUTE_VAL(0, 1) }, /* PWM0 M1 */ 859 { 0, RK_PC0, 1, ROUTE_PMU, 0x0110, ROUTE_VAL(2, 0) }, /* PWM1 M0 */ 860 { 0, RK_PB5, 4, ROUTE_PMU, 0x0110, ROUTE_VAL(2, 1) }, /* PWM1 M1 */ 861 { 0, RK_PC1, 1, ROUTE_PMU, 0x0110, ROUTE_VAL(4, 0) }, /* PWM2 M0 */ 862 { 0, RK_PB6, 4, ROUTE_PMU, 0x0110, ROUTE_VAL(4, 1) }, /* PWM2 M1 */ 863 864 { 3, RK_PB1, 3, ROUTE_GRF, 0x0300, ROUTE_VAL(8, 0) }, /* GMAC1 M0 */ 865 { 4, RK_PA7, 3, ROUTE_GRF, 0x0300, ROUTE_VAL(8, 1) }, /* GMAC1 M1 */ 866 { 0, RK_PB6, 1, ROUTE_GRF, 0x0300, ROUTE_VAL(14, 0) }, /* I2C2 M0 */ 867 { 4, RK_PB4, 1, ROUTE_GRF, 0x0300, ROUTE_VAL(14, 1) }, /* I2C2 M1 */ 868 869 { 1, RK_PA0, 1, ROUTE_GRF, 0x0304, ROUTE_VAL(0, 0) }, /* I2C3 M0 */ 870 { 3, RK_PB6, 4, ROUTE_GRF, 0x0304, ROUTE_VAL(0, 1) }, /* I2C3 M1 */ 871 { 4, RK_PB2, 1, ROUTE_GRF, 0x0304, ROUTE_VAL(2, 0) }, /* I2C4 M0 */ 872 { 2, RK_PB1, 2, ROUTE_GRF, 0x0304, ROUTE_VAL(2, 1) }, /* I2C4 M1 */ 873 { 3, RK_PB4, 4, ROUTE_GRF, 0x0304, ROUTE_VAL(4, 0) }, /* I2C5 M0 */ 874 { 4, RK_PD0, 2, ROUTE_GRF, 0x0304, ROUTE_VAL(4, 1) }, /* I2C5 M1 */ 875 { 3, RK_PB1, 5, ROUTE_GRF, 0x0304, ROUTE_VAL(14, 0) }, /* PWM8 M0 */ 876 { 1, RK_PD5, 4, ROUTE_GRF, 0x0304, ROUTE_VAL(14, 1) }, /* PWM8 M1 */ 877 878 { 3, RK_PB2, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(0, 0) }, /* PWM9 M0 */ 879 { 1, RK_PD6, 4, ROUTE_GRF, 0x0308, ROUTE_VAL(0, 1) }, /* PWM9 M1 */ 880 { 3, RK_PB5, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(2, 0) }, /* PWM10 M0 */ 881 { 2, RK_PA1, 2, ROUTE_GRF, 0x0308, ROUTE_VAL(2, 1) }, /* PWM10 M1 */ 882 { 3, RK_PB6, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(4, 0) }, /* PWM11 M0 */ 883 { 4, RK_PC0, 3, ROUTE_GRF, 0x0308, ROUTE_VAL(4, 1) }, /* PWM11 M1 */ 884 { 3, RK_PB7, 2, ROUTE_GRF, 0x0308, ROUTE_VAL(6, 0) }, /* PWM12 M0 */ 885 { 4, RK_PC5, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(6, 1) }, /* PWM12 M1 */ 886 { 3, RK_PC0, 2, ROUTE_GRF, 0x0308, ROUTE_VAL(8, 0) }, /* PWM13 M0 */ 887 { 4, RK_PC6, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(8, 1) }, /* PWM13 M1 */ 888 { 3, RK_PC4, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(10, 0) }, /* PWM14 M0 */ 889 { 4, RK_PC2, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(10, 1) }, /* PWM14 M1 */ 890 { 3, RK_PC5, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(12, 0) }, /* PWM15 M0 */ 891 { 4, RK_PC3, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(12, 1) }, /* PWM15 M1 */ 892 { 3, RK_PD2, 3, ROUTE_GRF, 0x0308, ROUTE_VAL(14, 0) }, /* SDMMC2 M0 */ 893 { 3, RK_PA5, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(14, 1) }, /* SDMMC2 M1 */ 894 895 { 2, RK_PB4, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(8, 0) }, /* UART1 M0 */ 896 { 3, RK_PD6, 4, ROUTE_GRF, 0x030c, ROUTE_VAL(8, 1) }, /* UART1 M1 */ 897 { 0, RK_PD1, 1, ROUTE_GRF, 0x030c, ROUTE_VAL(10, 0) }, /* UART2 M0 */ 898 { 1, RK_PD5, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(10, 1) }, /* UART2 M1 */ 899 { 1, RK_PA1, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(12, 0) }, /* UART3 M0 */ 900 { 3, RK_PB7, 4, ROUTE_GRF, 0x030c, ROUTE_VAL(12, 1) }, /* UART3 M1 */ 901 { 1, RK_PA6, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(14, 0) }, /* UART4 M0 */ 902 { 3, RK_PB2, 4, ROUTE_GRF, 0x030c, ROUTE_VAL(14, 1) }, /* UART4 M1 */ 903 904 { 2, RK_PA2, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(0, 0) }, /* UART5 M0 */ 905 { 3, RK_PC2, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(0, 1) }, /* UART5 M1 */ 906 { 2, RK_PA4, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(2, 0) }, /* UART6 M0 */ 907 { 1, RK_PD5, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(2, 1) }, /* UART6 M1 */ 908 { 2, RK_PA6, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(4, 0) }, /* UART7 M0 */ 909 { 3, RK_PC4, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(4, 1) }, /* UART7 M1 */ 910 { 4, RK_PA2, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(4, 2) }, /* UART7 M2 */ 911 { 2, RK_PC5, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(6, 0) }, /* UART8 M0 */ 912 { 2, RK_PD7, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(6, 1) }, /* UART8 M1 */ 913 { 2, RK_PB0, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(8, 0) }, /* UART9 M0 */ 914 { 4, RK_PC5, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(8, 1) }, /* UART9 M1 */ 915 { 4, RK_PA4, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(8, 2) }, /* UART9 M2 */ 916 { 1, RK_PA2, 1, ROUTE_GRF, 0x0310, ROUTE_VAL(10, 0) }, /* I2S1 M0 */ 917 { 3, RK_PC6, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(10, 1) }, /* I2S1 M1 */ 918 { 2, RK_PD0, 5, ROUTE_GRF, 0x0310, ROUTE_VAL(10, 2) }, /* I2S1 M2 */ 919 { 2, RK_PC1, 1, ROUTE_GRF, 0x0310, ROUTE_VAL(12, 0) }, /* I2S2 M0 */ 920 { 4, RK_PB6, 5, ROUTE_GRF, 0x0310, ROUTE_VAL(12, 1) }, /* I2S2 M1 */ 921 { 3, RK_PA2, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(14, 0) }, /* I2S3 M0 */ 922 { 4, RK_PC2, 5, ROUTE_GRF, 0x0310, ROUTE_VAL(14, 1) }, /* I2S3 M1 */ 923 924 { 0, RK_PA5, 3, ROUTE_GRF, 0x0314, ROUTE_VAL(2, 0) }, /* PCIE20 M0 */ 925 { 2, RK_PD0, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(2, 1) }, /* PCIE20 M1 */ 926 { 1, RK_PB0, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(2, 2) }, /* PCIE20 M2 */ 927 { 0, RK_PA4, 3, ROUTE_GRF, 0x0314, ROUTE_VAL(4, 0) }, /* PCIE30X1 M0 */ 928 { 2, RK_PD2, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(4, 1) }, /* PCIE30X1 M1 */ 929 { 1, RK_PA5, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(4, 2) }, /* PCIE30X1 M2 */ 930 { 0, RK_PA6, 2, ROUTE_GRF, 0x0314, ROUTE_VAL(6, 0) }, /* PCIE30X2 M0 */ 931 { 2, RK_PD4, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(6, 1) }, /* PCIE30X2 M1 */ 932 { 4, RK_PC2, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(6, 2) }, /* PCIE30X2 M2 */ 933 }; 934 935 void 936 rk3568_route(struct rkpinctrl_softc *sc, uint32_t *pins) 937 { 938 struct rockchip_route_table *route = NULL; 939 struct regmap *rm; 940 int bank = pins[0]; 941 int idx = pins[1]; 942 int mux = pins[2]; 943 int i; 944 945 for (i = 0; i < nitems(rk3568_route_table); i++) { 946 if (bank == rk3568_route_table[i].bank && 947 idx == rk3568_route_table[i].idx && 948 mux == rk3568_route_table[i].mux) { 949 route = &rk3568_route_table[i]; 950 break; 951 } 952 } 953 if (route == NULL) 954 return; 955 956 rm = route->grf ? sc->sc_pmu : sc->sc_grf; 957 regmap_write_4(rm, route->reg, route->val); 958 } 959 960 int 961 rk3568_pinctrl(uint32_t phandle, void *cookie) 962 { 963 struct rkpinctrl_softc *sc = cookie; 964 uint32_t *pins; 965 int node, len, i; 966 967 KASSERT(sc->sc_grf); 968 KASSERT(sc->sc_pmu); 969 970 node = OF_getnodebyphandle(phandle); 971 if (node == 0) 972 return -1; 973 974 len = OF_getproplen(node, "rockchip,pins"); 975 if (len <= 0) 976 return -1; 977 978 pins = malloc(len, M_TEMP, M_WAITOK); 979 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 980 goto fail; 981 982 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 983 struct regmap *rm; 984 bus_size_t iomux_base, p_base, ds_base, ie_base, off; 985 uint32_t bank, idx, mux; 986 int pull, strength, schmitt; 987 uint32_t mask, bits; 988 int s; 989 990 bank = pins[i]; 991 idx = pins[i + 1]; 992 mux = pins[i + 2]; 993 994 if (bank > 5 || idx >= 32 || mux > 7) 995 continue; 996 997 pull = rk3568_pull(bank, idx, pins[i + 3]); 998 strength = rk3568_strength(bank, idx, pins[i + 3]); 999 schmitt = rk3568_schmitt(bank, idx, pins[i + 3]); 1000 1001 /* Bank 0 lives in the PMU. */ 1002 if (bank < 1) { 1003 rm = sc->sc_pmu; 1004 iomux_base = RK3568_PMUGRF_GPIO0A_IOMUX_L; 1005 p_base = RK3568_PMUGRF_GPIO0A_P; 1006 ds_base = RK3568_PMUGRF_GPIO0A_DS_0; 1007 ie_base = RK3568_PMUGRF_GPIO0A_IE; 1008 } else { 1009 rm = sc->sc_grf; 1010 iomux_base = RK3568_GRF_GPIO1A_IOMUX_L; 1011 p_base = RK3568_GRF_GPIO1A_P; 1012 ds_base = RK3568_GRF_GPIO1A_DS_0; 1013 ie_base = RK3568_GRF_GPIO1A_IE; 1014 bank = bank - 1; 1015 } 1016 1017 s = splhigh(); 1018 1019 /* IOMUX control */ 1020 rk3568_route(sc, &pins[i]); 1021 off = bank * 0x20 + (idx / 4) * 0x04; 1022 mask = (0x7 << ((idx % 4) * 4)); 1023 bits = (mux << ((idx % 4) * 4)); 1024 regmap_write_4(rm, iomux_base + off, mask << 16 | bits); 1025 1026 /* GPIO pad pull down and pull up control */ 1027 if (pull >= 0) { 1028 off = bank * 0x10 + (idx / 8) * 0x04; 1029 mask = (0x3 << ((idx % 8) * 2)); 1030 bits = (pull << ((idx % 8) * 2)); 1031 regmap_write_4(rm, p_base + off, mask << 16 | bits); 1032 } 1033 1034 /* GPIO drive strength control */ 1035 if (strength >= 0) { 1036 off = bank * 0x40 + (idx / 2) * 0x04; 1037 mask = (0x3f << ((idx % 2) * 8)); 1038 bits = ((1 << (strength + 1)) - 1) << ((idx % 2) * 8); 1039 regmap_write_4(rm, ds_base + off, mask << 16 | bits); 1040 } 1041 1042 /* GPIO Schmitt trigger. */ 1043 if (schmitt >= 0) { 1044 off = bank * 0x10 + (idx / 8) * 0x04; 1045 mask = (0x3 << ((idx % 8) * 2)); 1046 bits = schmitt << ((idx % 8) * 2); 1047 regmap_write_4(rm, ie_base + off, mask << 16 | bits); 1048 } 1049 1050 splx(s); 1051 } 1052 1053 free(pins, M_TEMP, len); 1054 return 0; 1055 1056 fail: 1057 free(pins, M_TEMP, len); 1058 return -1; 1059 } 1060 1061 1062 /* 1063 * Rockchip RK3588 1064 */ 1065 1066 int 1067 rk3588_pull(uint32_t bank, uint32_t idx, uint32_t phandle) 1068 { 1069 int node; 1070 1071 node = OF_getnodebyphandle(phandle); 1072 if (node == 0) 1073 return -1; 1074 1075 if (OF_getproplen(node, "bias-disable") == 0) 1076 return 0; 1077 if (OF_getproplen(node, "bias-pull-up") == 0) 1078 return 3; 1079 if (OF_getproplen(node, "bias-pull-down") == 0) 1080 return 1; 1081 1082 return -1; 1083 } 1084 1085 int 1086 rk3588_strength(uint32_t bank, uint32_t idx, uint32_t phandle) 1087 { 1088 int node; 1089 1090 node = OF_getnodebyphandle(phandle); 1091 if (node == 0) 1092 return -1; 1093 1094 return OF_getpropint(node, "drive-strength", -1); 1095 } 1096 1097 int 1098 rk3588_schmitt(uint32_t bank, uint32_t idx, uint32_t phandle) 1099 { 1100 int node; 1101 1102 node = OF_getnodebyphandle(phandle); 1103 if (node == 0) 1104 return -1; 1105 1106 if (OF_getproplen(node, "input-schmitt-disable") == 0) 1107 return 0; 1108 if (OF_getproplen(node, "input-schmitt-enable") == 0) 1109 return 1; 1110 1111 return -1; 1112 } 1113 1114 #define RK3588_PMU1_IOC 0x0000 1115 #define RK3588_PMU2_IOC 0x4000 1116 #define RK3588_BUS_IOC 0x8000 1117 #define RK3588_VCCIO1_4_IOC 0x9000 1118 #define RK3588_VCCIO3_5_IOC 0xa000 1119 #define RK3588_VCCIO2_IOC 0xb000 1120 #define RK3588_VCCIO6_IOC 0xc000 1121 #define RK3588_EMMC_IOC 0xd000 1122 1123 bus_size_t 1124 rk3588_base(uint32_t bank, uint32_t idx) 1125 { 1126 if (bank == 1 && idx < 32) 1127 return RK3588_VCCIO1_4_IOC; 1128 if (bank == 2 && idx < 6) 1129 return RK3588_EMMC_IOC; 1130 if (bank == 2 && idx < 24) 1131 return RK3588_VCCIO3_5_IOC; 1132 if (bank == 2 && idx < 32) 1133 return RK3588_EMMC_IOC; 1134 if (bank == 3 && idx < 32) 1135 return RK3588_VCCIO3_5_IOC; 1136 if (bank == 4 && idx < 18) 1137 return RK3588_VCCIO6_IOC; 1138 if (bank == 4 && idx < 24) 1139 return RK3588_VCCIO3_5_IOC; 1140 if (bank == 4 && idx < 32) 1141 return RK3588_VCCIO2_IOC; 1142 1143 return (bus_size_t)-1; 1144 } 1145 1146 int 1147 rk3588_pinctrl(uint32_t phandle, void *cookie) 1148 { 1149 struct rkpinctrl_softc *sc = cookie; 1150 struct regmap *rm = sc->sc_grf; 1151 uint32_t *pins; 1152 int node, len, i; 1153 1154 KASSERT(sc->sc_grf); 1155 1156 node = OF_getnodebyphandle(phandle); 1157 if (node == 0) 1158 return -1; 1159 1160 len = OF_getproplen(node, "rockchip,pins"); 1161 if (len <= 0) 1162 return -1; 1163 1164 pins = malloc(len, M_TEMP, M_WAITOK); 1165 if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len) 1166 goto fail; 1167 1168 for (i = 0; i < len / sizeof(uint32_t); i += 4) { 1169 bus_size_t iomux_base, p_base, ds_base, smt_base, off; 1170 uint32_t bank, idx, mux; 1171 int pull, strength, schmitt; 1172 uint32_t mask, bits; 1173 int s; 1174 1175 bank = pins[i]; 1176 idx = pins[i + 1]; 1177 mux = pins[i + 2]; 1178 1179 if (bank > 5 || idx >= 32 || mux > 15) 1180 continue; 1181 1182 pull = rk3588_pull(bank, idx, pins[i + 3]); 1183 strength = rk3588_strength(bank, idx, pins[i + 3]); 1184 schmitt = rk3588_schmitt(bank, idx, pins[i + 3]); 1185 1186 if (bank == 0 && idx < 12) { 1187 /* PMU1 */ 1188 iomux_base = RK3588_PMU1_IOC; 1189 } else { 1190 /* BUS */ 1191 iomux_base = RK3588_BUS_IOC; 1192 } 1193 1194 if (bank == 0) { 1195 if (idx < 12) { 1196 /* PMU1 */ 1197 p_base = RK3588_PMU1_IOC + 0x0020; 1198 ds_base = RK3588_PMU1_IOC + 0x0010; 1199 smt_base = RK3588_PMU1_IOC + 0x0030; 1200 } else { 1201 /* PMU2 */ 1202 p_base = RK3588_PMU2_IOC + 0x0024; 1203 ds_base = RK3588_PMU2_IOC + 0x0008; 1204 smt_base = RK3588_PMU2_IOC + 0x003c; 1205 } 1206 } else { 1207 bus_size_t base = rk3588_base(bank, idx); 1208 KASSERT(base != (bus_size_t)-1); 1209 1210 p_base = base + 0x0100; 1211 ds_base = base + 0x0000; 1212 smt_base = base + 0x0200; 1213 } 1214 1215 s = splhigh(); 1216 1217 /* IOMUX control */ 1218 off = bank * 0x20 + (idx / 4) * 0x04; 1219 mask = (0xf << ((idx % 4) * 4)); 1220 bits = (mux << ((idx % 4) * 4)); 1221 regmap_write_4(rm, iomux_base + off, mask << 16 | bits); 1222 if (bank == 0 && idx > 12) { 1223 iomux_base = RK3588_PMU2_IOC; 1224 off = (idx - 12) / 4 * 0x04; 1225 mux = (mux < 8) ? mux : 8; 1226 bits = (mux << ((idx % 4) * 4)); 1227 regmap_write_4(rm, iomux_base + off, mask << 16 | bits); 1228 } 1229 1230 /* GPIO pad pull down and pull up control */ 1231 if (pull >= 0) { 1232 off = bank * 0x10 + (idx / 8) * 0x04; 1233 mask = (0x3 << ((idx % 8) * 2)); 1234 bits = (pull << ((idx % 8) * 2)); 1235 regmap_write_4(rm, p_base + off, mask << 16 | bits); 1236 } 1237 1238 /* GPIO drive strength control */ 1239 if (strength >= 0) { 1240 off = bank * 0x20 + (idx / 4) * 0x04; 1241 mask = (0xf << ((idx % 4) * 4)); 1242 bits = (strength << ((idx % 4) * 4)); 1243 regmap_write_4(rm, ds_base + off, mask << 16 | bits); 1244 } 1245 1246 /* GPIO Schmitt trigger. */ 1247 if (schmitt >= 0) { 1248 off = bank * 0x10 + (idx / 8) * 0x04; 1249 mask = (0x1 << (idx % 8)); 1250 bits = (schmitt << (idx % 8)); 1251 regmap_write_4(rm, smt_base + off, mask << 16 | bits); 1252 } 1253 1254 splx(s); 1255 } 1256 1257 free(pins, M_TEMP, len); 1258 return 0; 1259 1260 fail: 1261 free(pins, M_TEMP, len); 1262 return -1; 1263 } 1264