0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) "tegra voltage-coupler: " fmt
0011
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/of.h>
0015 #include <linux/reboot.h>
0016 #include <linux/regulator/coupler.h>
0017 #include <linux/regulator/driver.h>
0018 #include <linux/regulator/machine.h>
0019 #include <linux/suspend.h>
0020
0021 #include <soc/tegra/fuse.h>
0022 #include <soc/tegra/pmc.h>
0023
0024 struct tegra_regulator_coupler {
0025 struct regulator_coupler coupler;
0026 struct regulator_dev *core_rdev;
0027 struct regulator_dev *cpu_rdev;
0028 struct regulator_dev *rtc_rdev;
0029 struct notifier_block reboot_notifier;
0030 struct notifier_block suspend_notifier;
0031 int core_min_uV, cpu_min_uV;
0032 bool sys_reboot_mode_req;
0033 bool sys_reboot_mode;
0034 bool sys_suspend_mode_req;
0035 bool sys_suspend_mode;
0036 };
0037
0038 static inline struct tegra_regulator_coupler *
0039 to_tegra_coupler(struct regulator_coupler *coupler)
0040 {
0041 return container_of(coupler, struct tegra_regulator_coupler, coupler);
0042 }
0043
0044 static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
0045 struct regulator_dev *core_rdev)
0046 {
0047 int core_min_uV = 0;
0048 int core_max_uV;
0049 int core_cur_uV;
0050 int err;
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
0063 pr_info_once("voltage state synced\n");
0064 return 0;
0065 }
0066
0067 if (tegra->core_min_uV > 0)
0068 return tegra->core_min_uV;
0069
0070 core_cur_uV = regulator_get_voltage_rdev(core_rdev);
0071 if (core_cur_uV < 0)
0072 return core_cur_uV;
0073
0074 core_max_uV = max(core_cur_uV, 1200000);
0075
0076 err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
0077 if (err)
0078 return err;
0079
0080
0081
0082
0083
0084
0085 tegra->core_min_uV = core_max_uV;
0086
0087 pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
0088
0089 return tegra->core_min_uV;
0090 }
0091
0092 static int tegra20_core_rtc_max_spread(struct regulator_dev *core_rdev,
0093 struct regulator_dev *rtc_rdev)
0094 {
0095 struct coupling_desc *c_desc = &core_rdev->coupling_desc;
0096 struct regulator_dev *rdev;
0097 int max_spread;
0098 unsigned int i;
0099
0100 for (i = 1; i < c_desc->n_coupled; i++) {
0101 max_spread = core_rdev->constraints->max_spread[i - 1];
0102 rdev = c_desc->coupled_rdevs[i];
0103
0104 if (rdev == rtc_rdev && max_spread)
0105 return max_spread;
0106 }
0107
0108 pr_err_once("rtc-core max-spread is undefined in device-tree\n");
0109
0110 return 150000;
0111 }
0112
0113 static int tegra20_cpu_nominal_uV(void)
0114 {
0115 switch (tegra_sku_info.soc_speedo_id) {
0116 case 0:
0117 return 1100000;
0118 case 1:
0119 return 1025000;
0120 default:
0121 return 1125000;
0122 }
0123 }
0124
0125 static int tegra20_core_nominal_uV(void)
0126 {
0127 switch (tegra_sku_info.soc_speedo_id) {
0128 default:
0129 return 1225000;
0130 case 2:
0131 return 1300000;
0132 }
0133 }
0134
0135 static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
0136 struct regulator_dev *core_rdev,
0137 struct regulator_dev *rtc_rdev,
0138 int cpu_uV, int cpu_min_uV)
0139 {
0140 int core_min_uV, core_max_uV = INT_MAX;
0141 int rtc_min_uV, rtc_max_uV = INT_MAX;
0142 int core_target_uV;
0143 int rtc_target_uV;
0144 int max_spread;
0145 int core_uV;
0146 int rtc_uV;
0147 int err;
0148
0149
0150
0151
0152
0153
0154 max_spread = tegra20_core_rtc_max_spread(core_rdev, rtc_rdev);
0155
0156
0157
0158
0159
0160
0161 core_min_uV = tegra20_core_limit(tegra, core_rdev);
0162 if (core_min_uV < 0)
0163 return core_min_uV;
0164
0165 err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
0166 if (err)
0167 return err;
0168
0169 err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
0170 PM_SUSPEND_ON);
0171 if (err)
0172 return err;
0173
0174
0175 if (tegra->sys_suspend_mode)
0176 core_min_uV = clamp(tegra20_core_nominal_uV(),
0177 core_min_uV, core_max_uV);
0178
0179 core_uV = regulator_get_voltage_rdev(core_rdev);
0180 if (core_uV < 0)
0181 return core_uV;
0182
0183 core_min_uV = max(cpu_min_uV + 125000, core_min_uV);
0184 if (core_min_uV > core_max_uV)
0185 return -EINVAL;
0186
0187 if (cpu_uV + 120000 > core_uV)
0188 pr_err("core-cpu voltage constraint violated: %d %d\n",
0189 core_uV, cpu_uV + 120000);
0190
0191 rtc_uV = regulator_get_voltage_rdev(rtc_rdev);
0192 if (rtc_uV < 0)
0193 return rtc_uV;
0194
0195 if (cpu_uV + 120000 > rtc_uV)
0196 pr_err("rtc-cpu voltage constraint violated: %d %d\n",
0197 rtc_uV, cpu_uV + 120000);
0198
0199 if (abs(core_uV - rtc_uV) > 170000)
0200 pr_err("core-rtc voltage constraint violated: %d %d\n",
0201 core_uV, rtc_uV);
0202
0203 rtc_min_uV = max(cpu_min_uV + 125000, core_min_uV - max_spread);
0204
0205 err = regulator_check_voltage(rtc_rdev, &rtc_min_uV, &rtc_max_uV);
0206 if (err)
0207 return err;
0208
0209 while (core_uV != core_min_uV || rtc_uV != rtc_min_uV) {
0210 if (core_uV < core_min_uV) {
0211 core_target_uV = min(core_uV + max_spread, core_min_uV);
0212 core_target_uV = min(rtc_uV + max_spread, core_target_uV);
0213 } else {
0214 core_target_uV = max(core_uV - max_spread, core_min_uV);
0215 core_target_uV = max(rtc_uV - max_spread, core_target_uV);
0216 }
0217
0218 if (core_uV == core_target_uV)
0219 goto update_rtc;
0220
0221 err = regulator_set_voltage_rdev(core_rdev,
0222 core_target_uV,
0223 core_max_uV,
0224 PM_SUSPEND_ON);
0225 if (err)
0226 return err;
0227
0228 core_uV = core_target_uV;
0229 update_rtc:
0230 if (rtc_uV < rtc_min_uV) {
0231 rtc_target_uV = min(rtc_uV + max_spread, rtc_min_uV);
0232 rtc_target_uV = min(core_uV + max_spread, rtc_target_uV);
0233 } else {
0234 rtc_target_uV = max(rtc_uV - max_spread, rtc_min_uV);
0235 rtc_target_uV = max(core_uV - max_spread, rtc_target_uV);
0236 }
0237
0238 if (rtc_uV == rtc_target_uV)
0239 continue;
0240
0241 err = regulator_set_voltage_rdev(rtc_rdev,
0242 rtc_target_uV,
0243 rtc_max_uV,
0244 PM_SUSPEND_ON);
0245 if (err)
0246 return err;
0247
0248 rtc_uV = rtc_target_uV;
0249 }
0250
0251 return 0;
0252 }
0253
0254 static int tegra20_core_voltage_update(struct tegra_regulator_coupler *tegra,
0255 struct regulator_dev *cpu_rdev,
0256 struct regulator_dev *core_rdev,
0257 struct regulator_dev *rtc_rdev)
0258 {
0259 int cpu_uV;
0260
0261 cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
0262 if (cpu_uV < 0)
0263 return cpu_uV;
0264
0265 return tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
0266 cpu_uV, cpu_uV);
0267 }
0268
0269 static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
0270 struct regulator_dev *cpu_rdev,
0271 struct regulator_dev *core_rdev,
0272 struct regulator_dev *rtc_rdev)
0273 {
0274 int cpu_min_uV_consumers = 0;
0275 int cpu_max_uV = INT_MAX;
0276 int cpu_min_uV = 0;
0277 int cpu_uV;
0278 int err;
0279
0280 err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
0281 if (err)
0282 return err;
0283
0284 err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
0285 PM_SUSPEND_ON);
0286 if (err)
0287 return err;
0288
0289 err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
0290 &cpu_max_uV, PM_SUSPEND_ON);
0291 if (err)
0292 return err;
0293
0294 cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
0295 if (cpu_uV < 0)
0296 return cpu_uV;
0297
0298
0299 if (!tegra->cpu_min_uV)
0300 tegra->cpu_min_uV = cpu_uV;
0301
0302
0303
0304
0305
0306
0307 if (!cpu_min_uV_consumers)
0308 cpu_min_uV = cpu_uV;
0309
0310
0311 if (tegra->sys_reboot_mode)
0312 cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
0313
0314
0315 if (tegra->sys_suspend_mode)
0316 cpu_min_uV = clamp(tegra20_cpu_nominal_uV(),
0317 cpu_min_uV, cpu_max_uV);
0318
0319 if (cpu_min_uV > cpu_uV) {
0320 err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
0321 cpu_uV, cpu_min_uV);
0322 if (err)
0323 return err;
0324
0325 err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
0326 cpu_max_uV, PM_SUSPEND_ON);
0327 if (err)
0328 return err;
0329 } else if (cpu_min_uV < cpu_uV) {
0330 err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
0331 cpu_max_uV, PM_SUSPEND_ON);
0332 if (err)
0333 return err;
0334
0335 err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
0336 cpu_uV, cpu_min_uV);
0337 if (err)
0338 return err;
0339 }
0340
0341 return 0;
0342 }
0343
0344 static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
0345 struct regulator_dev *rdev,
0346 suspend_state_t state)
0347 {
0348 struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
0349 struct regulator_dev *core_rdev = tegra->core_rdev;
0350 struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
0351 struct regulator_dev *rtc_rdev = tegra->rtc_rdev;
0352
0353 if ((core_rdev != rdev && cpu_rdev != rdev && rtc_rdev != rdev) ||
0354 state != PM_SUSPEND_ON) {
0355 pr_err("regulators are not coupled properly\n");
0356 return -EINVAL;
0357 }
0358
0359 tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
0360 tegra->sys_suspend_mode = READ_ONCE(tegra->sys_suspend_mode_req);
0361
0362 if (rdev == cpu_rdev)
0363 return tegra20_cpu_voltage_update(tegra, cpu_rdev,
0364 core_rdev, rtc_rdev);
0365
0366 if (rdev == core_rdev)
0367 return tegra20_core_voltage_update(tegra, cpu_rdev,
0368 core_rdev, rtc_rdev);
0369
0370 pr_err("changing %s voltage not permitted\n", rdev_get_name(rtc_rdev));
0371
0372 return -EPERM;
0373 }
0374
0375 static int tegra20_regulator_prepare_suspend(struct tegra_regulator_coupler *tegra,
0376 bool sys_suspend_mode)
0377 {
0378 int err;
0379
0380 if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev)
0381 return 0;
0382
0383
0384
0385
0386
0387
0388
0389
0390 WRITE_ONCE(tegra->sys_suspend_mode_req, sys_suspend_mode);
0391
0392 err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
0393 if (err)
0394 return err;
0395
0396 err = regulator_sync_voltage_rdev(tegra->core_rdev);
0397 if (err)
0398 return err;
0399
0400 return 0;
0401 }
0402
0403 static int tegra20_regulator_suspend(struct notifier_block *notifier,
0404 unsigned long mode, void *arg)
0405 {
0406 struct tegra_regulator_coupler *tegra;
0407 int ret = 0;
0408
0409 tegra = container_of(notifier, struct tegra_regulator_coupler,
0410 suspend_notifier);
0411
0412 switch (mode) {
0413 case PM_HIBERNATION_PREPARE:
0414 case PM_RESTORE_PREPARE:
0415 case PM_SUSPEND_PREPARE:
0416 ret = tegra20_regulator_prepare_suspend(tegra, true);
0417 break;
0418
0419 case PM_POST_HIBERNATION:
0420 case PM_POST_RESTORE:
0421 case PM_POST_SUSPEND:
0422 ret = tegra20_regulator_prepare_suspend(tegra, false);
0423 break;
0424 }
0425
0426 if (ret)
0427 pr_err("failed to prepare regulators: %d\n", ret);
0428
0429 return notifier_from_errno(ret);
0430 }
0431
0432 static int tegra20_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
0433 bool sys_reboot_mode)
0434 {
0435 int err;
0436
0437 if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev)
0438 return 0;
0439
0440 WRITE_ONCE(tegra->sys_reboot_mode_req, true);
0441
0442
0443
0444
0445
0446
0447 err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
0448 if (err)
0449 return err;
0450
0451 err = regulator_sync_voltage_rdev(tegra->core_rdev);
0452 if (err)
0453 return err;
0454
0455 WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode);
0456
0457 return 0;
0458 }
0459
0460 static int tegra20_regulator_reboot(struct notifier_block *notifier,
0461 unsigned long event, void *cmd)
0462 {
0463 struct tegra_regulator_coupler *tegra;
0464 int ret;
0465
0466 if (event != SYS_RESTART)
0467 return NOTIFY_DONE;
0468
0469 tegra = container_of(notifier, struct tegra_regulator_coupler,
0470 reboot_notifier);
0471
0472 ret = tegra20_regulator_prepare_reboot(tegra, true);
0473
0474 return notifier_from_errno(ret);
0475 }
0476
0477 static int tegra20_regulator_attach(struct regulator_coupler *coupler,
0478 struct regulator_dev *rdev)
0479 {
0480 struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
0481 struct device_node *np = rdev->dev.of_node;
0482
0483 if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
0484 !tegra->core_rdev) {
0485 tegra->core_rdev = rdev;
0486 return 0;
0487 }
0488
0489 if (of_property_read_bool(np, "nvidia,tegra-rtc-regulator") &&
0490 !tegra->rtc_rdev) {
0491 tegra->rtc_rdev = rdev;
0492 return 0;
0493 }
0494
0495 if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
0496 !tegra->cpu_rdev) {
0497 tegra->cpu_rdev = rdev;
0498 return 0;
0499 }
0500
0501 return -EINVAL;
0502 }
0503
0504 static int tegra20_regulator_detach(struct regulator_coupler *coupler,
0505 struct regulator_dev *rdev)
0506 {
0507 struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
0508
0509
0510
0511
0512
0513
0514 if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING))
0515 return -EPERM;
0516
0517 if (tegra->core_rdev == rdev) {
0518 tegra->core_rdev = NULL;
0519 return 0;
0520 }
0521
0522 if (tegra->rtc_rdev == rdev) {
0523 tegra->rtc_rdev = NULL;
0524 return 0;
0525 }
0526
0527 if (tegra->cpu_rdev == rdev) {
0528 tegra->cpu_rdev = NULL;
0529 return 0;
0530 }
0531
0532 return -EINVAL;
0533 }
0534
0535 static struct tegra_regulator_coupler tegra20_coupler = {
0536 .coupler = {
0537 .attach_regulator = tegra20_regulator_attach,
0538 .detach_regulator = tegra20_regulator_detach,
0539 .balance_voltage = tegra20_regulator_balance_voltage,
0540 },
0541 .reboot_notifier.notifier_call = tegra20_regulator_reboot,
0542 .suspend_notifier.notifier_call = tegra20_regulator_suspend,
0543 };
0544
0545 static int __init tegra_regulator_coupler_init(void)
0546 {
0547 int err;
0548
0549 if (!of_machine_is_compatible("nvidia,tegra20"))
0550 return 0;
0551
0552 err = register_reboot_notifier(&tegra20_coupler.reboot_notifier);
0553 WARN_ON(err);
0554
0555 err = register_pm_notifier(&tegra20_coupler.suspend_notifier);
0556 WARN_ON(err);
0557
0558 return regulator_coupler_register(&tegra20_coupler.coupler);
0559 }
0560 arch_initcall(tegra_regulator_coupler_init);