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