1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * (C) Copyright 2018 Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <dm/of_access.h> 9 #include <regmap.h> 10 #include <syscon.h> 11 #include <asm/arch/clock.h> 12 #include <fdtdec.h> 13 #include <linux/compat.h> 14 #include <linux/err.h> 15 #include <power/regulator.h> 16 17 #define MAX_SUPPLIES 16 18 19 /* 20 * The max voltage for 1.8V and 3.3V come from the Rockchip datasheet under 21 * "Recommended Operating Conditions" for "Digital GPIO". When the typical 22 * is 3.3V the max is 3.6V. When the typical is 1.8V the max is 1.98V. 23 * 24 * They are used like this: 25 * - If the voltage on a rail is above the "1.8" voltage (1.98V) we'll tell the 26 * SoC we're at 3.3. 27 * - If the voltage on a rail is above the "3.3" voltage (3.6V) we'll consider 28 * that to be an error. 29 */ 30 #define MAX_VOLTAGE_1_8 1980000 31 #define MAX_VOLTAGE_3_3 3600000 32 33 #define PX30_IO_VSEL 0x180 34 #define PX30_IO_VSEL_VCCIO6_SRC BIT(0) 35 #define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1 36 37 #define RK3288_SOC_CON2 0x24c 38 #define RK3288_SOC_CON2_FLASH0 BIT(7) 39 #define RK3288_SOC_FLASH_SUPPLY_NUM 2 40 41 #define RK3308_SOC_CON0 0x300 42 #define RK3308_SOC_CON0_VCCIO3 BIT(8) 43 #define RK3308_SOC_VCCIO3_SUPPLY_NUM 3 44 45 #define RK3328_SOC_CON4 0x410 46 #define RK3328_SOC_CON4_VCCIO2 BIT(7) 47 #define RK3328_SOC_VCCIO2_SUPPLY_NUM 1 48 49 #define RK3366_SOC_CON6 0x418 50 #define RK3366_SOC_CON6_FLASH0 BIT(14) 51 #define RK3366_SOC_FLASH_SUPPLY_NUM 2 52 53 #define RK3368_SOC_CON15 0x43c 54 #define RK3368_SOC_CON15_FLASH0 BIT(14) 55 #define RK3368_SOC_FLASH_SUPPLY_NUM 2 56 57 #define RK3399_PMUGRF_CON0 0x180 58 #define RK3399_PMUGRF_CON0_VSEL BIT(8) 59 #define RK3399_PMUGRF_VSEL_SUPPLY_NUM 9 60 61 #define RK3568_PMU_GRF_IO_VSEL0 (0x0140) 62 #define RK3568_PMU_GRF_IO_VSEL1 (0x0144) 63 #define RK3568_PMU_GRF_IO_VSEL2 (0x0148) 64 65 struct rockchip_iodomain_priv; 66 67 /** 68 * @supplies: voltage settings matching the register bits. 69 */ 70 struct rockchip_iodomain_soc_data { 71 int grf_offset; 72 const char *supply_names[MAX_SUPPLIES]; 73 void (*init)(struct rockchip_iodomain_priv *iod); 74 }; 75 76 struct rockchip_iodomain_supply { 77 struct rockchip_iodomain_priv *iod; 78 struct udevice *reg; 79 int idx; 80 }; 81 82 struct rockchip_iodomain_priv { 83 struct regmap *regmap_base; 84 struct rockchip_iodomain_soc_data *sdata; 85 struct rockchip_iodomain_supply supplies[MAX_SUPPLIES]; 86 int (*write)(struct rockchip_iodomain_supply *supply, int uV); 87 }; 88 89 static int rockchip_ofdata_to_platdata(struct udevice *dev) 90 { 91 struct rockchip_iodomain_priv *priv = dev_get_priv(dev); 92 struct syscon_uc_info *syscon_priv; 93 struct regmap *regmap; 94 95 syscon_priv = dev_get_uclass_priv(dev_get_parent(dev)); 96 regmap = syscon_priv->regmap; 97 if (IS_ERR(regmap)) 98 return PTR_ERR(regmap); 99 100 priv->regmap_base = regmap; 101 102 return 0; 103 } 104 105 static int rk3568_pmu_iodomain_write(struct rockchip_iodomain_supply *supply, 106 int uV) 107 { 108 struct rockchip_iodomain_priv *priv = supply->iod; 109 struct regmap *regmap = priv->regmap_base; 110 u32 is_3v3 = uV > MAX_VOLTAGE_1_8; 111 u32 val0, val1; 112 int b; 113 114 switch (supply->idx) { 115 case 0: /* pmuio1 */ 116 case 1: /* pmuio2 */ 117 b = supply->idx; 118 val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b)); 119 b = supply->idx + 4; 120 val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0); 121 122 regmap_write(regmap, RK3568_PMU_GRF_IO_VSEL2, val0); 123 regmap_write(regmap, RK3568_PMU_GRF_IO_VSEL2, val1); 124 break; 125 case 2: /* vccio1 */ 126 case 3: /* vccio2 */ 127 case 4: /* vccio3 */ 128 case 5: /* vccio4 */ 129 case 6: /* vccio5 */ 130 case 7: /* vccio6 */ 131 case 8: /* vccio7 */ 132 b = supply->idx - 1; 133 val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b)); 134 val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0); 135 136 regmap_write(regmap, RK3568_PMU_GRF_IO_VSEL0, val0); 137 regmap_write(regmap, RK3568_PMU_GRF_IO_VSEL1, val1); 138 break; 139 default: 140 return -EINVAL; 141 }; 142 143 return 0; 144 } 145 146 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply, 147 int uV) 148 { 149 struct rockchip_iodomain_priv *priv = supply->iod; 150 struct regmap *regmap = priv->regmap_base; 151 u32 val; 152 int ret; 153 154 /* set value bit */ 155 val = (uV > MAX_VOLTAGE_1_8) ? 0 : 1; 156 val <<= supply->idx; 157 158 /* apply hiword-mask */ 159 val |= (BIT(supply->idx) << 16); 160 161 ret = regmap_write(regmap, priv->sdata->grf_offset, val); 162 if (ret) { 163 dev_err(priv->dev, "Couldn't write to GRF\n"); 164 return ret; 165 } 166 167 return 0; 168 } 169 170 static void px30_iodomain_init(struct rockchip_iodomain_priv *iod) 171 { 172 int ret; 173 u32 val; 174 175 /* if no VCCIO0 supply we should leave things alone */ 176 if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg) 177 return; 178 179 /* 180 * set vccio0 iodomain to also use this framework 181 * instead of a special gpio. 182 */ 183 val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16); 184 ret = regmap_write(iod->regmap_base, PX30_IO_VSEL, val); 185 if (ret < 0) 186 dev_warn(iod->dev, "couldn't update vccio0 ctrl\n"); 187 } 188 189 static void rk3288_iodomain_init(struct rockchip_iodomain_priv *iod) 190 { 191 int ret; 192 u32 val; 193 194 /* if no flash supply we should leave things alone */ 195 if (!iod->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg) 196 return; 197 198 /* 199 * set flash0 iodomain to also use this framework 200 * instead of a special gpio. 201 */ 202 val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16); 203 ret = regmap_write(iod->regmap_base, RK3288_SOC_CON2, val); 204 if (ret < 0) 205 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 206 } 207 208 static void rk3308_iodomain_init(struct rockchip_iodomain_priv *iod) 209 { 210 int ret; 211 u32 val; 212 213 /* if no vccio3 supply we should leave things alone */ 214 if (!iod->supplies[RK3308_SOC_VCCIO3_SUPPLY_NUM].reg) 215 return; 216 217 /* 218 * set vccio3 iodomain to also use this framework 219 * instead of a special gpio. 220 */ 221 val = RK3308_SOC_CON0_VCCIO3 | (RK3308_SOC_CON0_VCCIO3 << 16); 222 ret = regmap_write(iod->regmap_base, RK3308_SOC_CON0, val); 223 if (ret < 0) 224 dev_warn(iod->dev, "couldn't update vccio3 vsel ctrl\n"); 225 } 226 227 static void rk3328_iodomain_init(struct rockchip_iodomain_priv *iod) 228 { 229 int ret; 230 u32 val; 231 232 /* if no vccio2 supply we should leave things alone */ 233 if (!iod->supplies[RK3328_SOC_VCCIO2_SUPPLY_NUM].reg) 234 return; 235 236 /* 237 * set vccio2 iodomain to also use this framework 238 * instead of a special gpio. 239 */ 240 val = RK3328_SOC_CON4_VCCIO2 | (RK3328_SOC_CON4_VCCIO2 << 16); 241 ret = regmap_write(iod->regmap_base, RK3328_SOC_CON4, val); 242 if (ret < 0) 243 dev_warn(iod->dev, "couldn't update vccio2 vsel ctrl\n"); 244 } 245 246 static void rk3366_iodomain_init(struct rockchip_iodomain_priv *iod) 247 { 248 int ret; 249 u32 val; 250 251 /* if no flash supply we should leave things alone */ 252 if (!iod->supplies[RK3366_SOC_FLASH_SUPPLY_NUM].reg) 253 return; 254 255 /* 256 * set flash0 iodomain to also use this framework 257 * instead of a special gpio. 258 */ 259 val = RK3366_SOC_CON6_FLASH0 | (RK3366_SOC_CON6_FLASH0 << 16); 260 ret = regmap_write(iod->regmap_base, RK3368_SOC_CON15, val); 261 if (ret < 0) 262 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 263 } 264 265 static void rk3368_iodomain_init(struct rockchip_iodomain_priv *iod) 266 { 267 int ret; 268 u32 val; 269 270 /* if no flash supply we should leave things alone */ 271 if (!iod->supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg) 272 return; 273 274 /* 275 * set flash0 iodomain to also use this framework 276 * instead of a special gpio. 277 */ 278 val = RK3368_SOC_CON15_FLASH0 | (RK3368_SOC_CON15_FLASH0 << 16); 279 ret = regmap_write(iod->regmap_base, RK3368_SOC_CON15, val); 280 if (ret < 0) 281 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 282 } 283 284 static void rk3399_pmu_iodomain_init(struct rockchip_iodomain_priv *iod) 285 { 286 int ret; 287 u32 val; 288 289 /* if no pmu io supply we should leave things alone */ 290 if (!iod->supplies[RK3399_PMUGRF_VSEL_SUPPLY_NUM].reg) 291 return; 292 293 /* 294 * set pmu io iodomain to also use this framework 295 * instead of a special gpio. 296 */ 297 val = RK3399_PMUGRF_CON0_VSEL | (RK3399_PMUGRF_CON0_VSEL << 16); 298 ret = regmap_write(iod->regmap_base, RK3399_PMUGRF_CON0, val); 299 if (ret < 0) 300 dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n"); 301 } 302 303 static const struct rockchip_iodomain_soc_data soc_data_px30 = { 304 .grf_offset = 0x180, 305 .supply_names = { 306 NULL, 307 "vccio6", 308 "vccio1", 309 "vccio2", 310 "vccio3", 311 "vccio4", 312 "vccio5", 313 "vccio-oscgpi", 314 }, 315 .init = px30_iodomain_init, 316 }; 317 318 static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = { 319 .grf_offset = 0x100, 320 .supply_names = { 321 NULL, 322 NULL, 323 NULL, 324 NULL, 325 NULL, 326 NULL, 327 NULL, 328 NULL, 329 NULL, 330 NULL, 331 NULL, 332 NULL, 333 NULL, 334 NULL, 335 "pmuio1", 336 "pmuio2", 337 }, 338 }; 339 340 /* 341 * On the rk3188 the io-domains are handled by a shared register with the 342 * lower 8 bits being still being continuing drive-strength settings. 343 */ 344 static const struct rockchip_iodomain_soc_data soc_data_rk3188 = { 345 .grf_offset = 0x104, 346 .supply_names = { 347 NULL, 348 NULL, 349 NULL, 350 NULL, 351 NULL, 352 NULL, 353 NULL, 354 NULL, 355 "ap0", 356 "ap1", 357 "cif", 358 "flash", 359 "vccio0", 360 "vccio1", 361 "lcdc0", 362 "lcdc1", 363 }, 364 }; 365 366 static const struct rockchip_iodomain_soc_data soc_data_rk322x = { 367 .grf_offset = 0x418, 368 .supply_names = { 369 "vccio1", 370 "vccio2", 371 "vccio3", 372 "vccio4", 373 }, 374 }; 375 376 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { 377 .grf_offset = 0x380, 378 .supply_names = { 379 "lcdc", /* LCDC_VDD */ 380 "dvp", /* DVPIO_VDD */ 381 "flash0", /* FLASH0_VDD (emmc) */ 382 "flash1", /* FLASH1_VDD (sdio1) */ 383 "wifi", /* APIO3_VDD (sdio0) */ 384 "bb", /* APIO5_VDD */ 385 "audio", /* APIO4_VDD */ 386 "sdcard", /* SDMMC0_VDD (sdmmc) */ 387 "gpio30", /* APIO1_VDD */ 388 "gpio1830", /* APIO2_VDD */ 389 }, 390 .init = rk3288_iodomain_init, 391 }; 392 393 static const struct rockchip_iodomain_soc_data soc_data_rk3308 = { 394 .grf_offset = 0x300, 395 .supply_names = { 396 "vccio0", 397 "vccio1", 398 "vccio2", 399 "vccio3", 400 "vccio4", 401 "vccio5", 402 }, 403 .init = rk3308_iodomain_init, 404 }; 405 406 static const struct rockchip_iodomain_soc_data soc_data_rk3328 = { 407 .grf_offset = 0x410, 408 .supply_names = { 409 "vccio1", 410 "vccio2", 411 "vccio3", 412 "vccio4", 413 "vccio5", 414 "vccio6", 415 "pmuio", 416 }, 417 .init = rk3328_iodomain_init, 418 }; 419 420 static const struct rockchip_iodomain_soc_data soc_data_rk3366 = { 421 .grf_offset = 0x900, 422 .supply_names = { 423 "lcdc", /* LCDC_IOVDD */ 424 "dvpts", /* DVP_IOVDD */ 425 "flash", /* FLASH_IOVDD (emmc) */ 426 "wifibt", /* APIO1_IOVDD */ 427 NULL, 428 "audio", /* AUDIO_IODVDD */ 429 "sdcard", /* SDMMC_IOVDD (sdmmc) */ 430 "tphdsor", /* APIO2_IOVDD */ 431 }, 432 .init = rk3366_iodomain_init, 433 }; 434 435 static const struct rockchip_iodomain_soc_data soc_data_rk3368 = { 436 .grf_offset = 0x900, 437 .supply_names = { 438 NULL, /* reserved */ 439 "dvp", /* DVPIO_VDD */ 440 "flash0", /* FLASH0_VDD (emmc) */ 441 "wifi", /* APIO2_VDD (sdio0) */ 442 NULL, 443 "audio", /* APIO3_VDD */ 444 "sdcard", /* SDMMC0_VDD (sdmmc) */ 445 "gpio30", /* APIO1_VDD */ 446 "gpio1830", /* APIO4_VDD (gpujtag) */ 447 }, 448 .init = rk3368_iodomain_init, 449 }; 450 451 static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = { 452 .grf_offset = 0x100, 453 .supply_names = { 454 NULL, 455 NULL, 456 NULL, 457 NULL, 458 "pmu", /*PMU IO domain*/ 459 "vop", /*LCDC IO domain*/ 460 }, 461 }; 462 463 static const struct rockchip_iodomain_soc_data soc_data_rk3399 = { 464 .grf_offset = 0xe640, 465 .supply_names = { 466 "bt656", /* APIO2_VDD */ 467 "audio", /* APIO5_VDD */ 468 "sdmmc", /* SDMMC0_VDD */ 469 "gpio1830", /* APIO4_VDD */ 470 }, 471 }; 472 473 static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = { 474 .grf_offset = 0x180, 475 .supply_names = { 476 NULL, 477 NULL, 478 NULL, 479 NULL, 480 NULL, 481 NULL, 482 NULL, 483 NULL, 484 NULL, 485 "pmu1830", /* PMUIO2_VDD */ 486 }, 487 .init = rk3399_pmu_iodomain_init, 488 }; 489 490 static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = { 491 .grf_offset = 0x140, 492 .supply_names = { 493 "pmuio1", 494 "pmuio2", 495 "vccio1", 496 "vccio2", 497 "vccio3", 498 "vccio4", 499 "vccio5", 500 "vccio6", 501 "vccio7", 502 }, 503 }; 504 505 static const struct rockchip_iodomain_soc_data soc_data_rv1108 = { 506 .grf_offset = 0x404, 507 .supply_names = { 508 NULL, 509 NULL, 510 NULL, 511 NULL, 512 NULL, 513 NULL, 514 NULL, 515 NULL, 516 NULL, 517 NULL, 518 NULL, 519 "vccio1", 520 "vccio2", 521 "vccio3", 522 "vccio5", 523 "vccio6", 524 }, 525 526 }; 527 528 static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = { 529 .grf_offset = 0x104, 530 .supply_names = { 531 "pmu", 532 }, 533 }; 534 535 static const struct rockchip_iodomain_soc_data soc_data_rv1126_pmu = { 536 .grf_offset = 0x140, 537 .supply_names = { 538 NULL, 539 "vccio1", 540 "vccio2", 541 "vccio3", 542 "vccio4", 543 "vccio5", 544 "vccio6", 545 "vccio7", 546 "pmuio0", 547 "pmuio1", 548 }, 549 }; 550 551 static struct udevice *of_get_regulator(ofnode node, const char *supply) 552 { 553 char sname[32]; /* 32 is max size of property name */ 554 struct udevice *sudev = NULL; 555 ofnode snode; 556 u32 phandle; 557 int ret; 558 559 snprintf(sname, 32, "%s-supply", supply); 560 561 /* Get regulator and clk */ 562 if (!ofnode_read_u32(node, sname, &phandle)) { 563 snode = ofnode_get_by_phandle(phandle); 564 ret = regulator_get_by_devname(snode.np->name, &sudev); 565 if (ret) { 566 printf("%s: Get (%s) regulator: %s failed, ret=%d\n", 567 __func__, 568 sname, snode.np->full_name, ret); 569 return NULL; 570 } 571 debug("IO-DOMAIN: supply: %s\n", snode.np->full_name); 572 } 573 574 return sudev; 575 } 576 577 static int rockchip_iodomain_probe(struct udevice *dev) 578 { 579 struct rockchip_iodomain_priv *priv = dev_get_priv(dev); 580 struct rockchip_iodomain_soc_data *sdata; 581 int i, ret; 582 583 sdata = (struct rockchip_iodomain_soc_data *)dev_get_driver_data(dev); 584 priv->sdata = sdata; 585 if (sdata == &soc_data_rk3568_pmu) 586 priv->write = rk3568_pmu_iodomain_write; 587 else 588 priv->write = rockchip_iodomain_write; 589 590 if (!priv->regmap_base) 591 return -1; 592 593 for (i = 0; i < MAX_SUPPLIES; i++) { 594 const char *supply_name = priv->sdata->supply_names[i]; 595 struct rockchip_iodomain_supply *supply = &priv->supplies[i]; 596 struct udevice *reg; 597 u32 uV; 598 599 if (!supply_name) 600 continue; 601 602 reg = of_get_regulator(dev_ofnode(dev), supply_name); 603 if (!reg) 604 continue; 605 606 uV = regulator_get_value(reg); 607 if (uV <= 0) { 608 printf("voltage(%d uV) is invalid from %s\n", uV, reg->name); 609 continue; 610 } 611 612 if (uV > MAX_VOLTAGE_3_3) { 613 printf("%d uV is too high from %s\n", uV, reg->name); 614 continue; 615 } 616 617 /* setup our supply */ 618 supply->idx = i; 619 supply->iod = priv; 620 supply->reg = reg; 621 622 ret = priv->write(supply, uV); 623 if (ret) 624 supply->reg = NULL; 625 } 626 627 if (priv->sdata->init) 628 priv->sdata->init(priv); 629 630 return 0; 631 } 632 633 static const struct udevice_id rockchip_iodomain_match[] = { 634 { 635 .compatible = "rockchip,px30-io-voltage-domain", 636 .data = (ulong)&soc_data_px30 637 }, 638 { 639 .compatible = "rockchip,px30-pmu-io-voltage-domain", 640 .data = (ulong)&soc_data_px30_pmu 641 }, 642 { 643 .compatible = "rockchip,rk3188-io-voltage-domain", 644 .data = (ulong)&soc_data_rk3188 645 }, 646 { 647 .compatible = "rockchip,rk322x-io-voltage-domain", 648 .data = (ulong)&soc_data_rk322x 649 }, 650 { 651 .compatible = "rockchip,rk3288-io-voltage-domain", 652 .data = (ulong)&soc_data_rk3288 653 }, 654 { 655 .compatible = "rockchip,rk3308-io-voltage-domain", 656 .data = (ulong)&soc_data_rk3308 657 }, 658 { 659 .compatible = "rockchip,rk3328-io-voltage-domain", 660 .data = (ulong)&soc_data_rk3328 661 }, 662 { 663 .compatible = "rockchip,rk3366-io-voltage-domain", 664 .data = (ulong)&soc_data_rk3366 665 }, 666 { 667 .compatible = "rockchip,rk3368-io-voltage-domain", 668 .data = (ulong)&soc_data_rk3368 669 }, 670 { 671 .compatible = "rockchip,rk3368-pmu-io-voltage-domain", 672 .data = (ulong)&soc_data_rk3368_pmu 673 }, 674 { 675 .compatible = "rockchip,rk3399-io-voltage-domain", 676 .data = (ulong)&soc_data_rk3399 677 }, 678 { 679 .compatible = "rockchip,rk3399-pmu-io-voltage-domain", 680 .data = (ulong)&soc_data_rk3399_pmu 681 }, 682 { 683 .compatible = "rockchip,rk3568-pmu-io-voltage-domain", 684 .data = (ulong)&soc_data_rk3568_pmu 685 }, 686 { 687 .compatible = "rockchip,rv1108-io-voltage-domain", 688 .data = (ulong)&soc_data_rv1108 689 }, 690 { 691 .compatible = "rockchip,rv1108-pmu-io-voltage-domain", 692 .data = (ulong)&soc_data_rv1108_pmu 693 }, 694 { 695 .compatible = "rockchip,rv1126-pmu-io-voltage-domain", 696 .data = (ulong)&soc_data_rv1126_pmu 697 }, 698 { /* sentinel */ }, 699 }; 700 701 U_BOOT_DRIVER(io_domain) = { 702 .name = "io_domain", 703 .id = UCLASS_IO_DOMAIN, 704 .of_match = rockchip_iodomain_match, 705 .priv_auto_alloc_size = sizeof(struct rockchip_iodomain_priv), 706 .ofdata_to_platdata = rockchip_ofdata_to_platdata, 707 .probe = rockchip_iodomain_probe, 708 }; 709