1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Rockchip IO Voltage Domain driver 4 * 5 * Copyright 2014 MundoReader S.L. 6 * Copyright 2014 Google, Inc. 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 #include <linux/err.h> 12 #include <linux/mfd/syscon.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 #include <linux/regulator/consumer.h> 17 18 #define MAX_SUPPLIES 16 19 20 /* 21 * The max voltage for 1.8V and 3.3V come from the Rockchip datasheet under 22 * "Recommended Operating Conditions" for "Digital GPIO". When the typical 23 * is 3.3V the max is 3.6V. When the typical is 1.8V the max is 1.98V. 24 * 25 * They are used like this: 26 * - If the voltage on a rail is above the "1.8" voltage (1.98V) we'll tell the 27 * SoC we're at 3.3. 28 * - If the voltage on a rail is above the "3.3" voltage (3.6V) we'll consider 29 * that to be an error. 30 */ 31 #define MAX_VOLTAGE_1_8 1980000 32 #define MAX_VOLTAGE_3_3 3600000 33 34 #define PX30_IO_VSEL 0x180 35 #define PX30_IO_VSEL_VCCIO6_SRC BIT(0) 36 #define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1 37 38 #define RK3288_SOC_CON2 0x24c 39 #define RK3288_SOC_CON2_FLASH0 BIT(7) 40 #define RK3288_SOC_FLASH_SUPPLY_NUM 2 41 42 #define RK3328_SOC_CON4 0x410 43 #define RK3328_SOC_CON4_VCCIO2 BIT(7) 44 #define RK3328_SOC_VCCIO2_SUPPLY_NUM 1 45 46 #define RK3368_SOC_CON15 0x43c 47 #define RK3368_SOC_CON15_FLASH0 BIT(14) 48 #define RK3368_SOC_FLASH_SUPPLY_NUM 2 49 50 #define RK3399_PMUGRF_CON0 0x180 51 #define RK3399_PMUGRF_CON0_VSEL BIT(8) 52 #define RK3399_PMUGRF_VSEL_SUPPLY_NUM 9 53 54 struct rockchip_iodomain; 55 56 struct rockchip_iodomain_soc_data { 57 int grf_offset; 58 const char *supply_names[MAX_SUPPLIES]; 59 void (*init)(struct rockchip_iodomain *iod); 60 }; 61 62 struct rockchip_iodomain_supply { 63 struct rockchip_iodomain *iod; 64 struct regulator *reg; 65 struct notifier_block nb; 66 int idx; 67 }; 68 69 struct rockchip_iodomain { 70 struct device *dev; 71 struct regmap *grf; 72 const struct rockchip_iodomain_soc_data *soc_data; 73 struct rockchip_iodomain_supply supplies[MAX_SUPPLIES]; 74 }; 75 76 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply, 77 int uV) 78 { 79 struct rockchip_iodomain *iod = supply->iod; 80 u32 val; 81 int ret; 82 83 /* set value bit */ 84 val = (uV > MAX_VOLTAGE_1_8) ? 0 : 1; 85 val <<= supply->idx; 86 87 /* apply hiword-mask */ 88 val |= (BIT(supply->idx) << 16); 89 90 ret = regmap_write(iod->grf, iod->soc_data->grf_offset, val); 91 if (ret) 92 dev_err(iod->dev, "Couldn't write to GRF\n"); 93 94 return ret; 95 } 96 97 static int rockchip_iodomain_notify(struct notifier_block *nb, 98 unsigned long event, 99 void *data) 100 { 101 struct rockchip_iodomain_supply *supply = 102 container_of(nb, struct rockchip_iodomain_supply, nb); 103 int uV; 104 int ret; 105 106 /* 107 * According to Rockchip it's important to keep the SoC IO domain 108 * higher than (or equal to) the external voltage. That means we need 109 * to change it before external voltage changes happen in the case 110 * of an increase. 111 * 112 * Note that in the "pre" change we pick the max possible voltage that 113 * the regulator might end up at (the client requests a range and we 114 * don't know for certain the exact voltage). Right now we rely on the 115 * slop in MAX_VOLTAGE_1_8 and MAX_VOLTAGE_3_3 to save us if clients 116 * request something like a max of 3.6V when they really want 3.3V. 117 * We could attempt to come up with better rules if this fails. 118 */ 119 if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) { 120 struct pre_voltage_change_data *pvc_data = data; 121 122 uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV); 123 } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE | 124 REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) { 125 uV = (unsigned long)data; 126 } else { 127 return NOTIFY_OK; 128 } 129 130 dev_dbg(supply->iod->dev, "Setting to %d\n", uV); 131 132 if (uV > MAX_VOLTAGE_3_3) { 133 dev_err(supply->iod->dev, "Voltage too high: %d\n", uV); 134 135 if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) 136 return NOTIFY_BAD; 137 } 138 139 ret = rockchip_iodomain_write(supply, uV); 140 if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) 141 return NOTIFY_BAD; 142 143 dev_dbg(supply->iod->dev, "Setting to %d done\n", uV); 144 return NOTIFY_OK; 145 } 146 147 static void px30_iodomain_init(struct rockchip_iodomain *iod) 148 { 149 int ret; 150 u32 val; 151 152 /* if no VCCIO6 supply we should leave things alone */ 153 if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg) 154 return; 155 156 /* 157 * set vccio6 iodomain to also use this framework 158 * instead of a special gpio. 159 */ 160 val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16); 161 ret = regmap_write(iod->grf, PX30_IO_VSEL, val); 162 if (ret < 0) 163 dev_warn(iod->dev, "couldn't update vccio6 ctrl\n"); 164 } 165 166 static void rk3288_iodomain_init(struct rockchip_iodomain *iod) 167 { 168 int ret; 169 u32 val; 170 171 /* if no flash supply we should leave things alone */ 172 if (!iod->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg) 173 return; 174 175 /* 176 * set flash0 iodomain to also use this framework 177 * instead of a special gpio. 178 */ 179 val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16); 180 ret = regmap_write(iod->grf, RK3288_SOC_CON2, val); 181 if (ret < 0) 182 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 183 } 184 185 static void rk3328_iodomain_init(struct rockchip_iodomain *iod) 186 { 187 int ret; 188 u32 val; 189 190 /* if no vccio2 supply we should leave things alone */ 191 if (!iod->supplies[RK3328_SOC_VCCIO2_SUPPLY_NUM].reg) 192 return; 193 194 /* 195 * set vccio2 iodomain to also use this framework 196 * instead of a special gpio. 197 */ 198 val = RK3328_SOC_CON4_VCCIO2 | (RK3328_SOC_CON4_VCCIO2 << 16); 199 ret = regmap_write(iod->grf, RK3328_SOC_CON4, val); 200 if (ret < 0) 201 dev_warn(iod->dev, "couldn't update vccio2 vsel ctrl\n"); 202 } 203 204 static void rk3368_iodomain_init(struct rockchip_iodomain *iod) 205 { 206 int ret; 207 u32 val; 208 209 /* if no flash supply we should leave things alone */ 210 if (!iod->supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg) 211 return; 212 213 /* 214 * set flash0 iodomain to also use this framework 215 * instead of a special gpio. 216 */ 217 val = RK3368_SOC_CON15_FLASH0 | (RK3368_SOC_CON15_FLASH0 << 16); 218 ret = regmap_write(iod->grf, RK3368_SOC_CON15, val); 219 if (ret < 0) 220 dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); 221 } 222 223 static void rk3399_pmu_iodomain_init(struct rockchip_iodomain *iod) 224 { 225 int ret; 226 u32 val; 227 228 /* if no pmu io supply we should leave things alone */ 229 if (!iod->supplies[RK3399_PMUGRF_VSEL_SUPPLY_NUM].reg) 230 return; 231 232 /* 233 * set pmu io iodomain to also use this framework 234 * instead of a special gpio. 235 */ 236 val = RK3399_PMUGRF_CON0_VSEL | (RK3399_PMUGRF_CON0_VSEL << 16); 237 ret = regmap_write(iod->grf, RK3399_PMUGRF_CON0, val); 238 if (ret < 0) 239 dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n"); 240 } 241 242 static const struct rockchip_iodomain_soc_data soc_data_px30 = { 243 .grf_offset = 0x180, 244 .supply_names = { 245 NULL, 246 "vccio6", 247 "vccio1", 248 "vccio2", 249 "vccio3", 250 "vccio4", 251 "vccio5", 252 "vccio-oscgpi", 253 }, 254 .init = px30_iodomain_init, 255 }; 256 257 static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = { 258 .grf_offset = 0x100, 259 .supply_names = { 260 NULL, 261 NULL, 262 NULL, 263 NULL, 264 NULL, 265 NULL, 266 NULL, 267 NULL, 268 NULL, 269 NULL, 270 NULL, 271 NULL, 272 NULL, 273 NULL, 274 "pmuio1", 275 "pmuio2", 276 }, 277 }; 278 279 /* 280 * On the rk3188 the io-domains are handled by a shared register with the 281 * lower 8 bits being still being continuing drive-strength settings. 282 */ 283 static const struct rockchip_iodomain_soc_data soc_data_rk3188 = { 284 .grf_offset = 0x104, 285 .supply_names = { 286 NULL, 287 NULL, 288 NULL, 289 NULL, 290 NULL, 291 NULL, 292 NULL, 293 NULL, 294 "ap0", 295 "ap1", 296 "cif", 297 "flash", 298 "vccio0", 299 "vccio1", 300 "lcdc0", 301 "lcdc1", 302 }, 303 }; 304 305 static const struct rockchip_iodomain_soc_data soc_data_rk3228 = { 306 .grf_offset = 0x418, 307 .supply_names = { 308 "vccio1", 309 "vccio2", 310 "vccio3", 311 "vccio4", 312 }, 313 }; 314 315 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { 316 .grf_offset = 0x380, 317 .supply_names = { 318 "lcdc", /* LCDC_VDD */ 319 "dvp", /* DVPIO_VDD */ 320 "flash0", /* FLASH0_VDD (emmc) */ 321 "flash1", /* FLASH1_VDD (sdio1) */ 322 "wifi", /* APIO3_VDD (sdio0) */ 323 "bb", /* APIO5_VDD */ 324 "audio", /* APIO4_VDD */ 325 "sdcard", /* SDMMC0_VDD (sdmmc) */ 326 "gpio30", /* APIO1_VDD */ 327 "gpio1830", /* APIO2_VDD */ 328 }, 329 .init = rk3288_iodomain_init, 330 }; 331 332 static const struct rockchip_iodomain_soc_data soc_data_rk3328 = { 333 .grf_offset = 0x410, 334 .supply_names = { 335 "vccio1", 336 "vccio2", 337 "vccio3", 338 "vccio4", 339 "vccio5", 340 "vccio6", 341 "pmuio", 342 }, 343 .init = rk3328_iodomain_init, 344 }; 345 346 static const struct rockchip_iodomain_soc_data soc_data_rk3368 = { 347 .grf_offset = 0x900, 348 .supply_names = { 349 NULL, /* reserved */ 350 "dvp", /* DVPIO_VDD */ 351 "flash0", /* FLASH0_VDD (emmc) */ 352 "wifi", /* APIO2_VDD (sdio0) */ 353 NULL, 354 "audio", /* APIO3_VDD */ 355 "sdcard", /* SDMMC0_VDD (sdmmc) */ 356 "gpio30", /* APIO1_VDD */ 357 "gpio1830", /* APIO4_VDD (gpujtag) */ 358 }, 359 .init = rk3368_iodomain_init, 360 }; 361 362 static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = { 363 .grf_offset = 0x100, 364 .supply_names = { 365 NULL, 366 NULL, 367 NULL, 368 NULL, 369 "pmu", /*PMU IO domain*/ 370 "vop", /*LCDC IO domain*/ 371 }, 372 }; 373 374 static const struct rockchip_iodomain_soc_data soc_data_rk3399 = { 375 .grf_offset = 0xe640, 376 .supply_names = { 377 "bt656", /* APIO2_VDD */ 378 "audio", /* APIO5_VDD */ 379 "sdmmc", /* SDMMC0_VDD */ 380 "gpio1830", /* APIO4_VDD */ 381 }, 382 }; 383 384 static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = { 385 .grf_offset = 0x180, 386 .supply_names = { 387 NULL, 388 NULL, 389 NULL, 390 NULL, 391 NULL, 392 NULL, 393 NULL, 394 NULL, 395 NULL, 396 "pmu1830", /* PMUIO2_VDD */ 397 }, 398 .init = rk3399_pmu_iodomain_init, 399 }; 400 401 static const struct rockchip_iodomain_soc_data soc_data_rv1108 = { 402 .grf_offset = 0x404, 403 .supply_names = { 404 NULL, 405 NULL, 406 NULL, 407 NULL, 408 NULL, 409 NULL, 410 NULL, 411 NULL, 412 NULL, 413 NULL, 414 NULL, 415 "vccio1", 416 "vccio2", 417 "vccio3", 418 "vccio5", 419 "vccio6", 420 }, 421 422 }; 423 424 static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = { 425 .grf_offset = 0x104, 426 .supply_names = { 427 "pmu", 428 }, 429 }; 430 431 static const struct of_device_id rockchip_iodomain_match[] = { 432 { 433 .compatible = "rockchip,px30-io-voltage-domain", 434 .data = (void *)&soc_data_px30 435 }, 436 { 437 .compatible = "rockchip,px30-pmu-io-voltage-domain", 438 .data = (void *)&soc_data_px30_pmu 439 }, 440 { 441 .compatible = "rockchip,rk3188-io-voltage-domain", 442 .data = &soc_data_rk3188 443 }, 444 { 445 .compatible = "rockchip,rk3228-io-voltage-domain", 446 .data = &soc_data_rk3228 447 }, 448 { 449 .compatible = "rockchip,rk3288-io-voltage-domain", 450 .data = &soc_data_rk3288 451 }, 452 { 453 .compatible = "rockchip,rk3328-io-voltage-domain", 454 .data = &soc_data_rk3328 455 }, 456 { 457 .compatible = "rockchip,rk3368-io-voltage-domain", 458 .data = &soc_data_rk3368 459 }, 460 { 461 .compatible = "rockchip,rk3368-pmu-io-voltage-domain", 462 .data = &soc_data_rk3368_pmu 463 }, 464 { 465 .compatible = "rockchip,rk3399-io-voltage-domain", 466 .data = &soc_data_rk3399 467 }, 468 { 469 .compatible = "rockchip,rk3399-pmu-io-voltage-domain", 470 .data = &soc_data_rk3399_pmu 471 }, 472 { 473 .compatible = "rockchip,rv1108-io-voltage-domain", 474 .data = &soc_data_rv1108 475 }, 476 { 477 .compatible = "rockchip,rv1108-pmu-io-voltage-domain", 478 .data = &soc_data_rv1108_pmu 479 }, 480 { /* sentinel */ }, 481 }; 482 MODULE_DEVICE_TABLE(of, rockchip_iodomain_match); 483 484 static int rockchip_iodomain_probe(struct platform_device *pdev) 485 { 486 struct device_node *np = pdev->dev.of_node; 487 const struct of_device_id *match; 488 struct rockchip_iodomain *iod; 489 struct device *parent; 490 int i, ret = 0; 491 492 if (!np) 493 return -ENODEV; 494 495 iod = devm_kzalloc(&pdev->dev, sizeof(*iod), GFP_KERNEL); 496 if (!iod) 497 return -ENOMEM; 498 499 iod->dev = &pdev->dev; 500 platform_set_drvdata(pdev, iod); 501 502 match = of_match_node(rockchip_iodomain_match, np); 503 iod->soc_data = match->data; 504 505 parent = pdev->dev.parent; 506 if (parent && parent->of_node) { 507 iod->grf = syscon_node_to_regmap(parent->of_node); 508 } else { 509 dev_dbg(&pdev->dev, "falling back to old binding\n"); 510 iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 511 } 512 513 if (IS_ERR(iod->grf)) { 514 dev_err(&pdev->dev, "couldn't find grf regmap\n"); 515 return PTR_ERR(iod->grf); 516 } 517 518 for (i = 0; i < MAX_SUPPLIES; i++) { 519 const char *supply_name = iod->soc_data->supply_names[i]; 520 struct rockchip_iodomain_supply *supply = &iod->supplies[i]; 521 struct regulator *reg; 522 int uV; 523 524 if (!supply_name) 525 continue; 526 527 reg = devm_regulator_get_optional(iod->dev, supply_name); 528 if (IS_ERR(reg)) { 529 ret = PTR_ERR(reg); 530 531 /* If a supply wasn't specified, that's OK */ 532 if (ret == -ENODEV) 533 continue; 534 else if (ret != -EPROBE_DEFER) 535 dev_err(iod->dev, "couldn't get regulator %s\n", 536 supply_name); 537 goto unreg_notify; 538 } 539 540 /* set initial correct value */ 541 uV = regulator_get_voltage(reg); 542 543 /* must be a regulator we can get the voltage of */ 544 if (uV < 0) { 545 dev_err(iod->dev, "Can't determine voltage: %s\n", 546 supply_name); 547 ret = uV; 548 goto unreg_notify; 549 } 550 551 if (uV > MAX_VOLTAGE_3_3) { 552 dev_crit(iod->dev, 553 "%d uV is too high. May damage SoC!\n", 554 uV); 555 ret = -EINVAL; 556 goto unreg_notify; 557 } 558 559 /* setup our supply */ 560 supply->idx = i; 561 supply->iod = iod; 562 supply->reg = reg; 563 supply->nb.notifier_call = rockchip_iodomain_notify; 564 565 ret = rockchip_iodomain_write(supply, uV); 566 if (ret) { 567 supply->reg = NULL; 568 goto unreg_notify; 569 } 570 571 /* register regulator notifier */ 572 ret = regulator_register_notifier(reg, &supply->nb); 573 if (ret) { 574 dev_err(&pdev->dev, 575 "regulator notifier request failed\n"); 576 supply->reg = NULL; 577 goto unreg_notify; 578 } 579 } 580 581 if (iod->soc_data->init) 582 iod->soc_data->init(iod); 583 584 return 0; 585 586 unreg_notify: 587 for (i = MAX_SUPPLIES - 1; i >= 0; i--) { 588 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i]; 589 590 if (io_supply->reg) 591 regulator_unregister_notifier(io_supply->reg, 592 &io_supply->nb); 593 } 594 595 return ret; 596 } 597 598 static int rockchip_iodomain_remove(struct platform_device *pdev) 599 { 600 struct rockchip_iodomain *iod = platform_get_drvdata(pdev); 601 int i; 602 603 for (i = MAX_SUPPLIES - 1; i >= 0; i--) { 604 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i]; 605 606 if (io_supply->reg) 607 regulator_unregister_notifier(io_supply->reg, 608 &io_supply->nb); 609 } 610 611 return 0; 612 } 613 614 static struct platform_driver rockchip_iodomain_driver = { 615 .probe = rockchip_iodomain_probe, 616 .remove = rockchip_iodomain_remove, 617 .driver = { 618 .name = "rockchip-iodomain", 619 .of_match_table = rockchip_iodomain_match, 620 }, 621 }; 622 623 module_platform_driver(rockchip_iodomain_driver); 624 625 MODULE_DESCRIPTION("Rockchip IO-domain driver"); 626 MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 627 MODULE_AUTHOR("Doug Anderson <dianders@chromium.org>"); 628 MODULE_LICENSE("GPL v2"); 629