1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015 Linaro Ltd.
4 * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
9 #include <linux/cpufreq.h>
10 #include <linux/cpumask.h>
11 #include <linux/module.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>
19 #define MIN_VOLT_SHIFT (100000)
20 #define MAX_VOLT_SHIFT (200000)
21 #define MAX_VOLT_LIMIT (1150000)
22 #define VOLT_TOL (10000)
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
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.
35 struct mtk_cpu_dvfs_info {
37 struct device *cpu_dev;
38 struct regulator *proc_reg;
39 struct regulator *sram_reg;
41 struct clk *inter_clk;
42 struct list_head list_head;
43 int intermediate_voltage;
44 bool need_voltage_tracking;
47 static struct platform_device *cpufreq_pdev;
49 static LIST_HEAD(dvfs_info_list);
51 static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu)
53 struct mtk_cpu_dvfs_info *info;
55 list_for_each_entry(info, &dvfs_info_list, list_head) {
56 if (cpumask_test_cpu(cpu, &info->cpus))
63 static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
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;
70 old_vproc = regulator_get_voltage(proc_reg);
72 pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
75 /* Vsram should not exceed the maximum allowed voltage of SoC. */
76 new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT);
78 if (old_vproc < new_vproc) {
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.
86 old_vsram = regulator_get_voltage(sram_reg);
88 pr_err("%s: invalid Vsram value: %d\n",
92 old_vproc = regulator_get_voltage(proc_reg);
94 pr_err("%s: invalid Vproc value: %d\n",
99 vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT);
101 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
102 vsram = MAX_VOLT_LIMIT;
105 * If the target Vsram hits the maximum voltage,
106 * try to set the exact voltage value first.
108 ret = regulator_set_voltage(sram_reg, vsram,
111 ret = regulator_set_voltage(sram_reg,
117 ret = regulator_set_voltage(sram_reg, vsram,
120 vproc = vsram - MIN_VOLT_SHIFT;
125 ret = regulator_set_voltage(proc_reg, vproc,
128 regulator_set_voltage(sram_reg, old_vsram,
132 } while (vproc < new_vproc || vsram < new_vsram);
133 } else if (old_vproc > new_vproc) {
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.
141 old_vproc = regulator_get_voltage(proc_reg);
143 pr_err("%s: invalid Vproc value: %d\n",
144 __func__, old_vproc);
147 old_vsram = regulator_get_voltage(sram_reg);
149 pr_err("%s: invalid Vsram value: %d\n",
150 __func__, old_vsram);
154 vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT);
155 ret = regulator_set_voltage(proc_reg, vproc,
160 if (vproc == new_vproc)
163 vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT);
165 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
166 vsram = MAX_VOLT_LIMIT;
169 * If the target Vsram hits the maximum voltage,
170 * try to set the exact voltage value first.
172 ret = regulator_set_voltage(sram_reg, vsram,
175 ret = regulator_set_voltage(sram_reg,
179 ret = regulator_set_voltage(sram_reg, vsram,
184 regulator_set_voltage(proc_reg, old_vproc,
188 } while (vproc > new_vproc + VOLT_TOL ||
189 vsram > new_vsram + VOLT_TOL);
195 static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
197 if (info->need_voltage_tracking)
198 return mtk_cpufreq_voltage_tracking(info, vproc);
200 return regulator_set_voltage(info->proc_reg, vproc,
204 static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
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;
216 inter_vproc = info->intermediate_voltage;
218 old_freq_hz = clk_get_rate(cpu_clk);
219 old_vproc = regulator_get_voltage(info->proc_reg);
221 pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
225 freq_hz = freq_table[index].frequency * 1000;
227 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
229 pr_err("cpu%d: failed to find OPP for %ld\n",
230 policy->cpu, freq_hz);
233 vproc = dev_pm_opp_get_voltage(opp);
237 * If the new voltage or the intermediate voltage is higher than the
238 * current voltage, scale up voltage first.
240 target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
241 if (old_vproc < target_vproc) {
242 ret = mtk_cpufreq_set_voltage(info, target_vproc);
244 pr_err("cpu%d: failed to scale up voltage!\n",
246 mtk_cpufreq_set_voltage(info, old_vproc);
251 /* Reparent the CPU clock to intermediate clock. */
252 ret = clk_set_parent(cpu_clk, info->inter_clk);
254 pr_err("cpu%d: failed to re-parent cpu clock!\n",
256 mtk_cpufreq_set_voltage(info, old_vproc);
261 /* Set the original PLL to target rate. */
262 ret = clk_set_rate(armpll, freq_hz);
264 pr_err("cpu%d: failed to scale cpu clock rate!\n",
266 clk_set_parent(cpu_clk, armpll);
267 mtk_cpufreq_set_voltage(info, old_vproc);
271 /* Set parent of CPU clock back to the original PLL. */
272 ret = clk_set_parent(cpu_clk, armpll);
274 pr_err("cpu%d: failed to re-parent cpu clock!\n",
276 mtk_cpufreq_set_voltage(info, inter_vproc);
282 * If the new voltage is lower than the intermediate voltage or the
283 * original voltage, scale down to the new voltage.
285 if (vproc < inter_vproc || vproc < old_vproc) {
286 ret = mtk_cpufreq_set_voltage(info, vproc);
288 pr_err("cpu%d: failed to scale down voltage!\n",
290 clk_set_parent(cpu_clk, info->inter_clk);
291 clk_set_rate(armpll, old_freq_hz);
292 clk_set_parent(cpu_clk, armpll);
300 #define DYNAMIC_POWER "dynamic-power-coefficient"
302 static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
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;
313 cpu_dev = get_cpu_device(cpu);
315 pr_err("failed to get cpu%d device\n", cpu);
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);
324 pr_err("failed to get cpu clk for cpu%d\n", cpu);
326 ret = PTR_ERR(cpu_clk);
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",
336 pr_err("failed to get intermediate clk for cpu%d\n",
339 ret = PTR_ERR(inter_clk);
340 goto out_free_resources;
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",
349 pr_err("failed to get proc regulator for cpu%d\n",
352 ret = PTR_ERR(proc_reg);
353 goto out_free_resources;
356 /* Both presence and absence of sram regulator are valid cases. */
357 sram_reg = regulator_get_exclusive(cpu_dev, "sram");
359 /* Get OPP-sharing information from "operating-points-v2" bindings */
360 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus);
362 pr_err("failed to get OPP-sharing information for cpu%d\n",
364 goto out_free_resources;
367 ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
369 pr_warn("no OPP table for cpu%d\n", cpu);
370 goto out_free_resources;
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);
377 pr_err("failed to get intermediate opp for cpu%d\n", cpu);
379 goto out_free_opp_table;
381 info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
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;
391 * If SRAM regulator is present, software "voltage tracking" is needed
392 * for this CPU power domain.
394 info->need_voltage_tracking = !IS_ERR(sram_reg);
399 dev_pm_opp_of_cpumask_remove_table(&info->cpus);
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))
408 if (!IS_ERR(inter_clk))
414 static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
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);
425 dev_pm_opp_of_cpumask_remove_table(&info->cpus);
428 static int mtk_cpufreq_init(struct cpufreq_policy *policy)
430 struct mtk_cpu_dvfs_info *info;
431 struct cpufreq_frequency_table *freq_table;
434 info = mtk_cpu_dvfs_info_lookup(policy->cpu);
436 pr_err("dvfs info for cpu%d is not initialized.\n",
441 ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
443 pr_err("failed to init cpufreq table for cpu%d: %d\n",
448 cpumask_copy(policy->cpus, &info->cpus);
449 policy->freq_table = freq_table;
450 policy->driver_data = info;
451 policy->clk = info->cpu_clk;
456 static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
458 struct mtk_cpu_dvfs_info *info = policy->driver_data;
460 dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
465 static struct cpufreq_driver mtk_cpufreq_driver = {
466 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
467 CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
468 CPUFREQ_IS_COOLING_DEV,
469 .verify = cpufreq_generic_frequency_table_verify,
470 .target_index = mtk_cpufreq_set_target,
471 .get = cpufreq_generic_get,
472 .init = mtk_cpufreq_init,
473 .exit = mtk_cpufreq_exit,
474 .register_em = cpufreq_register_em_with_opp,
475 .name = "mtk-cpufreq",
476 .attr = cpufreq_generic_attr,
479 static int mtk_cpufreq_probe(struct platform_device *pdev)
481 struct mtk_cpu_dvfs_info *info, *tmp;
484 for_each_possible_cpu(cpu) {
485 info = mtk_cpu_dvfs_info_lookup(cpu);
489 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
492 goto release_dvfs_info_list;
495 ret = mtk_cpu_dvfs_info_init(info, cpu);
498 "failed to initialize dvfs info for cpu%d\n",
500 goto release_dvfs_info_list;
503 list_add(&info->list_head, &dvfs_info_list);
506 ret = cpufreq_register_driver(&mtk_cpufreq_driver);
508 dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n");
509 goto release_dvfs_info_list;
514 release_dvfs_info_list:
515 list_for_each_entry_safe(info, tmp, &dvfs_info_list, list_head) {
516 mtk_cpu_dvfs_info_release(info);
517 list_del(&info->list_head);
523 static struct platform_driver mtk_cpufreq_platdrv = {
525 .name = "mtk-cpufreq",
527 .probe = mtk_cpufreq_probe,
530 /* List of machines supported by this driver */
531 static const struct of_device_id mtk_cpufreq_machines[] __initconst = {
532 { .compatible = "mediatek,mt2701", },
533 { .compatible = "mediatek,mt2712", },
534 { .compatible = "mediatek,mt7622", },
535 { .compatible = "mediatek,mt7623", },
536 { .compatible = "mediatek,mt8167", },
537 { .compatible = "mediatek,mt817x", },
538 { .compatible = "mediatek,mt8173", },
539 { .compatible = "mediatek,mt8176", },
540 { .compatible = "mediatek,mt8183", },
541 { .compatible = "mediatek,mt8365", },
542 { .compatible = "mediatek,mt8516", },
546 MODULE_DEVICE_TABLE(of, mtk_cpufreq_machines);
548 static int __init mtk_cpufreq_driver_init(void)
550 struct device_node *np;
551 const struct of_device_id *match;
554 np = of_find_node_by_path("/");
558 match = of_match_node(mtk_cpufreq_machines, np);
561 pr_debug("Machine is not compatible with mtk-cpufreq\n");
565 err = platform_driver_register(&mtk_cpufreq_platdrv);
570 * Since there's no place to hold device registration code and no
571 * device tree based way to match cpufreq driver yet, both the driver
572 * and the device registration codes are put here to handle defer
575 cpufreq_pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0);
576 if (IS_ERR(cpufreq_pdev)) {
577 pr_err("failed to register mtk-cpufreq platform device\n");
578 platform_driver_unregister(&mtk_cpufreq_platdrv);
579 return PTR_ERR(cpufreq_pdev);
584 module_init(mtk_cpufreq_driver_init)
586 static void __exit mtk_cpufreq_driver_exit(void)
588 platform_device_unregister(cpufreq_pdev);
589 platform_driver_unregister(&mtk_cpufreq_platdrv);
591 module_exit(mtk_cpufreq_driver_exit)
593 MODULE_DESCRIPTION("MediaTek CPUFreq driver");
594 MODULE_AUTHOR("Pi-Cheng Chen <pi-cheng.chen@linaro.org>");
595 MODULE_LICENSE("GPL v2");