1 // SPDX-License-Identifier: GPL-2.0+
3 * Voltage regulators coupler for NVIDIA Tegra20
4 * Copyright (C) 2019 GRATE-DRIVER project
6 * Voltage constraints borrowed from downstream kernel sources
7 * Copyright (C) 2010-2011 NVIDIA Corporation
10 #define pr_fmt(fmt) "tegra voltage-coupler: " fmt
12 #include <linux/init.h>
13 #include <linux/kernel.h>
15 #include <linux/regulator/coupler.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/regulator/machine.h>
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
;
27 static inline struct tegra_regulator_coupler
*
28 to_tegra_coupler(struct regulator_coupler
*coupler
)
30 return container_of(coupler
, struct tegra_regulator_coupler
, coupler
);
33 static int tegra20_core_limit(struct tegra_regulator_coupler
*tegra
,
34 struct regulator_dev
*core_rdev
)
41 if (tegra
->core_min_uV
> 0)
42 return tegra
->core_min_uV
;
44 core_cur_uV
= regulator_get_voltage_rdev(core_rdev
);
48 core_max_uV
= max(core_cur_uV
, 1200000);
50 err
= regulator_check_voltage(core_rdev
, &core_min_uV
, &core_max_uV
);
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.
59 tegra
->core_min_uV
= core_max_uV
;
61 pr_info("core minimum voltage limited to %duV\n", tegra
->core_min_uV
);
63 return tegra
->core_min_uV
;
66 static int tegra20_core_rtc_max_spread(struct regulator_dev
*core_rdev
,
67 struct regulator_dev
*rtc_rdev
)
69 struct coupling_desc
*c_desc
= &core_rdev
->coupling_desc
;
70 struct regulator_dev
*rdev
;
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
];
78 if (rdev
== rtc_rdev
&& max_spread
)
82 pr_err_once("rtc-core max-spread is undefined in device-tree\n");
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
)
92 int core_min_uV
, core_max_uV
= INT_MAX
;
93 int rtc_min_uV
, rtc_max_uV
= INT_MAX
;
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.
106 max_spread
= tegra20_core_rtc_max_spread(core_rdev
, rtc_rdev
);
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.
113 core_min_uV
= tegra20_core_limit(tegra
, core_rdev
);
117 err
= regulator_check_voltage(core_rdev
, &core_min_uV
, &core_max_uV
);
121 err
= regulator_check_consumers(core_rdev
, &core_min_uV
, &core_max_uV
,
126 core_uV
= regulator_get_voltage_rdev(core_rdev
);
130 core_min_uV
= max(cpu_min_uV
+ 125000, core_min_uV
);
131 if (core_min_uV
> core_max_uV
)
134 if (cpu_uV
+ 120000 > core_uV
)
135 pr_err("core-cpu voltage constraint violated: %d %d\n",
136 core_uV
, cpu_uV
+ 120000);
138 rtc_uV
= regulator_get_voltage_rdev(rtc_rdev
);
142 if (cpu_uV
+ 120000 > rtc_uV
)
143 pr_err("rtc-cpu voltage constraint violated: %d %d\n",
144 rtc_uV
, cpu_uV
+ 120000);
146 if (abs(core_uV
- rtc_uV
) > 170000)
147 pr_err("core-rtc voltage constraint violated: %d %d\n",
150 rtc_min_uV
= max(cpu_min_uV
+ 125000, core_min_uV
- max_spread
);
152 err
= regulator_check_voltage(rtc_rdev
, &rtc_min_uV
, &rtc_max_uV
);
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
);
161 core_target_uV
= max(core_uV
- max_spread
, core_min_uV
);
162 core_target_uV
= max(rtc_uV
- max_spread
, core_target_uV
);
165 if (core_uV
== core_target_uV
)
168 err
= regulator_set_voltage_rdev(core_rdev
,
175 core_uV
= core_target_uV
;
177 if (rtc_uV
< rtc_min_uV
) {
178 rtc_target_uV
= min(rtc_uV
+ max_spread
, rtc_min_uV
);
179 rtc_target_uV
= min(core_uV
+ max_spread
, rtc_target_uV
);
181 rtc_target_uV
= max(rtc_uV
- max_spread
, rtc_min_uV
);
182 rtc_target_uV
= max(core_uV
- max_spread
, rtc_target_uV
);
185 if (rtc_uV
== rtc_target_uV
)
188 err
= regulator_set_voltage_rdev(rtc_rdev
,
195 rtc_uV
= rtc_target_uV
;
201 static int tegra20_core_voltage_update(struct tegra_regulator_coupler
*tegra
,
202 struct regulator_dev
*cpu_rdev
,
203 struct regulator_dev
*core_rdev
,
204 struct regulator_dev
*rtc_rdev
)
208 cpu_uV
= regulator_get_voltage_rdev(cpu_rdev
);
212 return tegra20_core_rtc_update(tegra
, core_rdev
, rtc_rdev
,
216 static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler
*tegra
,
217 struct regulator_dev
*cpu_rdev
,
218 struct regulator_dev
*core_rdev
,
219 struct regulator_dev
*rtc_rdev
)
221 int cpu_min_uV_consumers
= 0;
222 int cpu_max_uV
= INT_MAX
;
227 err
= regulator_check_voltage(cpu_rdev
, &cpu_min_uV
, &cpu_max_uV
);
231 err
= regulator_check_consumers(cpu_rdev
, &cpu_min_uV
, &cpu_max_uV
,
236 err
= regulator_check_consumers(cpu_rdev
, &cpu_min_uV_consumers
,
237 &cpu_max_uV
, PM_SUSPEND_ON
);
241 cpu_uV
= regulator_get_voltage_rdev(cpu_rdev
);
246 * CPU's regulator may not have any consumers, hence the voltage
247 * must not be changed in that case because CPU simply won't
248 * survive the voltage drop if it's running on a higher frequency.
250 if (!cpu_min_uV_consumers
)
253 if (cpu_min_uV
> cpu_uV
) {
254 err
= tegra20_core_rtc_update(tegra
, core_rdev
, rtc_rdev
,
259 err
= regulator_set_voltage_rdev(cpu_rdev
, cpu_min_uV
,
260 cpu_max_uV
, PM_SUSPEND_ON
);
263 } else if (cpu_min_uV
< cpu_uV
) {
264 err
= regulator_set_voltage_rdev(cpu_rdev
, cpu_min_uV
,
265 cpu_max_uV
, PM_SUSPEND_ON
);
269 err
= tegra20_core_rtc_update(tegra
, core_rdev
, rtc_rdev
,
278 static int tegra20_regulator_balance_voltage(struct regulator_coupler
*coupler
,
279 struct regulator_dev
*rdev
,
280 suspend_state_t state
)
282 struct tegra_regulator_coupler
*tegra
= to_tegra_coupler(coupler
);
283 struct regulator_dev
*core_rdev
= tegra
->core_rdev
;
284 struct regulator_dev
*cpu_rdev
= tegra
->cpu_rdev
;
285 struct regulator_dev
*rtc_rdev
= tegra
->rtc_rdev
;
287 if ((core_rdev
!= rdev
&& cpu_rdev
!= rdev
&& rtc_rdev
!= rdev
) ||
288 state
!= PM_SUSPEND_ON
) {
289 pr_err("regulators are not coupled properly\n");
293 if (rdev
== cpu_rdev
)
294 return tegra20_cpu_voltage_update(tegra
, cpu_rdev
,
295 core_rdev
, rtc_rdev
);
297 if (rdev
== core_rdev
)
298 return tegra20_core_voltage_update(tegra
, cpu_rdev
,
299 core_rdev
, rtc_rdev
);
301 pr_err("changing %s voltage not permitted\n", rdev_get_name(rtc_rdev
));
306 static int tegra20_regulator_attach(struct regulator_coupler
*coupler
,
307 struct regulator_dev
*rdev
)
309 struct tegra_regulator_coupler
*tegra
= to_tegra_coupler(coupler
);
310 struct device_node
*np
= rdev
->dev
.of_node
;
312 if (of_property_read_bool(np
, "nvidia,tegra-core-regulator") &&
314 tegra
->core_rdev
= rdev
;
318 if (of_property_read_bool(np
, "nvidia,tegra-rtc-regulator") &&
320 tegra
->rtc_rdev
= rdev
;
324 if (of_property_read_bool(np
, "nvidia,tegra-cpu-regulator") &&
326 tegra
->cpu_rdev
= rdev
;
333 static int tegra20_regulator_detach(struct regulator_coupler
*coupler
,
334 struct regulator_dev
*rdev
)
336 struct tegra_regulator_coupler
*tegra
= to_tegra_coupler(coupler
);
338 if (tegra
->core_rdev
== rdev
) {
339 tegra
->core_rdev
= NULL
;
343 if (tegra
->rtc_rdev
== rdev
) {
344 tegra
->rtc_rdev
= NULL
;
348 if (tegra
->cpu_rdev
== rdev
) {
349 tegra
->cpu_rdev
= NULL
;
356 static struct tegra_regulator_coupler tegra20_coupler
= {
358 .attach_regulator
= tegra20_regulator_attach
,
359 .detach_regulator
= tegra20_regulator_detach
,
360 .balance_voltage
= tegra20_regulator_balance_voltage
,
364 static int __init
tegra_regulator_coupler_init(void)
366 if (!of_machine_is_compatible("nvidia,tegra20"))
369 return regulator_coupler_register(&tegra20_coupler
.coupler
);
371 arch_initcall(tegra_regulator_coupler_init
);