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