1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Voltage regulators coupler for NVIDIA Tegra20 4 * Copyright (C) 2019 GRATE-DRIVER project 5 * 6 * Voltage constraints borrowed from downstream kernel sources 7 * Copyright (C) 2010-2011 NVIDIA Corporation 8 */ 9 10 #define pr_fmt(fmt) "tegra voltage-coupler: " fmt 11 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/of.h> 15 #include <linux/regulator/coupler.h> 16 #include <linux/regulator/driver.h> 17 #include <linux/regulator/machine.h> 18 19 struct tegra_regulator_coupler { 20 struct regulator_coupler coupler; 21 struct regulator_dev *core_rdev; 22 struct regulator_dev *cpu_rdev; 23 struct regulator_dev *rtc_rdev; 24 int core_min_uV; 25 }; 26 27 static inline struct tegra_regulator_coupler * 28 to_tegra_coupler(struct regulator_coupler *coupler) 29 { 30 return container_of(coupler, struct tegra_regulator_coupler, coupler); 31 } 32 33 static int tegra20_core_limit(struct tegra_regulator_coupler *tegra, 34 struct regulator_dev *core_rdev) 35 { 36 int core_min_uV = 0; 37 int core_max_uV; 38 int core_cur_uV; 39 int err; 40 41 if (tegra->core_min_uV > 0) 42 return tegra->core_min_uV; 43 44 core_cur_uV = regulator_get_voltage_rdev(core_rdev); 45 if (core_cur_uV < 0) 46 return core_cur_uV; 47 48 core_max_uV = max(core_cur_uV, 1200000); 49 50 err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV); 51 if (err) 52 return err; 53 54 /* 55 * Limit minimum CORE voltage to a value left from bootloader or, 56 * if it's unreasonably low value, to the most common 1.2v or to 57 * whatever maximum value defined via board's device-tree. 58 */ 59 tegra->core_min_uV = core_max_uV; 60 61 pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV); 62 63 return tegra->core_min_uV; 64 } 65 66 static int tegra20_core_rtc_max_spread(struct regulator_dev *core_rdev, 67 struct regulator_dev *rtc_rdev) 68 { 69 struct coupling_desc *c_desc = &core_rdev->coupling_desc; 70 struct regulator_dev *rdev; 71 int max_spread; 72 unsigned int i; 73 74 for (i = 1; i < c_desc->n_coupled; i++) { 75 max_spread = core_rdev->constraints->max_spread[i - 1]; 76 rdev = c_desc->coupled_rdevs[i]; 77 78 if (rdev == rtc_rdev && max_spread) 79 return max_spread; 80 } 81 82 pr_err_once("rtc-core max-spread is undefined in device-tree\n"); 83 84 return 150000; 85 } 86 87 static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra, 88 struct regulator_dev *core_rdev, 89 struct regulator_dev *rtc_rdev, 90 int cpu_uV, int cpu_min_uV) 91 { 92 int core_min_uV, core_max_uV = INT_MAX; 93 int rtc_min_uV, rtc_max_uV = INT_MAX; 94 int core_target_uV; 95 int rtc_target_uV; 96 int max_spread; 97 int core_uV; 98 int rtc_uV; 99 int err; 100 101 /* 102 * RTC and CORE voltages should be no more than 170mV from each other, 103 * CPU should be below RTC and CORE by at least 120mV. This applies 104 * to all Tegra20 SoC's. 105 */ 106 max_spread = tegra20_core_rtc_max_spread(core_rdev, rtc_rdev); 107 108 /* 109 * The core voltage scaling is currently not hooked up in drivers, 110 * hence we will limit the minimum core voltage to a reasonable value. 111 * This should be good enough for the time being. 112 */ 113 core_min_uV = tegra20_core_limit(tegra, core_rdev); 114 if (core_min_uV < 0) 115 return core_min_uV; 116 117 err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV); 118 if (err) 119 return err; 120 121 err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV, 122 PM_SUSPEND_ON); 123 if (err) 124 return err; 125 126 core_uV = regulator_get_voltage_rdev(core_rdev); 127 if (core_uV < 0) 128 return core_uV; 129 130 core_min_uV = max(cpu_min_uV + 125000, core_min_uV); 131 if (core_min_uV > core_max_uV) 132 return -EINVAL; 133 134 if (cpu_uV + 120000 > core_uV) 135 pr_err("core-cpu voltage constraint violated: %d %d\n", 136 core_uV, cpu_uV + 120000); 137 138 rtc_uV = regulator_get_voltage_rdev(rtc_rdev); 139 if (rtc_uV < 0) 140 return rtc_uV; 141 142 if (cpu_uV + 120000 > rtc_uV) 143 pr_err("rtc-cpu voltage constraint violated: %d %d\n", 144 rtc_uV, cpu_uV + 120000); 145 146 if (abs(core_uV - rtc_uV) > 170000) 147 pr_err("core-rtc voltage constraint violated: %d %d\n", 148 core_uV, rtc_uV); 149 150 rtc_min_uV = max(cpu_min_uV + 125000, core_min_uV - max_spread); 151 152 err = regulator_check_voltage(rtc_rdev, &rtc_min_uV, &rtc_max_uV); 153 if (err) 154 return err; 155 156 while (core_uV != core_min_uV || rtc_uV != rtc_min_uV) { 157 if (core_uV < core_min_uV) { 158 core_target_uV = min(core_uV + max_spread, core_min_uV); 159 core_target_uV = min(rtc_uV + max_spread, core_target_uV); 160 } else { 161 core_target_uV = max(core_uV - max_spread, core_min_uV); 162 core_target_uV = max(rtc_uV - max_spread, core_target_uV); 163 } 164 165 err = regulator_set_voltage_rdev(core_rdev, 166 core_target_uV, 167 core_max_uV, 168 PM_SUSPEND_ON); 169 if (err) 170 return err; 171 172 core_uV = core_target_uV; 173 174 if (rtc_uV < rtc_min_uV) { 175 rtc_target_uV = min(rtc_uV + max_spread, rtc_min_uV); 176 rtc_target_uV = min(core_uV + max_spread, rtc_target_uV); 177 } else { 178 rtc_target_uV = max(rtc_uV - max_spread, rtc_min_uV); 179 rtc_target_uV = max(core_uV - max_spread, rtc_target_uV); 180 } 181 182 err = regulator_set_voltage_rdev(rtc_rdev, 183 rtc_target_uV, 184 rtc_max_uV, 185 PM_SUSPEND_ON); 186 if (err) 187 return err; 188 189 rtc_uV = rtc_target_uV; 190 } 191 192 return 0; 193 } 194 195 static int tegra20_core_voltage_update(struct tegra_regulator_coupler *tegra, 196 struct regulator_dev *cpu_rdev, 197 struct regulator_dev *core_rdev, 198 struct regulator_dev *rtc_rdev) 199 { 200 int cpu_uV; 201 202 cpu_uV = regulator_get_voltage_rdev(cpu_rdev); 203 if (cpu_uV < 0) 204 return cpu_uV; 205 206 return tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev, 207 cpu_uV, cpu_uV); 208 } 209 210 static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra, 211 struct regulator_dev *cpu_rdev, 212 struct regulator_dev *core_rdev, 213 struct regulator_dev *rtc_rdev) 214 { 215 int cpu_min_uV_consumers = 0; 216 int cpu_max_uV = INT_MAX; 217 int cpu_min_uV = 0; 218 int cpu_uV; 219 int err; 220 221 err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV); 222 if (err) 223 return err; 224 225 err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV, 226 PM_SUSPEND_ON); 227 if (err) 228 return err; 229 230 err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers, 231 &cpu_max_uV, PM_SUSPEND_ON); 232 if (err) 233 return err; 234 235 cpu_uV = regulator_get_voltage_rdev(cpu_rdev); 236 if (cpu_uV < 0) 237 return cpu_uV; 238 239 /* 240 * CPU's regulator may not have any consumers, hence the voltage 241 * must not be changed in that case because CPU simply won't 242 * survive the voltage drop if it's running on a higher frequency. 243 */ 244 if (!cpu_min_uV_consumers) 245 cpu_min_uV = cpu_uV; 246 247 if (cpu_min_uV > cpu_uV) { 248 err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev, 249 cpu_uV, cpu_min_uV); 250 if (err) 251 return err; 252 253 err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV, 254 cpu_max_uV, PM_SUSPEND_ON); 255 if (err) 256 return err; 257 } else if (cpu_min_uV < cpu_uV) { 258 err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV, 259 cpu_max_uV, PM_SUSPEND_ON); 260 if (err) 261 return err; 262 263 err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev, 264 cpu_uV, cpu_min_uV); 265 if (err) 266 return err; 267 } 268 269 return 0; 270 } 271 272 static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler, 273 struct regulator_dev *rdev, 274 suspend_state_t state) 275 { 276 struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); 277 struct regulator_dev *core_rdev = tegra->core_rdev; 278 struct regulator_dev *cpu_rdev = tegra->cpu_rdev; 279 struct regulator_dev *rtc_rdev = tegra->rtc_rdev; 280 281 if ((core_rdev != rdev && cpu_rdev != rdev && rtc_rdev != rdev) || 282 state != PM_SUSPEND_ON) { 283 pr_err("regulators are not coupled properly\n"); 284 return -EINVAL; 285 } 286 287 if (rdev == cpu_rdev) 288 return tegra20_cpu_voltage_update(tegra, cpu_rdev, 289 core_rdev, rtc_rdev); 290 291 if (rdev == core_rdev) 292 return tegra20_core_voltage_update(tegra, cpu_rdev, 293 core_rdev, rtc_rdev); 294 295 pr_err("changing %s voltage not permitted\n", rdev_get_name(rtc_rdev)); 296 297 return -EPERM; 298 } 299 300 static int tegra20_regulator_attach(struct regulator_coupler *coupler, 301 struct regulator_dev *rdev) 302 { 303 struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); 304 struct device_node *np = rdev->dev.of_node; 305 306 if (of_property_read_bool(np, "nvidia,tegra-core-regulator") && 307 !tegra->core_rdev) { 308 tegra->core_rdev = rdev; 309 return 0; 310 } 311 312 if (of_property_read_bool(np, "nvidia,tegra-rtc-regulator") && 313 !tegra->rtc_rdev) { 314 tegra->rtc_rdev = rdev; 315 return 0; 316 } 317 318 if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") && 319 !tegra->cpu_rdev) { 320 tegra->cpu_rdev = rdev; 321 return 0; 322 } 323 324 return -EINVAL; 325 } 326 327 static int tegra20_regulator_detach(struct regulator_coupler *coupler, 328 struct regulator_dev *rdev) 329 { 330 struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); 331 332 if (tegra->core_rdev == rdev) { 333 tegra->core_rdev = NULL; 334 return 0; 335 } 336 337 if (tegra->rtc_rdev == rdev) { 338 tegra->rtc_rdev = NULL; 339 return 0; 340 } 341 342 if (tegra->cpu_rdev == rdev) { 343 tegra->cpu_rdev = NULL; 344 return 0; 345 } 346 347 return -EINVAL; 348 } 349 350 static struct tegra_regulator_coupler tegra20_coupler = { 351 .coupler = { 352 .attach_regulator = tegra20_regulator_attach, 353 .detach_regulator = tegra20_regulator_detach, 354 .balance_voltage = tegra20_regulator_balance_voltage, 355 }, 356 }; 357 358 static int __init tegra_regulator_coupler_init(void) 359 { 360 if (!of_machine_is_compatible("nvidia,tegra20")) 361 return 0; 362 363 return regulator_coupler_register(&tegra20_coupler.coupler); 364 } 365 arch_initcall(tegra_regulator_coupler_init); 366