Lines Matching +full:cluster +full:- +full:cpufreq
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
9 #include <linux/cpufreq.h>
30 * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
33 * 100mV < Vsram - Vproc < 200mV
71 if (cpumask_test_cpu(cpu, &info->cpus))
81 const struct mtk_cpufreq_platform_data *soc_data = info->soc_data;
82 struct regulator *proc_reg = info->proc_reg;
83 struct regulator *sram_reg = info->sram_reg;
85 int retry = info->vtrack_max;
89 dev_err(info->cpu_dev,
96 dev_err(info->cpu_dev, "invalid Vsram value: %d\n", pre_vsram);
100 new_vsram = clamp(new_vproc + soc_data->min_volt_shift,
101 soc_data->sram_min_volt, soc_data->sram_max_volt);
105 vsram = clamp(pre_vproc + soc_data->max_volt_shift,
106 soc_data->sram_min_volt, new_vsram);
108 soc_data->sram_max_volt);
113 if (vsram == soc_data->sram_max_volt ||
114 new_vsram == soc_data->sram_min_volt)
117 vproc = vsram - soc_data->min_volt_shift;
120 soc_data->proc_max_volt);
123 soc_data->sram_max_volt);
128 pre_vsram - soc_data->max_volt_shift);
130 soc_data->proc_max_volt);
138 vproc + soc_data->min_volt_shift);
141 soc_data->sram_max_volt);
144 soc_data->proc_max_volt);
152 if (--retry < 0) {
153 dev_err(info->cpu_dev,
155 return -EINVAL;
164 const struct mtk_cpufreq_platform_data *soc_data = info->soc_data;
167 if (info->need_voltage_tracking)
170 ret = regulator_set_voltage(info->proc_reg, vproc,
171 soc_data->proc_max_volt);
173 info->pre_vproc = vproc;
182 if (info->ccifreq_bound)
185 sup_link = device_link_add(info->cpu_dev, info->cci_dev,
188 dev_err(info->cpu_dev, "cpu%d: sup_link is NULL\n", info->opp_cpu);
192 if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND)
195 info->ccifreq_bound = true;
203 struct cpufreq_frequency_table *freq_table = policy->freq_table;
204 struct clk *cpu_clk = policy->clk;
206 struct mtk_cpu_dvfs_info *info = policy->driver_data;
207 struct device *cpu_dev = info->cpu_dev;
212 inter_vproc = info->intermediate_voltage;
216 mutex_lock(&info->reg_lock);
218 if (unlikely(info->pre_vproc <= 0))
219 pre_vproc = regulator_get_voltage(info->proc_reg);
221 pre_vproc = info->pre_vproc;
234 policy->cpu, freq_hz);
246 if (info->soc_data->ccifreq_supported && !is_ccifreq_ready(info))
247 vproc = max(vproc, info->vproc_on_boot);
258 "cpu%d: failed to scale up voltage!\n", policy->cpu);
265 ret = clk_set_parent(cpu_clk, info->inter_clk);
268 "cpu%d: failed to re-parent cpu clock!\n", policy->cpu);
277 "cpu%d: failed to scale cpu clock rate!\n", policy->cpu);
287 "cpu%d: failed to re-parent cpu clock!\n", policy->cpu);
300 "cpu%d: failed to scale down voltage!\n", policy->cpu);
301 clk_set_parent(cpu_clk, info->inter_clk);
308 info->current_freq = freq_hz;
311 mutex_unlock(&info->reg_lock);
331 mutex_lock(&info->reg_lock);
332 if (info->current_freq == freq) {
336 dev_err(info->cpu_dev,
339 mutex_unlock(&info->reg_lock);
344 if (info->current_freq == freq) {
346 new_opp = dev_pm_opp_find_freq_ceil(info->cpu_dev,
349 dev_err(info->cpu_dev,
356 policy = cpufreq_cpu_get(info->opp_cpu);
373 np = of_parse_phandle(cpu_dev->of_node, "mediatek,cci", 0);
375 return ERR_PTR(-ENODEV);
380 return ERR_PTR(-ENODEV);
382 return &pdev->dev;
394 return dev_err_probe(cpu_dev, -ENODEV, "failed to get cpu%d device\n", cpu);
395 info->cpu_dev = cpu_dev;
397 info->ccifreq_bound = false;
398 if (info->soc_data->ccifreq_supported) {
399 info->cci_dev = of_get_cci(info->cpu_dev);
400 if (IS_ERR(info->cci_dev))
401 return dev_err_probe(cpu_dev, PTR_ERR(info->cci_dev),
406 info->cpu_clk = clk_get(cpu_dev, "cpu");
407 if (IS_ERR(info->cpu_clk))
408 return dev_err_probe(cpu_dev, PTR_ERR(info->cpu_clk),
411 info->inter_clk = clk_get(cpu_dev, "intermediate");
412 if (IS_ERR(info->inter_clk)) {
413 ret = PTR_ERR(info->inter_clk);
419 info->proc_reg = regulator_get_optional(cpu_dev, "proc");
420 if (IS_ERR(info->proc_reg)) {
421 ret = PTR_ERR(info->proc_reg);
427 ret = regulator_enable(info->proc_reg);
434 info->sram_reg = regulator_get_optional(cpu_dev, "sram");
435 if (IS_ERR(info->sram_reg)) {
436 ret = PTR_ERR(info->sram_reg);
437 if (ret == -EPROBE_DEFER) {
443 info->sram_reg = NULL;
445 ret = regulator_enable(info->sram_reg);
452 /* Get OPP-sharing information from "operating-points-v2" bindings */
453 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus);
456 "cpu%d: failed to get OPP-sharing information\n", cpu);
460 ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
466 ret = clk_prepare_enable(info->cpu_clk);
472 ret = clk_prepare_enable(info->inter_clk);
478 if (info->soc_data->ccifreq_supported) {
479 info->vproc_on_boot = regulator_get_voltage(info->proc_reg);
480 if (info->vproc_on_boot < 0) {
481 ret = dev_err_probe(info->cpu_dev, info->vproc_on_boot,
488 rate = clk_get_rate(info->inter_clk);
495 info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
498 mutex_init(&info->reg_lock);
499 info->current_freq = clk_get_rate(info->cpu_clk);
501 info->opp_cpu = cpu;
502 info->opp_nb.notifier_call = mtk_cpufreq_opp_notifier;
503 ret = dev_pm_opp_register_notifier(cpu_dev, &info->opp_nb);
513 info->need_voltage_tracking = (info->sram_reg != NULL);
520 info->vtrack_max = 3 * DIV_ROUND_UP(max(info->soc_data->sram_max_volt,
521 info->soc_data->proc_max_volt),
522 info->soc_data->min_volt_shift);
527 clk_disable_unprepare(info->inter_clk);
530 clk_disable_unprepare(info->cpu_clk);
533 dev_pm_opp_of_cpumask_remove_table(&info->cpus);
536 if (info->sram_reg)
537 regulator_disable(info->sram_reg);
540 if (info->sram_reg)
541 regulator_put(info->sram_reg);
544 regulator_disable(info->proc_reg);
547 regulator_put(info->proc_reg);
550 clk_put(info->inter_clk);
553 clk_put(info->cpu_clk);
560 regulator_disable(info->proc_reg);
561 regulator_put(info->proc_reg);
562 if (info->sram_reg) {
563 regulator_disable(info->sram_reg);
564 regulator_put(info->sram_reg);
566 clk_disable_unprepare(info->cpu_clk);
567 clk_put(info->cpu_clk);
568 clk_disable_unprepare(info->inter_clk);
569 clk_put(info->inter_clk);
570 dev_pm_opp_of_cpumask_remove_table(&info->cpus);
571 dev_pm_opp_unregister_notifier(info->cpu_dev, &info->opp_nb);
580 info = mtk_cpu_dvfs_info_lookup(policy->cpu);
583 policy->cpu);
584 return -EINVAL;
587 ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
589 dev_err(info->cpu_dev,
590 "failed to init cpufreq table for cpu%d: %d\n",
591 policy->cpu, ret);
595 cpumask_copy(policy->cpus, &info->cpus);
596 policy->freq_table = freq_table;
597 policy->driver_data = info;
598 policy->clk = info->cpu_clk;
605 struct mtk_cpu_dvfs_info *info = policy->driver_data;
607 dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
620 .name = "mtk-cpufreq",
629 data = dev_get_platdata(&pdev->dev);
631 return dev_err_probe(&pdev->dev, -ENODEV,
632 "failed to get mtk cpufreq platform data\n");
639 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
641 ret = dev_err_probe(&pdev->dev, -ENOMEM,
646 info->soc_data = data;
651 list_add(&info->list_head, &dvfs_info_list);
656 dev_err_probe(&pdev->dev, ret, "failed to register mtk cpufreq driver\n");
665 list_del(&info->list_head);
673 .name = "mtk-cpufreq",
767 return -ENODEV;
772 pr_debug("Machine is not compatible with mtk-cpufreq\n");
773 return -ENODEV;
775 data = match->data;
783 * device tree based way to match cpufreq driver yet, both the driver
787 cpufreq_pdev = platform_device_register_data(NULL, "mtk-cpufreq", -1,
790 pr_err("failed to register mtk-cpufreq platform device\n");
806 MODULE_DESCRIPTION("MediaTek CPUFreq driver");
807 MODULE_AUTHOR("Pi-Cheng Chen <pi-cheng.chen@linaro.org>");