Lines Matching +full:mt8183 +full:- +full:cci

1 // SPDX-License-Identifier: GPL-2.0-only
4 * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
33 * 100mV < Vsram - Vproc < 200mV
71 if (cpumask_test_cpu(cpu, &info->cpus)) in mtk_cpu_dvfs_info_lookup()
81 const struct mtk_cpufreq_platform_data *soc_data = info->soc_data; in mtk_cpufreq_voltage_tracking()
82 struct regulator *proc_reg = info->proc_reg; in mtk_cpufreq_voltage_tracking()
83 struct regulator *sram_reg = info->sram_reg; in mtk_cpufreq_voltage_tracking()
85 int retry = info->vtrack_max; in mtk_cpufreq_voltage_tracking()
89 dev_err(info->cpu_dev, in mtk_cpufreq_voltage_tracking()
96 dev_err(info->cpu_dev, "invalid Vsram value: %d\n", pre_vsram); in mtk_cpufreq_voltage_tracking()
100 new_vsram = clamp(new_vproc + soc_data->min_volt_shift, in mtk_cpufreq_voltage_tracking()
101 soc_data->sram_min_volt, soc_data->sram_max_volt); in mtk_cpufreq_voltage_tracking()
105 vsram = clamp(pre_vproc + soc_data->max_volt_shift, in mtk_cpufreq_voltage_tracking()
106 soc_data->sram_min_volt, new_vsram); in mtk_cpufreq_voltage_tracking()
108 soc_data->sram_max_volt); in mtk_cpufreq_voltage_tracking()
113 if (vsram == soc_data->sram_max_volt || in mtk_cpufreq_voltage_tracking()
114 new_vsram == soc_data->sram_min_volt) in mtk_cpufreq_voltage_tracking()
117 vproc = vsram - soc_data->min_volt_shift; in mtk_cpufreq_voltage_tracking()
120 soc_data->proc_max_volt); in mtk_cpufreq_voltage_tracking()
123 soc_data->sram_max_volt); in mtk_cpufreq_voltage_tracking()
128 pre_vsram - soc_data->max_volt_shift); in mtk_cpufreq_voltage_tracking()
130 soc_data->proc_max_volt); in mtk_cpufreq_voltage_tracking()
138 vproc + soc_data->min_volt_shift); in mtk_cpufreq_voltage_tracking()
141 soc_data->sram_max_volt); in mtk_cpufreq_voltage_tracking()
144 soc_data->proc_max_volt); in mtk_cpufreq_voltage_tracking()
152 if (--retry < 0) { in mtk_cpufreq_voltage_tracking()
153 dev_err(info->cpu_dev, in mtk_cpufreq_voltage_tracking()
155 return -EINVAL; in mtk_cpufreq_voltage_tracking()
164 const struct mtk_cpufreq_platform_data *soc_data = info->soc_data; in mtk_cpufreq_set_voltage()
167 if (info->need_voltage_tracking) in mtk_cpufreq_set_voltage()
170 ret = regulator_set_voltage(info->proc_reg, vproc, in mtk_cpufreq_set_voltage()
171 soc_data->proc_max_volt); in mtk_cpufreq_set_voltage()
173 info->pre_vproc = vproc; in mtk_cpufreq_set_voltage()
182 if (info->ccifreq_bound) in is_ccifreq_ready()
185 sup_link = device_link_add(info->cpu_dev, info->cci_dev, in is_ccifreq_ready()
188 dev_err(info->cpu_dev, "cpu%d: sup_link is NULL\n", info->opp_cpu); in is_ccifreq_ready()
192 if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND) in is_ccifreq_ready()
195 info->ccifreq_bound = true; in is_ccifreq_ready()
203 struct cpufreq_frequency_table *freq_table = policy->freq_table; in mtk_cpufreq_set_target()
204 struct clk *cpu_clk = policy->clk; in mtk_cpufreq_set_target()
206 struct mtk_cpu_dvfs_info *info = policy->driver_data; in mtk_cpufreq_set_target()
207 struct device *cpu_dev = info->cpu_dev; in mtk_cpufreq_set_target()
212 inter_vproc = info->intermediate_voltage; in mtk_cpufreq_set_target()
216 mutex_lock(&info->reg_lock); in mtk_cpufreq_set_target()
218 if (unlikely(info->pre_vproc <= 0)) in mtk_cpufreq_set_target()
219 pre_vproc = regulator_get_voltage(info->proc_reg); in mtk_cpufreq_set_target()
221 pre_vproc = info->pre_vproc; in mtk_cpufreq_set_target()
234 policy->cpu, freq_hz); in mtk_cpufreq_set_target()
242 * If MediaTek cci is supported but is not ready, we will use the value in mtk_cpufreq_set_target()
246 if (info->soc_data->ccifreq_supported && !is_ccifreq_ready(info)) in mtk_cpufreq_set_target()
247 vproc = max(vproc, info->vproc_on_boot); in mtk_cpufreq_set_target()
258 "cpu%d: failed to scale up voltage!\n", policy->cpu); in mtk_cpufreq_set_target()
265 ret = clk_set_parent(cpu_clk, info->inter_clk); in mtk_cpufreq_set_target()
268 "cpu%d: failed to re-parent cpu clock!\n", policy->cpu); in mtk_cpufreq_set_target()
277 "cpu%d: failed to scale cpu clock rate!\n", policy->cpu); in mtk_cpufreq_set_target()
287 "cpu%d: failed to re-parent cpu clock!\n", policy->cpu); in mtk_cpufreq_set_target()
300 "cpu%d: failed to scale down voltage!\n", policy->cpu); in mtk_cpufreq_set_target()
301 clk_set_parent(cpu_clk, info->inter_clk); in mtk_cpufreq_set_target()
308 info->current_freq = freq_hz; in mtk_cpufreq_set_target()
311 mutex_unlock(&info->reg_lock); in mtk_cpufreq_set_target()
331 mutex_lock(&info->reg_lock); in mtk_cpufreq_opp_notifier()
332 if (info->current_freq == freq) { in mtk_cpufreq_opp_notifier()
336 dev_err(info->cpu_dev, in mtk_cpufreq_opp_notifier()
339 mutex_unlock(&info->reg_lock); in mtk_cpufreq_opp_notifier()
344 if (info->current_freq == freq) { in mtk_cpufreq_opp_notifier()
346 new_opp = dev_pm_opp_find_freq_ceil(info->cpu_dev, in mtk_cpufreq_opp_notifier()
349 dev_err(info->cpu_dev, in mtk_cpufreq_opp_notifier()
356 policy = cpufreq_cpu_get(info->opp_cpu); in mtk_cpufreq_opp_notifier()
373 np = of_parse_phandle(cpu_dev->of_node, "mediatek,cci", 0); in of_get_cci()
375 return ERR_PTR(-ENODEV); in of_get_cci()
380 return ERR_PTR(-ENODEV); in of_get_cci()
382 return &pdev->dev; in of_get_cci()
395 return -ENODEV; in mtk_cpu_dvfs_info_init()
397 info->cpu_dev = cpu_dev; in mtk_cpu_dvfs_info_init()
399 info->ccifreq_bound = false; in mtk_cpu_dvfs_info_init()
400 if (info->soc_data->ccifreq_supported) { in mtk_cpu_dvfs_info_init()
401 info->cci_dev = of_get_cci(info->cpu_dev); in mtk_cpu_dvfs_info_init()
402 if (IS_ERR(info->cci_dev)) { in mtk_cpu_dvfs_info_init()
403 ret = PTR_ERR(info->cci_dev); in mtk_cpu_dvfs_info_init()
404 dev_err(cpu_dev, "cpu%d: failed to get cci device\n", cpu); in mtk_cpu_dvfs_info_init()
405 return -ENODEV; in mtk_cpu_dvfs_info_init()
409 info->cpu_clk = clk_get(cpu_dev, "cpu"); in mtk_cpu_dvfs_info_init()
410 if (IS_ERR(info->cpu_clk)) { in mtk_cpu_dvfs_info_init()
411 ret = PTR_ERR(info->cpu_clk); in mtk_cpu_dvfs_info_init()
416 info->inter_clk = clk_get(cpu_dev, "intermediate"); in mtk_cpu_dvfs_info_init()
417 if (IS_ERR(info->inter_clk)) { in mtk_cpu_dvfs_info_init()
418 ret = PTR_ERR(info->inter_clk); in mtk_cpu_dvfs_info_init()
424 info->proc_reg = regulator_get_optional(cpu_dev, "proc"); in mtk_cpu_dvfs_info_init()
425 if (IS_ERR(info->proc_reg)) { in mtk_cpu_dvfs_info_init()
426 ret = PTR_ERR(info->proc_reg); in mtk_cpu_dvfs_info_init()
432 ret = regulator_enable(info->proc_reg); in mtk_cpu_dvfs_info_init()
439 info->sram_reg = regulator_get_optional(cpu_dev, "sram"); in mtk_cpu_dvfs_info_init()
440 if (IS_ERR(info->sram_reg)) { in mtk_cpu_dvfs_info_init()
441 ret = PTR_ERR(info->sram_reg); in mtk_cpu_dvfs_info_init()
442 if (ret == -EPROBE_DEFER) in mtk_cpu_dvfs_info_init()
445 info->sram_reg = NULL; in mtk_cpu_dvfs_info_init()
447 ret = regulator_enable(info->sram_reg); in mtk_cpu_dvfs_info_init()
454 /* Get OPP-sharing information from "operating-points-v2" bindings */ in mtk_cpu_dvfs_info_init()
455 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus); in mtk_cpu_dvfs_info_init()
458 "cpu%d: failed to get OPP-sharing information\n", cpu); in mtk_cpu_dvfs_info_init()
462 ret = dev_pm_opp_of_cpumask_add_table(&info->cpus); in mtk_cpu_dvfs_info_init()
468 ret = clk_prepare_enable(info->cpu_clk); in mtk_cpu_dvfs_info_init()
472 ret = clk_prepare_enable(info->inter_clk); in mtk_cpu_dvfs_info_init()
476 if (info->soc_data->ccifreq_supported) { in mtk_cpu_dvfs_info_init()
477 info->vproc_on_boot = regulator_get_voltage(info->proc_reg); in mtk_cpu_dvfs_info_init()
478 if (info->vproc_on_boot < 0) { in mtk_cpu_dvfs_info_init()
479 ret = info->vproc_on_boot; in mtk_cpu_dvfs_info_init()
480 dev_err(info->cpu_dev, in mtk_cpu_dvfs_info_init()
481 "invalid Vproc value: %d\n", info->vproc_on_boot); in mtk_cpu_dvfs_info_init()
487 rate = clk_get_rate(info->inter_clk); in mtk_cpu_dvfs_info_init()
494 info->intermediate_voltage = dev_pm_opp_get_voltage(opp); in mtk_cpu_dvfs_info_init()
497 mutex_init(&info->reg_lock); in mtk_cpu_dvfs_info_init()
498 info->current_freq = clk_get_rate(info->cpu_clk); in mtk_cpu_dvfs_info_init()
500 info->opp_cpu = cpu; in mtk_cpu_dvfs_info_init()
501 info->opp_nb.notifier_call = mtk_cpufreq_opp_notifier; in mtk_cpu_dvfs_info_init()
502 ret = dev_pm_opp_register_notifier(cpu_dev, &info->opp_nb); in mtk_cpu_dvfs_info_init()
512 info->need_voltage_tracking = (info->sram_reg != NULL); in mtk_cpu_dvfs_info_init()
519 info->vtrack_max = 3 * DIV_ROUND_UP(max(info->soc_data->sram_max_volt, in mtk_cpu_dvfs_info_init()
520 info->soc_data->proc_max_volt), in mtk_cpu_dvfs_info_init()
521 info->soc_data->min_volt_shift); in mtk_cpu_dvfs_info_init()
526 clk_disable_unprepare(info->inter_clk); in mtk_cpu_dvfs_info_init()
529 clk_disable_unprepare(info->cpu_clk); in mtk_cpu_dvfs_info_init()
532 dev_pm_opp_of_cpumask_remove_table(&info->cpus); in mtk_cpu_dvfs_info_init()
535 if (info->sram_reg) in mtk_cpu_dvfs_info_init()
536 regulator_disable(info->sram_reg); in mtk_cpu_dvfs_info_init()
539 if (info->sram_reg) in mtk_cpu_dvfs_info_init()
540 regulator_put(info->sram_reg); in mtk_cpu_dvfs_info_init()
543 regulator_disable(info->proc_reg); in mtk_cpu_dvfs_info_init()
546 regulator_put(info->proc_reg); in mtk_cpu_dvfs_info_init()
549 clk_put(info->inter_clk); in mtk_cpu_dvfs_info_init()
552 clk_put(info->cpu_clk); in mtk_cpu_dvfs_info_init()
559 regulator_disable(info->proc_reg); in mtk_cpu_dvfs_info_release()
560 regulator_put(info->proc_reg); in mtk_cpu_dvfs_info_release()
561 if (info->sram_reg) { in mtk_cpu_dvfs_info_release()
562 regulator_disable(info->sram_reg); in mtk_cpu_dvfs_info_release()
563 regulator_put(info->sram_reg); in mtk_cpu_dvfs_info_release()
565 clk_disable_unprepare(info->cpu_clk); in mtk_cpu_dvfs_info_release()
566 clk_put(info->cpu_clk); in mtk_cpu_dvfs_info_release()
567 clk_disable_unprepare(info->inter_clk); in mtk_cpu_dvfs_info_release()
568 clk_put(info->inter_clk); in mtk_cpu_dvfs_info_release()
569 dev_pm_opp_of_cpumask_remove_table(&info->cpus); in mtk_cpu_dvfs_info_release()
570 dev_pm_opp_unregister_notifier(info->cpu_dev, &info->opp_nb); in mtk_cpu_dvfs_info_release()
579 info = mtk_cpu_dvfs_info_lookup(policy->cpu); in mtk_cpufreq_init()
582 policy->cpu); in mtk_cpufreq_init()
583 return -EINVAL; in mtk_cpufreq_init()
586 ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); in mtk_cpufreq_init()
588 dev_err(info->cpu_dev, in mtk_cpufreq_init()
590 policy->cpu, ret); in mtk_cpufreq_init()
594 cpumask_copy(policy->cpus, &info->cpus); in mtk_cpufreq_init()
595 policy->freq_table = freq_table; in mtk_cpufreq_init()
596 policy->driver_data = info; in mtk_cpufreq_init()
597 policy->clk = info->cpu_clk; in mtk_cpufreq_init()
604 struct mtk_cpu_dvfs_info *info = policy->driver_data; in mtk_cpufreq_exit()
606 dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); in mtk_cpufreq_exit()
621 .name = "mtk-cpufreq",
631 data = dev_get_platdata(&pdev->dev); in mtk_cpufreq_probe()
633 dev_err(&pdev->dev, in mtk_cpufreq_probe()
635 return -ENODEV; in mtk_cpufreq_probe()
643 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in mtk_cpufreq_probe()
645 ret = -ENOMEM; in mtk_cpufreq_probe()
649 info->soc_data = data; in mtk_cpufreq_probe()
652 dev_err(&pdev->dev, in mtk_cpufreq_probe()
658 list_add(&info->list_head, &dvfs_info_list); in mtk_cpufreq_probe()
663 dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n"); in mtk_cpufreq_probe()
672 list_del(&info->list_head); in mtk_cpufreq_probe()
680 .name = "mtk-cpufreq",
747 { .compatible = "mediatek,mt8183", .data = &mt8183_platform_data },
764 return -ENODEV; in mtk_cpufreq_driver_init()
769 pr_debug("Machine is not compatible with mtk-cpufreq\n"); in mtk_cpufreq_driver_init()
770 return -ENODEV; in mtk_cpufreq_driver_init()
772 data = match->data; in mtk_cpufreq_driver_init()
784 cpufreq_pdev = platform_device_register_data(NULL, "mtk-cpufreq", -1, in mtk_cpufreq_driver_init()
787 pr_err("failed to register mtk-cpufreq platform device\n"); in mtk_cpufreq_driver_init()
804 MODULE_AUTHOR("Pi-Cheng Chen <pi-cheng.chen@linaro.org>");