1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2015 Linaro Ltd.
4 * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
5 */
6
7 #include <linux/clk.h>
8 #include <linux/cpu.h>
9 #include <linux/cpufreq.h>
10 #include <linux/cpumask.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_opp.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/slab.h>
17 #include <linux/thermal.h>
18
19 #define MIN_VOLT_SHIFT (100000)
20 #define MAX_VOLT_SHIFT (200000)
21 #define MAX_VOLT_LIMIT (1150000)
22 #define VOLT_TOL (10000)
23
24 /*
25 * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS
26 * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
27 * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two
28 * voltage inputs need to be controlled under a hardware limitation:
29 * 100mV < Vsram - Vproc < 200mV
30 *
31 * When scaling the clock frequency of a CPU clock domain, the clock source
32 * needs to be switched to another stable PLL clock temporarily until
33 * the original PLL becomes stable at target frequency.
34 */
35 struct mtk_cpu_dvfs_info {
36 struct cpumask cpus;
37 struct device *cpu_dev;
38 struct regulator *proc_reg;
39 struct regulator *sram_reg;
40 struct clk *cpu_clk;
41 struct clk *inter_clk;
42 struct list_head list_head;
43 int intermediate_voltage;
44 bool need_voltage_tracking;
45 };
46
47 static struct platform_device *cpufreq_pdev;
48
49 static LIST_HEAD(dvfs_info_list);
50
mtk_cpu_dvfs_info_lookup(int cpu)51 static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu)
52 {
53 struct mtk_cpu_dvfs_info *info;
54
55 list_for_each_entry(info, &dvfs_info_list, list_head) {
56 if (cpumask_test_cpu(cpu, &info->cpus))
57 return info;
58 }
59
60 return NULL;
61 }
62
mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info * info,int new_vproc)63 static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
64 int new_vproc)
65 {
66 struct regulator *proc_reg = info->proc_reg;
67 struct regulator *sram_reg = info->sram_reg;
68 int old_vproc, old_vsram, new_vsram, vsram, vproc, ret;
69
70 old_vproc = regulator_get_voltage(proc_reg);
71 if (old_vproc < 0) {
72 pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
73 return old_vproc;
74 }
75 /* Vsram should not exceed the maximum allowed voltage of SoC. */
76 new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT);
77
78 if (old_vproc < new_vproc) {
79 /*
80 * When scaling up voltages, Vsram and Vproc scale up step
81 * by step. At each step, set Vsram to (Vproc + 200mV) first,
82 * then set Vproc to (Vsram - 100mV).
83 * Keep doing it until Vsram and Vproc hit target voltages.
84 */
85 do {
86 old_vsram = regulator_get_voltage(sram_reg);
87 if (old_vsram < 0) {
88 pr_err("%s: invalid Vsram value: %d\n",
89 __func__, old_vsram);
90 return old_vsram;
91 }
92 old_vproc = regulator_get_voltage(proc_reg);
93 if (old_vproc < 0) {
94 pr_err("%s: invalid Vproc value: %d\n",
95 __func__, old_vproc);
96 return old_vproc;
97 }
98
99 vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT);
100
101 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
102 vsram = MAX_VOLT_LIMIT;
103
104 /*
105 * If the target Vsram hits the maximum voltage,
106 * try to set the exact voltage value first.
107 */
108 ret = regulator_set_voltage(sram_reg, vsram,
109 vsram);
110 if (ret)
111 ret = regulator_set_voltage(sram_reg,
112 vsram - VOLT_TOL,
113 vsram);
114
115 vproc = new_vproc;
116 } else {
117 ret = regulator_set_voltage(sram_reg, vsram,
118 vsram + VOLT_TOL);
119
120 vproc = vsram - MIN_VOLT_SHIFT;
121 }
122 if (ret)
123 return ret;
124
125 ret = regulator_set_voltage(proc_reg, vproc,
126 vproc + VOLT_TOL);
127 if (ret) {
128 regulator_set_voltage(sram_reg, old_vsram,
129 old_vsram);
130 return ret;
131 }
132 } while (vproc < new_vproc || vsram < new_vsram);
133 } else if (old_vproc > new_vproc) {
134 /*
135 * When scaling down voltages, Vsram and Vproc scale down step
136 * by step. At each step, set Vproc to (Vsram - 200mV) first,
137 * then set Vproc to (Vproc + 100mV).
138 * Keep doing it until Vsram and Vproc hit target voltages.
139 */
140 do {
141 old_vproc = regulator_get_voltage(proc_reg);
142 if (old_vproc < 0) {
143 pr_err("%s: invalid Vproc value: %d\n",
144 __func__, old_vproc);
145 return old_vproc;
146 }
147 old_vsram = regulator_get_voltage(sram_reg);
148 if (old_vsram < 0) {
149 pr_err("%s: invalid Vsram value: %d\n",
150 __func__, old_vsram);
151 return old_vsram;
152 }
153
154 vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT);
155 ret = regulator_set_voltage(proc_reg, vproc,
156 vproc + VOLT_TOL);
157 if (ret)
158 return ret;
159
160 if (vproc == new_vproc)
161 vsram = new_vsram;
162 else
163 vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT);
164
165 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
166 vsram = MAX_VOLT_LIMIT;
167
168 /*
169 * If the target Vsram hits the maximum voltage,
170 * try to set the exact voltage value first.
171 */
172 ret = regulator_set_voltage(sram_reg, vsram,
173 vsram);
174 if (ret)
175 ret = regulator_set_voltage(sram_reg,
176 vsram - VOLT_TOL,
177 vsram);
178 } else {
179 ret = regulator_set_voltage(sram_reg, vsram,
180 vsram + VOLT_TOL);
181 }
182
183 if (ret) {
184 regulator_set_voltage(proc_reg, old_vproc,
185 old_vproc);
186 return ret;
187 }
188 } while (vproc > new_vproc + VOLT_TOL ||
189 vsram > new_vsram + VOLT_TOL);
190 }
191
192 return 0;
193 }
194
mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info * info,int vproc)195 static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
196 {
197 if (info->need_voltage_tracking)
198 return mtk_cpufreq_voltage_tracking(info, vproc);
199 else
200 return regulator_set_voltage(info->proc_reg, vproc,
201 vproc + VOLT_TOL);
202 }
203
mtk_cpufreq_set_target(struct cpufreq_policy * policy,unsigned int index)204 static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
205 unsigned int index)
206 {
207 struct cpufreq_frequency_table *freq_table = policy->freq_table;
208 struct clk *cpu_clk = policy->clk;
209 struct clk *armpll = clk_get_parent(cpu_clk);
210 struct mtk_cpu_dvfs_info *info = policy->driver_data;
211 struct device *cpu_dev = info->cpu_dev;
212 struct dev_pm_opp *opp;
213 long freq_hz, old_freq_hz;
214 int vproc, old_vproc, inter_vproc, target_vproc, ret;
215
216 inter_vproc = info->intermediate_voltage;
217
218 old_freq_hz = clk_get_rate(cpu_clk);
219 old_vproc = regulator_get_voltage(info->proc_reg);
220 if (old_vproc < 0) {
221 pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
222 return old_vproc;
223 }
224
225 freq_hz = freq_table[index].frequency * 1000;
226
227 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
228 if (IS_ERR(opp)) {
229 pr_err("cpu%d: failed to find OPP for %ld\n",
230 policy->cpu, freq_hz);
231 return PTR_ERR(opp);
232 }
233 vproc = dev_pm_opp_get_voltage(opp);
234 dev_pm_opp_put(opp);
235
236 /*
237 * If the new voltage or the intermediate voltage is higher than the
238 * current voltage, scale up voltage first.
239 */
240 target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
241 if (old_vproc < target_vproc) {
242 ret = mtk_cpufreq_set_voltage(info, target_vproc);
243 if (ret) {
244 pr_err("cpu%d: failed to scale up voltage!\n",
245 policy->cpu);
246 mtk_cpufreq_set_voltage(info, old_vproc);
247 return ret;
248 }
249 }
250
251 /* Reparent the CPU clock to intermediate clock. */
252 ret = clk_set_parent(cpu_clk, info->inter_clk);
253 if (ret) {
254 pr_err("cpu%d: failed to re-parent cpu clock!\n",
255 policy->cpu);
256 mtk_cpufreq_set_voltage(info, old_vproc);
257 WARN_ON(1);
258 return ret;
259 }
260
261 /* Set the original PLL to target rate. */
262 ret = clk_set_rate(armpll, freq_hz);
263 if (ret) {
264 pr_err("cpu%d: failed to scale cpu clock rate!\n",
265 policy->cpu);
266 clk_set_parent(cpu_clk, armpll);
267 mtk_cpufreq_set_voltage(info, old_vproc);
268 return ret;
269 }
270
271 /* Set parent of CPU clock back to the original PLL. */
272 ret = clk_set_parent(cpu_clk, armpll);
273 if (ret) {
274 pr_err("cpu%d: failed to re-parent cpu clock!\n",
275 policy->cpu);
276 mtk_cpufreq_set_voltage(info, inter_vproc);
277 WARN_ON(1);
278 return ret;
279 }
280
281 /*
282 * If the new voltage is lower than the intermediate voltage or the
283 * original voltage, scale down to the new voltage.
284 */
285 if (vproc < inter_vproc || vproc < old_vproc) {
286 ret = mtk_cpufreq_set_voltage(info, vproc);
287 if (ret) {
288 pr_err("cpu%d: failed to scale down voltage!\n",
289 policy->cpu);
290 clk_set_parent(cpu_clk, info->inter_clk);
291 clk_set_rate(armpll, old_freq_hz);
292 clk_set_parent(cpu_clk, armpll);
293 return ret;
294 }
295 }
296
297 return 0;
298 }
299
300 #define DYNAMIC_POWER "dynamic-power-coefficient"
301
mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info * info,int cpu)302 static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
303 {
304 struct device *cpu_dev;
305 struct regulator *proc_reg = ERR_PTR(-ENODEV);
306 struct regulator *sram_reg = ERR_PTR(-ENODEV);
307 struct clk *cpu_clk = ERR_PTR(-ENODEV);
308 struct clk *inter_clk = ERR_PTR(-ENODEV);
309 struct dev_pm_opp *opp;
310 unsigned long rate;
311 int ret;
312
313 cpu_dev = get_cpu_device(cpu);
314 if (!cpu_dev) {
315 pr_err("failed to get cpu%d device\n", cpu);
316 return -ENODEV;
317 }
318
319 cpu_clk = clk_get(cpu_dev, "cpu");
320 if (IS_ERR(cpu_clk)) {
321 if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
322 pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
323 else
324 pr_err("failed to get cpu clk for cpu%d\n", cpu);
325
326 ret = PTR_ERR(cpu_clk);
327 return ret;
328 }
329
330 inter_clk = clk_get(cpu_dev, "intermediate");
331 if (IS_ERR(inter_clk)) {
332 if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
333 pr_warn("intermediate clk for cpu%d not ready, retry.\n",
334 cpu);
335 else
336 pr_err("failed to get intermediate clk for cpu%d\n",
337 cpu);
338
339 ret = PTR_ERR(inter_clk);
340 goto out_free_resources;
341 }
342
343 proc_reg = regulator_get_optional(cpu_dev, "proc");
344 if (IS_ERR(proc_reg)) {
345 if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
346 pr_warn("proc regulator for cpu%d not ready, retry.\n",
347 cpu);
348 else
349 pr_err("failed to get proc regulator for cpu%d\n",
350 cpu);
351
352 ret = PTR_ERR(proc_reg);
353 goto out_free_resources;
354 }
355
356 /* Both presence and absence of sram regulator are valid cases. */
357 sram_reg = regulator_get_exclusive(cpu_dev, "sram");
358
359 /* Get OPP-sharing information from "operating-points-v2" bindings */
360 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus);
361 if (ret) {
362 pr_err("failed to get OPP-sharing information for cpu%d\n",
363 cpu);
364 goto out_free_resources;
365 }
366
367 ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
368 if (ret) {
369 pr_warn("no OPP table for cpu%d\n", cpu);
370 goto out_free_resources;
371 }
372
373 /* Search a safe voltage for intermediate frequency. */
374 rate = clk_get_rate(inter_clk);
375 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
376 if (IS_ERR(opp)) {
377 pr_err("failed to get intermediate opp for cpu%d\n", cpu);
378 ret = PTR_ERR(opp);
379 goto out_free_opp_table;
380 }
381 info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
382 dev_pm_opp_put(opp);
383
384 info->cpu_dev = cpu_dev;
385 info->proc_reg = proc_reg;
386 info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg;
387 info->cpu_clk = cpu_clk;
388 info->inter_clk = inter_clk;
389
390 /*
391 * If SRAM regulator is present, software "voltage tracking" is needed
392 * for this CPU power domain.
393 */
394 info->need_voltage_tracking = !IS_ERR(sram_reg);
395
396 return 0;
397
398 out_free_opp_table:
399 dev_pm_opp_of_cpumask_remove_table(&info->cpus);
400
401 out_free_resources:
402 if (!IS_ERR(proc_reg))
403 regulator_put(proc_reg);
404 if (!IS_ERR(sram_reg))
405 regulator_put(sram_reg);
406 if (!IS_ERR(cpu_clk))
407 clk_put(cpu_clk);
408 if (!IS_ERR(inter_clk))
409 clk_put(inter_clk);
410
411 return ret;
412 }
413
mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info * info)414 static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
415 {
416 if (!IS_ERR(info->proc_reg))
417 regulator_put(info->proc_reg);
418 if (!IS_ERR(info->sram_reg))
419 regulator_put(info->sram_reg);
420 if (!IS_ERR(info->cpu_clk))
421 clk_put(info->cpu_clk);
422 if (!IS_ERR(info->inter_clk))
423 clk_put(info->inter_clk);
424
425 dev_pm_opp_of_cpumask_remove_table(&info->cpus);
426 }
427
mtk_cpufreq_init(struct cpufreq_policy * policy)428 static int mtk_cpufreq_init(struct cpufreq_policy *policy)
429 {
430 struct mtk_cpu_dvfs_info *info;
431 struct cpufreq_frequency_table *freq_table;
432 int ret;
433
434 info = mtk_cpu_dvfs_info_lookup(policy->cpu);
435 if (!info) {
436 pr_err("dvfs info for cpu%d is not initialized.\n",
437 policy->cpu);
438 return -EINVAL;
439 }
440
441 ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
442 if (ret) {
443 pr_err("failed to init cpufreq table for cpu%d: %d\n",
444 policy->cpu, ret);
445 return ret;
446 }
447
448 cpumask_copy(policy->cpus, &info->cpus);
449 policy->freq_table = freq_table;
450 policy->driver_data = info;
451 policy->clk = info->cpu_clk;
452
453 dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus);
454
455 return 0;
456 }
457
mtk_cpufreq_exit(struct cpufreq_policy * policy)458 static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
459 {
460 struct mtk_cpu_dvfs_info *info = policy->driver_data;
461
462 dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
463
464 return 0;
465 }
466
467 static struct cpufreq_driver mtk_cpufreq_driver = {
468 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
469 CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
470 CPUFREQ_IS_COOLING_DEV,
471 .verify = cpufreq_generic_frequency_table_verify,
472 .target_index = mtk_cpufreq_set_target,
473 .get = cpufreq_generic_get,
474 .init = mtk_cpufreq_init,
475 .exit = mtk_cpufreq_exit,
476 .name = "mtk-cpufreq",
477 .attr = cpufreq_generic_attr,
478 };
479
mtk_cpufreq_probe(struct platform_device * pdev)480 static int mtk_cpufreq_probe(struct platform_device *pdev)
481 {
482 struct mtk_cpu_dvfs_info *info, *tmp;
483 int cpu, ret;
484
485 for_each_possible_cpu(cpu) {
486 info = mtk_cpu_dvfs_info_lookup(cpu);
487 if (info)
488 continue;
489
490 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
491 if (!info) {
492 ret = -ENOMEM;
493 goto release_dvfs_info_list;
494 }
495
496 ret = mtk_cpu_dvfs_info_init(info, cpu);
497 if (ret) {
498 dev_err(&pdev->dev,
499 "failed to initialize dvfs info for cpu%d\n",
500 cpu);
501 goto release_dvfs_info_list;
502 }
503
504 list_add(&info->list_head, &dvfs_info_list);
505 }
506
507 ret = cpufreq_register_driver(&mtk_cpufreq_driver);
508 if (ret) {
509 dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n");
510 goto release_dvfs_info_list;
511 }
512
513 return 0;
514
515 release_dvfs_info_list:
516 list_for_each_entry_safe(info, tmp, &dvfs_info_list, list_head) {
517 mtk_cpu_dvfs_info_release(info);
518 list_del(&info->list_head);
519 }
520
521 return ret;
522 }
523
524 static struct platform_driver mtk_cpufreq_platdrv = {
525 .driver = {
526 .name = "mtk-cpufreq",
527 },
528 .probe = mtk_cpufreq_probe,
529 };
530
531 /* List of machines supported by this driver */
532 static const struct of_device_id mtk_cpufreq_machines[] __initconst = {
533 { .compatible = "mediatek,mt2701", },
534 { .compatible = "mediatek,mt2712", },
535 { .compatible = "mediatek,mt7622", },
536 { .compatible = "mediatek,mt7623", },
537 { .compatible = "mediatek,mt817x", },
538 { .compatible = "mediatek,mt8173", },
539 { .compatible = "mediatek,mt8176", },
540 { .compatible = "mediatek,mt8183", },
541 { .compatible = "mediatek,mt8516", },
542
543 { }
544 };
545 MODULE_DEVICE_TABLE(of, mtk_cpufreq_machines);
546
mtk_cpufreq_driver_init(void)547 static int __init mtk_cpufreq_driver_init(void)
548 {
549 struct device_node *np;
550 const struct of_device_id *match;
551 int err;
552
553 np = of_find_node_by_path("/");
554 if (!np)
555 return -ENODEV;
556
557 match = of_match_node(mtk_cpufreq_machines, np);
558 of_node_put(np);
559 if (!match) {
560 pr_debug("Machine is not compatible with mtk-cpufreq\n");
561 return -ENODEV;
562 }
563
564 err = platform_driver_register(&mtk_cpufreq_platdrv);
565 if (err)
566 return err;
567
568 /*
569 * Since there's no place to hold device registration code and no
570 * device tree based way to match cpufreq driver yet, both the driver
571 * and the device registration codes are put here to handle defer
572 * probing.
573 */
574 cpufreq_pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0);
575 if (IS_ERR(cpufreq_pdev)) {
576 pr_err("failed to register mtk-cpufreq platform device\n");
577 platform_driver_unregister(&mtk_cpufreq_platdrv);
578 return PTR_ERR(cpufreq_pdev);
579 }
580
581 return 0;
582 }
module_init(mtk_cpufreq_driver_init)583 module_init(mtk_cpufreq_driver_init)
584
585 static void __exit mtk_cpufreq_driver_exit(void)
586 {
587 platform_device_unregister(cpufreq_pdev);
588 platform_driver_unregister(&mtk_cpufreq_platdrv);
589 }
590 module_exit(mtk_cpufreq_driver_exit)
591
592 MODULE_DESCRIPTION("MediaTek CPUFreq driver");
593 MODULE_AUTHOR("Pi-Cheng Chen <pi-cheng.chen@linaro.org>");
594 MODULE_LICENSE("GPL v2");
595