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