Lines Matching +full:vsram +full:- +full:proc
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
27 * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two
29 * 100mV < Vsram - Vproc < 200mV
56 if (cpumask_test_cpu(cpu, &info->cpus)) in mtk_cpu_dvfs_info_lookup()
66 struct regulator *proc_reg = info->proc_reg; in mtk_cpufreq_voltage_tracking()
67 struct regulator *sram_reg = info->sram_reg; in mtk_cpufreq_voltage_tracking()
68 int old_vproc, old_vsram, new_vsram, vsram, vproc, ret; in mtk_cpufreq_voltage_tracking() local
75 /* Vsram should not exceed the maximum allowed voltage of SoC. */ in mtk_cpufreq_voltage_tracking()
80 * When scaling up voltages, Vsram and Vproc scale up step in mtk_cpufreq_voltage_tracking()
81 * by step. At each step, set Vsram to (Vproc + 200mV) first, in mtk_cpufreq_voltage_tracking()
82 * then set Vproc to (Vsram - 100mV). in mtk_cpufreq_voltage_tracking()
83 * Keep doing it until Vsram and Vproc hit target voltages. in mtk_cpufreq_voltage_tracking()
88 pr_err("%s: invalid Vsram value: %d\n", in mtk_cpufreq_voltage_tracking()
99 vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT); in mtk_cpufreq_voltage_tracking()
101 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { in mtk_cpufreq_voltage_tracking()
102 vsram = MAX_VOLT_LIMIT; in mtk_cpufreq_voltage_tracking()
105 * If the target Vsram hits the maximum voltage, in mtk_cpufreq_voltage_tracking()
108 ret = regulator_set_voltage(sram_reg, vsram, in mtk_cpufreq_voltage_tracking()
109 vsram); in mtk_cpufreq_voltage_tracking()
112 vsram - VOLT_TOL, in mtk_cpufreq_voltage_tracking()
113 vsram); in mtk_cpufreq_voltage_tracking()
117 ret = regulator_set_voltage(sram_reg, vsram, in mtk_cpufreq_voltage_tracking()
118 vsram + VOLT_TOL); in mtk_cpufreq_voltage_tracking()
120 vproc = vsram - MIN_VOLT_SHIFT; in mtk_cpufreq_voltage_tracking()
132 } while (vproc < new_vproc || vsram < new_vsram); in mtk_cpufreq_voltage_tracking()
135 * When scaling down voltages, Vsram and Vproc scale down step in mtk_cpufreq_voltage_tracking()
136 * by step. At each step, set Vproc to (Vsram - 200mV) first, in mtk_cpufreq_voltage_tracking()
138 * Keep doing it until Vsram and Vproc hit target voltages. in mtk_cpufreq_voltage_tracking()
149 pr_err("%s: invalid Vsram value: %d\n", in mtk_cpufreq_voltage_tracking()
154 vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT); in mtk_cpufreq_voltage_tracking()
161 vsram = new_vsram; in mtk_cpufreq_voltage_tracking()
163 vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT); in mtk_cpufreq_voltage_tracking()
165 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { in mtk_cpufreq_voltage_tracking()
166 vsram = MAX_VOLT_LIMIT; in mtk_cpufreq_voltage_tracking()
169 * If the target Vsram hits the maximum voltage, in mtk_cpufreq_voltage_tracking()
172 ret = regulator_set_voltage(sram_reg, vsram, in mtk_cpufreq_voltage_tracking()
173 vsram); in mtk_cpufreq_voltage_tracking()
176 vsram - VOLT_TOL, in mtk_cpufreq_voltage_tracking()
177 vsram); in mtk_cpufreq_voltage_tracking()
179 ret = regulator_set_voltage(sram_reg, vsram, in mtk_cpufreq_voltage_tracking()
180 vsram + VOLT_TOL); in mtk_cpufreq_voltage_tracking()
189 vsram > new_vsram + VOLT_TOL); in mtk_cpufreq_voltage_tracking()
197 if (info->need_voltage_tracking) in mtk_cpufreq_set_voltage()
200 return regulator_set_voltage(info->proc_reg, vproc, in mtk_cpufreq_set_voltage()
207 struct cpufreq_frequency_table *freq_table = policy->freq_table; in mtk_cpufreq_set_target()
208 struct clk *cpu_clk = policy->clk; in mtk_cpufreq_set_target()
210 struct mtk_cpu_dvfs_info *info = policy->driver_data; in mtk_cpufreq_set_target()
211 struct device *cpu_dev = info->cpu_dev; in mtk_cpufreq_set_target()
216 inter_vproc = info->intermediate_voltage; in mtk_cpufreq_set_target()
219 old_vproc = regulator_get_voltage(info->proc_reg); in mtk_cpufreq_set_target()
230 policy->cpu, freq_hz); in mtk_cpufreq_set_target()
245 policy->cpu); in mtk_cpufreq_set_target()
252 ret = clk_set_parent(cpu_clk, info->inter_clk); in mtk_cpufreq_set_target()
254 pr_err("cpu%d: failed to re-parent cpu clock!\n", in mtk_cpufreq_set_target()
255 policy->cpu); in mtk_cpufreq_set_target()
265 policy->cpu); in mtk_cpufreq_set_target()
274 pr_err("cpu%d: failed to re-parent cpu clock!\n", in mtk_cpufreq_set_target()
275 policy->cpu); in mtk_cpufreq_set_target()
289 policy->cpu); in mtk_cpufreq_set_target()
290 clk_set_parent(cpu_clk, info->inter_clk); in mtk_cpufreq_set_target()
300 #define DYNAMIC_POWER "dynamic-power-coefficient"
305 struct regulator *proc_reg = ERR_PTR(-ENODEV); in mtk_cpu_dvfs_info_init()
306 struct regulator *sram_reg = ERR_PTR(-ENODEV); in mtk_cpu_dvfs_info_init()
307 struct clk *cpu_clk = ERR_PTR(-ENODEV); in mtk_cpu_dvfs_info_init()
308 struct clk *inter_clk = ERR_PTR(-ENODEV); in mtk_cpu_dvfs_info_init()
316 return -ENODEV; in mtk_cpu_dvfs_info_init()
321 if (PTR_ERR(cpu_clk) == -EPROBE_DEFER) in mtk_cpu_dvfs_info_init()
332 if (PTR_ERR(inter_clk) == -EPROBE_DEFER) in mtk_cpu_dvfs_info_init()
343 proc_reg = regulator_get_optional(cpu_dev, "proc"); in mtk_cpu_dvfs_info_init()
345 if (PTR_ERR(proc_reg) == -EPROBE_DEFER) in mtk_cpu_dvfs_info_init()
346 pr_warn("proc regulator for cpu%d not ready, retry.\n", in mtk_cpu_dvfs_info_init()
349 pr_err("failed to get proc regulator for cpu%d\n", in mtk_cpu_dvfs_info_init()
359 /* Get OPP-sharing information from "operating-points-v2" bindings */ in mtk_cpu_dvfs_info_init()
360 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus); in mtk_cpu_dvfs_info_init()
362 pr_err("failed to get OPP-sharing information for cpu%d\n", in mtk_cpu_dvfs_info_init()
367 ret = dev_pm_opp_of_cpumask_add_table(&info->cpus); in mtk_cpu_dvfs_info_init()
381 info->intermediate_voltage = dev_pm_opp_get_voltage(opp); in mtk_cpu_dvfs_info_init()
384 info->cpu_dev = cpu_dev; in mtk_cpu_dvfs_info_init()
385 info->proc_reg = proc_reg; in mtk_cpu_dvfs_info_init()
386 info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg; in mtk_cpu_dvfs_info_init()
387 info->cpu_clk = cpu_clk; in mtk_cpu_dvfs_info_init()
388 info->inter_clk = inter_clk; in mtk_cpu_dvfs_info_init()
394 info->need_voltage_tracking = !IS_ERR(sram_reg); in mtk_cpu_dvfs_info_init()
399 dev_pm_opp_of_cpumask_remove_table(&info->cpus); in mtk_cpu_dvfs_info_init()
416 if (!IS_ERR(info->proc_reg)) in mtk_cpu_dvfs_info_release()
417 regulator_put(info->proc_reg); in mtk_cpu_dvfs_info_release()
418 if (!IS_ERR(info->sram_reg)) in mtk_cpu_dvfs_info_release()
419 regulator_put(info->sram_reg); in mtk_cpu_dvfs_info_release()
420 if (!IS_ERR(info->cpu_clk)) in mtk_cpu_dvfs_info_release()
421 clk_put(info->cpu_clk); in mtk_cpu_dvfs_info_release()
422 if (!IS_ERR(info->inter_clk)) in mtk_cpu_dvfs_info_release()
423 clk_put(info->inter_clk); in mtk_cpu_dvfs_info_release()
425 dev_pm_opp_of_cpumask_remove_table(&info->cpus); in mtk_cpu_dvfs_info_release()
434 info = mtk_cpu_dvfs_info_lookup(policy->cpu); in mtk_cpufreq_init()
437 policy->cpu); in mtk_cpufreq_init()
438 return -EINVAL; in mtk_cpufreq_init()
441 ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); in mtk_cpufreq_init()
444 policy->cpu, ret); in mtk_cpufreq_init()
448 cpumask_copy(policy->cpus, &info->cpus); in mtk_cpufreq_init()
449 policy->freq_table = freq_table; in mtk_cpufreq_init()
450 policy->driver_data = info; in mtk_cpufreq_init()
451 policy->clk = info->cpu_clk; in mtk_cpufreq_init()
453 dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus); in mtk_cpufreq_init()
460 struct mtk_cpu_dvfs_info *info = policy->driver_data; in mtk_cpufreq_exit()
462 dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); in mtk_cpufreq_exit()
476 .name = "mtk-cpufreq",
490 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in mtk_cpufreq_probe()
492 ret = -ENOMEM; in mtk_cpufreq_probe()
498 dev_err(&pdev->dev, in mtk_cpufreq_probe()
504 list_add(&info->list_head, &dvfs_info_list); in mtk_cpufreq_probe()
509 dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n"); in mtk_cpufreq_probe()
518 list_del(&info->list_head); in mtk_cpufreq_probe()
526 .name = "mtk-cpufreq",
555 return -ENODEV; in mtk_cpufreq_driver_init()
560 pr_debug("Machine is not compatible with mtk-cpufreq\n"); in mtk_cpufreq_driver_init()
561 return -ENODEV; in mtk_cpufreq_driver_init()
574 cpufreq_pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0); in mtk_cpufreq_driver_init()
576 pr_err("failed to register mtk-cpufreq platform device\n"); in mtk_cpufreq_driver_init()
593 MODULE_AUTHOR("Pi-Cheng Chen <pi-cheng.chen@linaro.org>");