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 struct rockchip_iodomain_priv; 62 63 /** 64 * @supplies: voltage settings matching the register bits. 65 */ 66 struct rockchip_iodomain_soc_data { 67 int grf_offset; 68 const char *supply_names[MAX_SUPPLIES]; 69 void (*init)(struct rockchip_iodomain_priv *iod); 70 }; 71 72 struct rockchip_iodomain_supply { 73 struct rockchip_iodomain_priv *iod; 74 struct udevice *reg; 75 int idx; 76 }; 77 78 struct rockchip_iodomain_priv { 79 struct regmap *regmap_base; 80 struct rockchip_iodomain_soc_data *sdata; 81 struct rockchip_iodomain_supply supplies[MAX_SUPPLIES]; 82 }; 83 84 static int rockchip_ofdata_to_platdata(struct udevice *dev) 85 { 86 struct rockchip_iodomain_priv *priv = dev_get_priv(dev); 87 struct regmap *regmap; 88 89 /* get grf-reg base address */ 90 regmap = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_GRF); 91 if (IS_ERR(regmap)) 92 return PTR_ERR(regmap); 93 94 priv->regmap_base = regmap; 95 96 return 0; 97 } 98 99 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply, 100 int uV) 101 { 102 struct rockchip_iodomain_priv *priv = supply->iod; 103 struct regmap *regmap = priv->regmap_base; 104 u32 val; 105 int ret; 106 107 /* set value bit */ 108 val = (uV > MAX_VOLTAGE_1_8) ? 0 : 1; 109 val <<= supply->idx; 110 111 /* apply hiword-mask */ 112 val |= (BIT(supply->idx) << 16); 113 114 ret = regmap_write(regmap, priv->sdata->grf_offset, val); 115 if (ret) { 116 dev_err(priv->dev, "Couldn't write to GRF\n"); 117 return ret; 118 } 119 120 return 0; 121 } 122 123 static void px30_iodomain_init(struct rockchip_iodomain_priv *iod) 124 { 125 int ret; 126 u32 val; 127 128 /* if no VCCIO0 supply we should leave things alone */ 129 if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg) 130 return; 131 132 /* 133 * set vccio0 iodomain to also use this framework 134 * instead of a special gpio. 135 */ 136 val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16); 137 ret = regmap_write(iod->regmap_base, PX30_IO_VSEL, val); 138 if (ret < 0) 139 dev_warn(iod->dev, "couldn't update vccio0 ctrl\n"); 140 } 141 142 static void rk3288_iodomain_init(struct rockchip_iodomain_priv *iod) 143 { 144 int ret; 145 u32 val; 146 147 /* if no flash supply we should leave things alone */ 148 if (!iod->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg) 149 return; 150 151 /* 152 * set flash0 iodomain to also use this framework 153 * instead of a special gpio. 154 */ 155 val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16); 156 ret = regmap_write(iod->regmap_base, RK3288_SOC_CON2, val); 157 if (ret < 0) 158 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 159 } 160 161 static void rk3308_iodomain_init(struct rockchip_iodomain_priv *iod) 162 { 163 int ret; 164 u32 val; 165 166 /* if no vccio3 supply we should leave things alone */ 167 if (!iod->supplies[RK3308_SOC_VCCIO3_SUPPLY_NUM].reg) 168 return; 169 170 /* 171 * set vccio3 iodomain to also use this framework 172 * instead of a special gpio. 173 */ 174 val = RK3308_SOC_CON0_VCCIO3 | (RK3308_SOC_CON0_VCCIO3 << 16); 175 ret = regmap_write(iod->regmap_base, RK3308_SOC_CON0, val); 176 if (ret < 0) 177 dev_warn(iod->dev, "couldn't update vccio3 vsel ctrl\n"); 178 } 179 180 static void rk3328_iodomain_init(struct rockchip_iodomain_priv *iod) 181 { 182 int ret; 183 u32 val; 184 185 /* if no vccio2 supply we should leave things alone */ 186 if (!iod->supplies[RK3328_SOC_VCCIO2_SUPPLY_NUM].reg) 187 return; 188 189 /* 190 * set vccio2 iodomain to also use this framework 191 * instead of a special gpio. 192 */ 193 val = RK3328_SOC_CON4_VCCIO2 | (RK3328_SOC_CON4_VCCIO2 << 16); 194 ret = regmap_write(iod->regmap_base, RK3328_SOC_CON4, val); 195 if (ret < 0) 196 dev_warn(iod->dev, "couldn't update vccio2 vsel ctrl\n"); 197 } 198 199 static void rk3366_iodomain_init(struct rockchip_iodomain_priv *iod) 200 { 201 int ret; 202 u32 val; 203 204 /* if no flash supply we should leave things alone */ 205 if (!iod->supplies[RK3366_SOC_FLASH_SUPPLY_NUM].reg) 206 return; 207 208 /* 209 * set flash0 iodomain to also use this framework 210 * instead of a special gpio. 211 */ 212 val = RK3366_SOC_CON6_FLASH0 | (RK3366_SOC_CON6_FLASH0 << 16); 213 ret = regmap_write(iod->regmap_base, RK3368_SOC_CON15, val); 214 if (ret < 0) 215 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 216 } 217 218 static void rk3368_iodomain_init(struct rockchip_iodomain_priv *iod) 219 { 220 int ret; 221 u32 val; 222 223 /* if no flash supply we should leave things alone */ 224 if (!iod->supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg) 225 return; 226 227 /* 228 * set flash0 iodomain to also use this framework 229 * instead of a special gpio. 230 */ 231 val = RK3368_SOC_CON15_FLASH0 | (RK3368_SOC_CON15_FLASH0 << 16); 232 ret = regmap_write(iod->regmap_base, RK3368_SOC_CON15, val); 233 if (ret < 0) 234 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 235 } 236 237 static void rk3399_pmu_iodomain_init(struct rockchip_iodomain_priv *iod) 238 { 239 int ret; 240 u32 val; 241 242 /* if no pmu io supply we should leave things alone */ 243 if (!iod->supplies[RK3399_PMUGRF_VSEL_SUPPLY_NUM].reg) 244 return; 245 246 /* 247 * set pmu io iodomain to also use this framework 248 * instead of a special gpio. 249 */ 250 val = RK3399_PMUGRF_CON0_VSEL | (RK3399_PMUGRF_CON0_VSEL << 16); 251 ret = regmap_write(iod->regmap_base, RK3399_PMUGRF_CON0, val); 252 if (ret < 0) 253 dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n"); 254 } 255 256 static const struct rockchip_iodomain_soc_data soc_data_px30 = { 257 .grf_offset = 0x180, 258 .supply_names = { 259 NULL, 260 "vccio6", 261 "vccio1", 262 "vccio2", 263 "vccio3", 264 "vccio4", 265 "vccio5", 266 "vccio-oscgpi", 267 }, 268 .init = px30_iodomain_init, 269 }; 270 271 static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = { 272 .grf_offset = 0x100, 273 .supply_names = { 274 NULL, 275 NULL, 276 NULL, 277 NULL, 278 NULL, 279 NULL, 280 NULL, 281 NULL, 282 NULL, 283 NULL, 284 NULL, 285 NULL, 286 NULL, 287 NULL, 288 "pmuio1", 289 "pmuio2", 290 }, 291 }; 292 293 /* 294 * On the rk3188 the io-domains are handled by a shared register with the 295 * lower 8 bits being still being continuing drive-strength settings. 296 */ 297 static const struct rockchip_iodomain_soc_data soc_data_rk3188 = { 298 .grf_offset = 0x104, 299 .supply_names = { 300 NULL, 301 NULL, 302 NULL, 303 NULL, 304 NULL, 305 NULL, 306 NULL, 307 NULL, 308 "ap0", 309 "ap1", 310 "cif", 311 "flash", 312 "vccio0", 313 "vccio1", 314 "lcdc0", 315 "lcdc1", 316 }, 317 }; 318 319 static const struct rockchip_iodomain_soc_data soc_data_rk322x = { 320 .grf_offset = 0x418, 321 .supply_names = { 322 "vccio1", 323 "vccio2", 324 "vccio3", 325 "vccio4", 326 }, 327 }; 328 329 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { 330 .grf_offset = 0x380, 331 .supply_names = { 332 "lcdc", /* LCDC_VDD */ 333 "dvp", /* DVPIO_VDD */ 334 "flash0", /* FLASH0_VDD (emmc) */ 335 "flash1", /* FLASH1_VDD (sdio1) */ 336 "wifi", /* APIO3_VDD (sdio0) */ 337 "bb", /* APIO5_VDD */ 338 "audio", /* APIO4_VDD */ 339 "sdcard", /* SDMMC0_VDD (sdmmc) */ 340 "gpio30", /* APIO1_VDD */ 341 "gpio1830", /* APIO2_VDD */ 342 }, 343 .init = rk3288_iodomain_init, 344 }; 345 346 static const struct rockchip_iodomain_soc_data soc_data_rk3308 = { 347 .grf_offset = 0x300, 348 .supply_names = { 349 "vccio0", 350 "vccio1", 351 "vccio2", 352 "vccio3", 353 "vccio4", 354 "vccio5", 355 }, 356 .init = rk3308_iodomain_init, 357 }; 358 359 static const struct rockchip_iodomain_soc_data soc_data_rk3328 = { 360 .grf_offset = 0x410, 361 .supply_names = { 362 "vccio1", 363 "vccio2", 364 "vccio3", 365 "vccio4", 366 "vccio5", 367 "vccio6", 368 "pmuio", 369 }, 370 .init = rk3328_iodomain_init, 371 }; 372 373 static const struct rockchip_iodomain_soc_data soc_data_rk3366 = { 374 .grf_offset = 0x900, 375 .supply_names = { 376 "lcdc", /* LCDC_IOVDD */ 377 "dvpts", /* DVP_IOVDD */ 378 "flash", /* FLASH_IOVDD (emmc) */ 379 "wifibt", /* APIO1_IOVDD */ 380 NULL, 381 "audio", /* AUDIO_IODVDD */ 382 "sdcard", /* SDMMC_IOVDD (sdmmc) */ 383 "tphdsor", /* APIO2_IOVDD */ 384 }, 385 .init = rk3366_iodomain_init, 386 }; 387 388 static const struct rockchip_iodomain_soc_data soc_data_rk3368 = { 389 .grf_offset = 0x900, 390 .supply_names = { 391 NULL, /* reserved */ 392 "dvp", /* DVPIO_VDD */ 393 "flash0", /* FLASH0_VDD (emmc) */ 394 "wifi", /* APIO2_VDD (sdio0) */ 395 NULL, 396 "audio", /* APIO3_VDD */ 397 "sdcard", /* SDMMC0_VDD (sdmmc) */ 398 "gpio30", /* APIO1_VDD */ 399 "gpio1830", /* APIO4_VDD (gpujtag) */ 400 }, 401 .init = rk3368_iodomain_init, 402 }; 403 404 static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = { 405 .grf_offset = 0x100, 406 .supply_names = { 407 NULL, 408 NULL, 409 NULL, 410 NULL, 411 "pmu", /*PMU IO domain*/ 412 "vop", /*LCDC IO domain*/ 413 }, 414 }; 415 416 static const struct rockchip_iodomain_soc_data soc_data_rk3399 = { 417 .grf_offset = 0xe640, 418 .supply_names = { 419 "bt656", /* APIO2_VDD */ 420 "audio", /* APIO5_VDD */ 421 "sdmmc", /* SDMMC0_VDD */ 422 "gpio1830", /* APIO4_VDD */ 423 }, 424 }; 425 426 static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = { 427 .grf_offset = 0x180, 428 .supply_names = { 429 NULL, 430 NULL, 431 NULL, 432 NULL, 433 NULL, 434 NULL, 435 NULL, 436 NULL, 437 NULL, 438 "pmu1830", /* PMUIO2_VDD */ 439 }, 440 .init = rk3399_pmu_iodomain_init, 441 }; 442 443 static const struct rockchip_iodomain_soc_data soc_data_rv1108 = { 444 .grf_offset = 0x404, 445 .supply_names = { 446 NULL, 447 NULL, 448 NULL, 449 NULL, 450 NULL, 451 NULL, 452 NULL, 453 NULL, 454 NULL, 455 NULL, 456 NULL, 457 "vccio1", 458 "vccio2", 459 "vccio3", 460 "vccio5", 461 "vccio6", 462 }, 463 464 }; 465 466 static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = { 467 .grf_offset = 0x104, 468 .supply_names = { 469 "pmu", 470 }, 471 }; 472 473 static struct udevice *of_get_regulator(ofnode node, const char *supply) 474 { 475 char sname[32]; /* 32 is max size of property name */ 476 struct udevice *sudev; 477 ofnode snode; 478 u32 phandle; 479 int ret; 480 481 snprintf(sname, 32, "%s-supply", supply); 482 483 /* Get regulator and clk */ 484 if (!ofnode_read_u32(node, sname, &phandle)) { 485 snode = ofnode_get_by_phandle(phandle); 486 ret = regulator_get_by_devname(snode.np->name, &sudev); 487 if (ret) { 488 printf("%s: %s: Get supply(%s) failed, ret=%d", 489 __func__, 490 sudev->name, snode.np->full_name, ret); 491 return NULL; 492 } 493 debug("IO-DOMAIN: supply: %s\n", snode.np->full_name); 494 } 495 496 return sudev; 497 } 498 499 static int rockchip_iodomain_probe(struct udevice *dev) 500 { 501 struct rockchip_iodomain_priv *priv = dev_get_priv(dev); 502 struct rockchip_iodomain_soc_data *sdata; 503 int i, ret; 504 505 sdata = (struct rockchip_iodomain_soc_data *)dev_get_driver_data(dev); 506 priv->sdata = sdata; 507 508 if (!priv->regmap_base) 509 return -1; 510 511 for (i = 0; i < MAX_SUPPLIES; i++) { 512 const char *supply_name = priv->sdata->supply_names[i]; 513 struct rockchip_iodomain_supply *supply = &priv->supplies[i]; 514 struct udevice *reg; 515 u32 uV; 516 517 if (!supply_name) 518 continue; 519 520 reg = of_get_regulator(dev_ofnode(dev), supply_name); 521 if (!reg) { 522 printf("could not find regulator %s\n", supply_name); 523 return -1; 524 } 525 526 uV = regulator_get_value(reg); 527 if (uV < 0) { 528 printf("could not get voltage from %s\n", reg->name); 529 return -1; 530 } 531 532 if (uV > MAX_VOLTAGE_3_3) { 533 printf("%d uV is too high from %s\n", uV, reg->name); 534 return -1; 535 } 536 537 /* setup our supply */ 538 supply->idx = i; 539 supply->iod = priv; 540 supply->reg = reg; 541 542 ret = rockchip_iodomain_write(supply, uV); 543 if (ret) 544 supply->reg = NULL; 545 } 546 547 if (priv->sdata->init) 548 priv->sdata->init(priv); 549 550 return 0; 551 } 552 553 static const struct udevice_id rockchip_iodomain_match[] = { 554 { 555 .compatible = "rockchip,px30-io-voltage-domain", 556 .data = (ulong)&soc_data_px30 557 }, 558 { 559 .compatible = "rockchip,px30-pmu-io-voltage-domain", 560 .data = (ulong)&soc_data_px30_pmu 561 }, 562 { 563 .compatible = "rockchip,rk3188-io-voltage-domain", 564 .data = (ulong)&soc_data_rk3188 565 }, 566 { 567 .compatible = "rockchip,rk322x-io-voltage-domain", 568 .data = (ulong)&soc_data_rk322x 569 }, 570 { 571 .compatible = "rockchip,rk3288-io-voltage-domain", 572 .data = (ulong)&soc_data_rk3288 573 }, 574 { 575 .compatible = "rockchip,rk3308-io-voltage-domain", 576 .data = (ulong)&soc_data_rk3308 577 }, 578 { 579 .compatible = "rockchip,rk3328-io-voltage-domain", 580 .data = (ulong)&soc_data_rk3328 581 }, 582 { 583 .compatible = "rockchip,rk3366-io-voltage-domain", 584 .data = (ulong)&soc_data_rk3366 585 }, 586 { 587 .compatible = "rockchip,rk3368-io-voltage-domain", 588 .data = (ulong)&soc_data_rk3368 589 }, 590 { 591 .compatible = "rockchip,rk3368-pmu-io-voltage-domain", 592 .data = (ulong)&soc_data_rk3368_pmu 593 }, 594 { 595 .compatible = "rockchip,rk3399-io-voltage-domain", 596 .data = (ulong)&soc_data_rk3399 597 }, 598 { 599 .compatible = "rockchip,rk3399-pmu-io-voltage-domain", 600 .data = (ulong)&soc_data_rk3399_pmu 601 }, 602 { 603 .compatible = "rockchip,rv1108-io-voltage-domain", 604 .data = (ulong)&soc_data_rv1108 605 }, 606 { 607 .compatible = "rockchip,rv1108-pmu-io-voltage-domain", 608 .data = (ulong)&soc_data_rv1108_pmu 609 }, 610 { /* sentinel */ }, 611 }; 612 613 U_BOOT_DRIVER(io_domain) = { 614 .name = "io_domain", 615 .id = UCLASS_IO_DOMAIN, 616 .of_match = rockchip_iodomain_match, 617 .priv_auto_alloc_size = sizeof(struct rockchip_iodomain_priv), 618 .ofdata_to_platdata = rockchip_ofdata_to_platdata, 619 .probe = rockchip_iodomain_probe, 620 }; 621