brintos

brintos / linux-shallow public Read only

0
0
Text · 21.3 KiB · 663f615 Raw
810 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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/minmax.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/of_platform.h>15#include <linux/platform_device.h>16#include <linux/pm_opp.h>17#include <linux/regulator/consumer.h>18 19struct mtk_cpufreq_platform_data {20	int min_volt_shift;21	int max_volt_shift;22	int proc_max_volt;23	int sram_min_volt;24	int sram_max_volt;25	bool ccifreq_supported;26};27 28/*29 * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS30 * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in31 * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two32 * voltage inputs need to be controlled under a hardware limitation:33 * 100mV < Vsram - Vproc < 200mV34 *35 * When scaling the clock frequency of a CPU clock domain, the clock source36 * needs to be switched to another stable PLL clock temporarily until37 * the original PLL becomes stable at target frequency.38 */39struct mtk_cpu_dvfs_info {40	struct cpumask cpus;41	struct device *cpu_dev;42	struct device *cci_dev;43	struct regulator *proc_reg;44	struct regulator *sram_reg;45	struct clk *cpu_clk;46	struct clk *inter_clk;47	struct list_head list_head;48	int intermediate_voltage;49	bool need_voltage_tracking;50	int vproc_on_boot;51	int pre_vproc;52	/* Avoid race condition for regulators between notify and policy */53	struct mutex reg_lock;54	struct notifier_block opp_nb;55	unsigned int opp_cpu;56	unsigned long current_freq;57	const struct mtk_cpufreq_platform_data *soc_data;58	int vtrack_max;59	bool ccifreq_bound;60};61 62static struct platform_device *cpufreq_pdev;63 64static LIST_HEAD(dvfs_info_list);65 66static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu)67{68	struct mtk_cpu_dvfs_info *info;69 70	list_for_each_entry(info, &dvfs_info_list, list_head) {71		if (cpumask_test_cpu(cpu, &info->cpus))72			return info;73	}74 75	return NULL;76}77 78static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,79					int new_vproc)80{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;84	int pre_vproc, pre_vsram, new_vsram, vsram, vproc, ret;85	int retry = info->vtrack_max;86 87	pre_vproc = regulator_get_voltage(proc_reg);88	if (pre_vproc < 0) {89		dev_err(info->cpu_dev,90			"invalid Vproc value: %d\n", pre_vproc);91		return pre_vproc;92	}93 94	pre_vsram = regulator_get_voltage(sram_reg);95	if (pre_vsram < 0) {96		dev_err(info->cpu_dev, "invalid Vsram value: %d\n", pre_vsram);97		return pre_vsram;98	}99 100	new_vsram = clamp(new_vproc + soc_data->min_volt_shift,101			  soc_data->sram_min_volt, soc_data->sram_max_volt);102 103	do {104		if (pre_vproc <= new_vproc) {105			vsram = clamp(pre_vproc + soc_data->max_volt_shift,106				      soc_data->sram_min_volt, new_vsram);107			ret = regulator_set_voltage(sram_reg, vsram,108						    soc_data->sram_max_volt);109 110			if (ret)111				return ret;112 113			if (vsram == soc_data->sram_max_volt ||114			    new_vsram == soc_data->sram_min_volt)115				vproc = new_vproc;116			else117				vproc = vsram - soc_data->min_volt_shift;118 119			ret = regulator_set_voltage(proc_reg, vproc,120						    soc_data->proc_max_volt);121			if (ret) {122				regulator_set_voltage(sram_reg, pre_vsram,123						      soc_data->sram_max_volt);124				return ret;125			}126		} else if (pre_vproc > new_vproc) {127			vproc = max(new_vproc,128				    pre_vsram - soc_data->max_volt_shift);129			ret = regulator_set_voltage(proc_reg, vproc,130						    soc_data->proc_max_volt);131			if (ret)132				return ret;133 134			if (vproc == new_vproc)135				vsram = new_vsram;136			else137				vsram = max(new_vsram,138					    vproc + soc_data->min_volt_shift);139 140			ret = regulator_set_voltage(sram_reg, vsram,141						    soc_data->sram_max_volt);142			if (ret) {143				regulator_set_voltage(proc_reg, pre_vproc,144						      soc_data->proc_max_volt);145				return ret;146			}147		}148 149		pre_vproc = vproc;150		pre_vsram = vsram;151 152		if (--retry < 0) {153			dev_err(info->cpu_dev,154				"over loop count, failed to set voltage\n");155			return -EINVAL;156		}157	} while (vproc != new_vproc || vsram != new_vsram);158 159	return 0;160}161 162static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)163{164	const struct mtk_cpufreq_platform_data *soc_data = info->soc_data;165	int ret;166 167	if (info->need_voltage_tracking)168		ret = mtk_cpufreq_voltage_tracking(info, vproc);169	else170		ret = regulator_set_voltage(info->proc_reg, vproc,171					    soc_data->proc_max_volt);172	if (!ret)173		info->pre_vproc = vproc;174 175	return ret;176}177 178static bool is_ccifreq_ready(struct mtk_cpu_dvfs_info *info)179{180	struct device_link *sup_link;181 182	if (info->ccifreq_bound)183		return true;184 185	sup_link = device_link_add(info->cpu_dev, info->cci_dev,186				   DL_FLAG_AUTOREMOVE_CONSUMER);187	if (!sup_link) {188		dev_err(info->cpu_dev, "cpu%d: sup_link is NULL\n", info->opp_cpu);189		return false;190	}191 192	if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND)193		return false;194 195	info->ccifreq_bound = true;196 197	return true;198}199 200static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,201				  unsigned int index)202{203	struct cpufreq_frequency_table *freq_table = policy->freq_table;204	struct clk *cpu_clk = policy->clk;205	struct clk *armpll = clk_get_parent(cpu_clk);206	struct mtk_cpu_dvfs_info *info = policy->driver_data;207	struct device *cpu_dev = info->cpu_dev;208	struct dev_pm_opp *opp;209	long freq_hz, pre_freq_hz;210	int vproc, pre_vproc, inter_vproc, target_vproc, ret;211 212	inter_vproc = info->intermediate_voltage;213 214	pre_freq_hz = clk_get_rate(cpu_clk);215 216	mutex_lock(&info->reg_lock);217 218	if (unlikely(info->pre_vproc <= 0))219		pre_vproc = regulator_get_voltage(info->proc_reg);220	else221		pre_vproc = info->pre_vproc;222 223	if (pre_vproc < 0) {224		dev_err(cpu_dev, "invalid Vproc value: %d\n", pre_vproc);225		ret = pre_vproc;226		goto out;227	}228 229	freq_hz = freq_table[index].frequency * 1000;230 231	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);232	if (IS_ERR(opp)) {233		dev_err(cpu_dev, "cpu%d: failed to find OPP for %ld\n",234			policy->cpu, freq_hz);235		ret = PTR_ERR(opp);236		goto out;237	}238	vproc = dev_pm_opp_get_voltage(opp);239	dev_pm_opp_put(opp);240 241	/*242	 * If MediaTek cci is supported but is not ready, we will use the value243	 * of max(target cpu voltage, booting voltage) to prevent high freqeuncy244	 * low voltage crash.245	 */246	if (info->soc_data->ccifreq_supported && !is_ccifreq_ready(info))247		vproc = max(vproc, info->vproc_on_boot);248 249	/*250	 * If the new voltage or the intermediate voltage is higher than the251	 * current voltage, scale up voltage first.252	 */253	target_vproc = max(inter_vproc, vproc);254	if (pre_vproc <= target_vproc) {255		ret = mtk_cpufreq_set_voltage(info, target_vproc);256		if (ret) {257			dev_err(cpu_dev,258				"cpu%d: failed to scale up voltage!\n", policy->cpu);259			mtk_cpufreq_set_voltage(info, pre_vproc);260			goto out;261		}262	}263 264	/* Reparent the CPU clock to intermediate clock. */265	ret = clk_set_parent(cpu_clk, info->inter_clk);266	if (ret) {267		dev_err(cpu_dev,268			"cpu%d: failed to re-parent cpu clock!\n", policy->cpu);269		mtk_cpufreq_set_voltage(info, pre_vproc);270		goto out;271	}272 273	/* Set the original PLL to target rate. */274	ret = clk_set_rate(armpll, freq_hz);275	if (ret) {276		dev_err(cpu_dev,277			"cpu%d: failed to scale cpu clock rate!\n", policy->cpu);278		clk_set_parent(cpu_clk, armpll);279		mtk_cpufreq_set_voltage(info, pre_vproc);280		goto out;281	}282 283	/* Set parent of CPU clock back to the original PLL. */284	ret = clk_set_parent(cpu_clk, armpll);285	if (ret) {286		dev_err(cpu_dev,287			"cpu%d: failed to re-parent cpu clock!\n", policy->cpu);288		mtk_cpufreq_set_voltage(info, inter_vproc);289		goto out;290	}291 292	/*293	 * If the new voltage is lower than the intermediate voltage or the294	 * original voltage, scale down to the new voltage.295	 */296	if (vproc < inter_vproc || vproc < pre_vproc) {297		ret = mtk_cpufreq_set_voltage(info, vproc);298		if (ret) {299			dev_err(cpu_dev,300				"cpu%d: failed to scale down voltage!\n", policy->cpu);301			clk_set_parent(cpu_clk, info->inter_clk);302			clk_set_rate(armpll, pre_freq_hz);303			clk_set_parent(cpu_clk, armpll);304			goto out;305		}306	}307 308	info->current_freq = freq_hz;309 310out:311	mutex_unlock(&info->reg_lock);312 313	return ret;314}315 316static int mtk_cpufreq_opp_notifier(struct notifier_block *nb,317				    unsigned long event, void *data)318{319	struct dev_pm_opp *opp = data;320	struct dev_pm_opp *new_opp;321	struct mtk_cpu_dvfs_info *info;322	unsigned long freq, volt;323	struct cpufreq_policy *policy;324	int ret = 0;325 326	info = container_of(nb, struct mtk_cpu_dvfs_info, opp_nb);327 328	if (event == OPP_EVENT_ADJUST_VOLTAGE) {329		freq = dev_pm_opp_get_freq(opp);330 331		mutex_lock(&info->reg_lock);332		if (info->current_freq == freq) {333			volt = dev_pm_opp_get_voltage(opp);334			ret = mtk_cpufreq_set_voltage(info, volt);335			if (ret)336				dev_err(info->cpu_dev,337					"failed to scale voltage: %d\n", ret);338		}339		mutex_unlock(&info->reg_lock);340	} else if (event == OPP_EVENT_DISABLE) {341		freq = dev_pm_opp_get_freq(opp);342 343		/* case of current opp item is disabled */344		if (info->current_freq == freq) {345			freq = 1;346			new_opp = dev_pm_opp_find_freq_ceil(info->cpu_dev,347							    &freq);348			if (IS_ERR(new_opp)) {349				dev_err(info->cpu_dev,350					"all opp items are disabled\n");351				ret = PTR_ERR(new_opp);352				return notifier_from_errno(ret);353			}354 355			dev_pm_opp_put(new_opp);356			policy = cpufreq_cpu_get(info->opp_cpu);357			if (policy) {358				cpufreq_driver_target(policy, freq / 1000,359						      CPUFREQ_RELATION_L);360				cpufreq_cpu_put(policy);361			}362		}363	}364 365	return notifier_from_errno(ret);366}367 368static struct device *of_get_cci(struct device *cpu_dev)369{370	struct device_node *np;371	struct platform_device *pdev;372 373	np = of_parse_phandle(cpu_dev->of_node, "mediatek,cci", 0);374	if (!np)375		return ERR_PTR(-ENODEV);376 377	pdev = of_find_device_by_node(np);378	of_node_put(np);379	if (!pdev)380		return ERR_PTR(-ENODEV);381 382	return &pdev->dev;383}384 385static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)386{387	struct device *cpu_dev;388	struct dev_pm_opp *opp;389	unsigned long rate;390	int ret;391 392	cpu_dev = get_cpu_device(cpu);393	if (!cpu_dev)394		return dev_err_probe(cpu_dev, -ENODEV, "failed to get cpu%d device\n", cpu);395	info->cpu_dev = cpu_dev;396 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),402					     "cpu%d: failed to get cci device\n",403					     cpu);404	}405 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),409				     "cpu%d: failed to get cpu clk\n", cpu);410 411	info->inter_clk = clk_get(cpu_dev, "intermediate");412	if (IS_ERR(info->inter_clk)) {413		ret = PTR_ERR(info->inter_clk);414		dev_err_probe(cpu_dev, ret,415			      "cpu%d: failed to get intermediate clk\n", cpu);416		goto out_free_mux_clock;417	}418 419	info->proc_reg = regulator_get_optional(cpu_dev, "proc");420	if (IS_ERR(info->proc_reg)) {421		ret = PTR_ERR(info->proc_reg);422		dev_err_probe(cpu_dev, ret,423			      "cpu%d: failed to get proc regulator\n", cpu);424		goto out_free_inter_clock;425	}426 427	ret = regulator_enable(info->proc_reg);428	if (ret) {429		dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable vproc\n", cpu);430		goto out_free_proc_reg;431	}432 433	/* Both presence and absence of sram regulator are valid cases. */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) {438			dev_err_probe(cpu_dev, ret,439				      "cpu%d: Failed to get sram regulator\n", cpu);440			goto out_disable_proc_reg;441		}442 443		info->sram_reg = NULL;444	} else {445		ret = regulator_enable(info->sram_reg);446		if (ret) {447			dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable vsram\n", cpu);448			goto out_free_sram_reg;449		}450	}451 452	/* Get OPP-sharing information from "operating-points-v2" bindings */453	ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus);454	if (ret) {455		dev_err_probe(cpu_dev, ret,456			"cpu%d: failed to get OPP-sharing information\n", cpu);457		goto out_disable_sram_reg;458	}459 460	ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);461	if (ret) {462		dev_err_probe(cpu_dev, ret, "cpu%d: no OPP table\n", cpu);463		goto out_disable_sram_reg;464	}465 466	ret = clk_prepare_enable(info->cpu_clk);467	if (ret) {468		dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable cpu clk\n", cpu);469		goto out_free_opp_table;470	}471 472	ret = clk_prepare_enable(info->inter_clk);473	if (ret) {474		dev_err_probe(cpu_dev, ret, "cpu%d: failed to enable inter clk\n", cpu);475		goto out_disable_mux_clock;476	}477 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,482					    "invalid Vproc value\n");483			goto out_disable_inter_clock;484		}485	}486 487	/* Search a safe voltage for intermediate frequency. */488	rate = clk_get_rate(info->inter_clk);489	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);490	if (IS_ERR(opp)) {491		ret = dev_err_probe(cpu_dev, PTR_ERR(opp),492				    "cpu%d: failed to get intermediate opp\n", cpu);493		goto out_disable_inter_clock;494	}495	info->intermediate_voltage = dev_pm_opp_get_voltage(opp);496	dev_pm_opp_put(opp);497 498	mutex_init(&info->reg_lock);499	info->current_freq = clk_get_rate(info->cpu_clk);500 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);504	if (ret) {505		dev_err_probe(cpu_dev, ret, "cpu%d: failed to register opp notifier\n", cpu);506		goto out_disable_inter_clock;507	}508 509	/*510	 * If SRAM regulator is present, software "voltage tracking" is needed511	 * for this CPU power domain.512	 */513	info->need_voltage_tracking = (info->sram_reg != NULL);514 515	/*516	 * We assume min voltage is 0 and tracking target voltage using517	 * min_volt_shift for each iteration.518	 * The vtrack_max is 3 times of expeted iteration count.519	 */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);523 524	return 0;525 526out_disable_inter_clock:527	clk_disable_unprepare(info->inter_clk);528 529out_disable_mux_clock:530	clk_disable_unprepare(info->cpu_clk);531 532out_free_opp_table:533	dev_pm_opp_of_cpumask_remove_table(&info->cpus);534 535out_disable_sram_reg:536	if (info->sram_reg)537		regulator_disable(info->sram_reg);538 539out_free_sram_reg:540	if (info->sram_reg)541		regulator_put(info->sram_reg);542 543out_disable_proc_reg:544	regulator_disable(info->proc_reg);545 546out_free_proc_reg:547	regulator_put(info->proc_reg);548 549out_free_inter_clock:550	clk_put(info->inter_clk);551 552out_free_mux_clock:553	clk_put(info->cpu_clk);554 555	return ret;556}557 558static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)559{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);565	}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);572}573 574static int mtk_cpufreq_init(struct cpufreq_policy *policy)575{576	struct mtk_cpu_dvfs_info *info;577	struct cpufreq_frequency_table *freq_table;578	int ret;579 580	info = mtk_cpu_dvfs_info_lookup(policy->cpu);581	if (!info) {582		pr_err("dvfs info for cpu%d is not initialized.\n",583			policy->cpu);584		return -EINVAL;585	}586 587	ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);588	if (ret) {589		dev_err(info->cpu_dev,590			"failed to init cpufreq table for cpu%d: %d\n",591			policy->cpu, ret);592		return ret;593	}594 595	cpumask_copy(policy->cpus, &info->cpus);596	policy->freq_table = freq_table;597	policy->driver_data = info;598	policy->clk = info->cpu_clk;599 600	return 0;601}602 603static void mtk_cpufreq_exit(struct cpufreq_policy *policy)604{605	struct mtk_cpu_dvfs_info *info = policy->driver_data;606 607	dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);608}609 610static struct cpufreq_driver mtk_cpufreq_driver = {611	.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |612		 CPUFREQ_HAVE_GOVERNOR_PER_POLICY |613		 CPUFREQ_IS_COOLING_DEV,614	.verify = cpufreq_generic_frequency_table_verify,615	.target_index = mtk_cpufreq_set_target,616	.get = cpufreq_generic_get,617	.init = mtk_cpufreq_init,618	.exit = mtk_cpufreq_exit,619	.register_em = cpufreq_register_em_with_opp,620	.name = "mtk-cpufreq",621	.attr = cpufreq_generic_attr,622};623 624static int mtk_cpufreq_probe(struct platform_device *pdev)625{626	const struct mtk_cpufreq_platform_data *data;627	struct mtk_cpu_dvfs_info *info, *tmp;628	int cpu, ret;629 630	data = dev_get_platdata(&pdev->dev);631	if (!data)632		return dev_err_probe(&pdev->dev, -ENODEV,633				     "failed to get mtk cpufreq platform data\n");634 635	for_each_possible_cpu(cpu) {636		info = mtk_cpu_dvfs_info_lookup(cpu);637		if (info)638			continue;639 640		info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);641		if (!info) {642			ret = dev_err_probe(&pdev->dev, -ENOMEM,643					    "Failed to allocate dvfs_info\n");644			goto release_dvfs_info_list;645		}646 647		info->soc_data = data;648		ret = mtk_cpu_dvfs_info_init(info, cpu);649		if (ret)650			goto release_dvfs_info_list;651 652		list_add(&info->list_head, &dvfs_info_list);653	}654 655	ret = cpufreq_register_driver(&mtk_cpufreq_driver);656	if (ret) {657		dev_err_probe(&pdev->dev, ret, "failed to register mtk cpufreq driver\n");658		goto release_dvfs_info_list;659	}660 661	return 0;662 663release_dvfs_info_list:664	list_for_each_entry_safe(info, tmp, &dvfs_info_list, list_head) {665		mtk_cpu_dvfs_info_release(info);666		list_del(&info->list_head);667	}668 669	return ret;670}671 672static struct platform_driver mtk_cpufreq_platdrv = {673	.driver = {674		.name	= "mtk-cpufreq",675	},676	.probe		= mtk_cpufreq_probe,677};678 679static const struct mtk_cpufreq_platform_data mt2701_platform_data = {680	.min_volt_shift = 100000,681	.max_volt_shift = 200000,682	.proc_max_volt = 1150000,683	.sram_min_volt = 0,684	.sram_max_volt = 1150000,685	.ccifreq_supported = false,686};687 688static const struct mtk_cpufreq_platform_data mt7622_platform_data = {689	.min_volt_shift = 100000,690	.max_volt_shift = 200000,691	.proc_max_volt = 1350000,692	.sram_min_volt = 0,693	.sram_max_volt = 1350000,694	.ccifreq_supported = false,695};696 697static const struct mtk_cpufreq_platform_data mt7623_platform_data = {698	.min_volt_shift = 100000,699	.max_volt_shift = 200000,700	.proc_max_volt = 1300000,701	.ccifreq_supported = false,702};703 704static const struct mtk_cpufreq_platform_data mt7988_platform_data = {705	.min_volt_shift = 100000,706	.max_volt_shift = 200000,707	.proc_max_volt = 900000,708	.sram_min_volt = 0,709	.sram_max_volt = 1150000,710	.ccifreq_supported = true,711};712 713static const struct mtk_cpufreq_platform_data mt8183_platform_data = {714	.min_volt_shift = 100000,715	.max_volt_shift = 200000,716	.proc_max_volt = 1150000,717	.sram_min_volt = 0,718	.sram_max_volt = 1150000,719	.ccifreq_supported = true,720};721 722static const struct mtk_cpufreq_platform_data mt8186_platform_data = {723	.min_volt_shift = 100000,724	.max_volt_shift = 250000,725	.proc_max_volt = 1118750,726	.sram_min_volt = 850000,727	.sram_max_volt = 1118750,728	.ccifreq_supported = true,729};730 731static const struct mtk_cpufreq_platform_data mt8516_platform_data = {732	.min_volt_shift = 100000,733	.max_volt_shift = 200000,734	.proc_max_volt = 1310000,735	.sram_min_volt = 0,736	.sram_max_volt = 1310000,737	.ccifreq_supported = false,738};739 740/* List of machines supported by this driver */741static const struct of_device_id mtk_cpufreq_machines[] __initconst __maybe_unused = {742	{ .compatible = "mediatek,mt2701", .data = &mt2701_platform_data },743	{ .compatible = "mediatek,mt2712", .data = &mt2701_platform_data },744	{ .compatible = "mediatek,mt7622", .data = &mt7622_platform_data },745	{ .compatible = "mediatek,mt7623", .data = &mt7623_platform_data },746	{ .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data },747	{ .compatible = "mediatek,mt8167", .data = &mt8516_platform_data },748	{ .compatible = "mediatek,mt817x", .data = &mt2701_platform_data },749	{ .compatible = "mediatek,mt8173", .data = &mt2701_platform_data },750	{ .compatible = "mediatek,mt8176", .data = &mt2701_platform_data },751	{ .compatible = "mediatek,mt8183", .data = &mt8183_platform_data },752	{ .compatible = "mediatek,mt8186", .data = &mt8186_platform_data },753	{ .compatible = "mediatek,mt8365", .data = &mt2701_platform_data },754	{ .compatible = "mediatek,mt8516", .data = &mt8516_platform_data },755	{ }756};757MODULE_DEVICE_TABLE(of, mtk_cpufreq_machines);758 759static int __init mtk_cpufreq_driver_init(void)760{761	struct device_node *np;762	const struct of_device_id *match;763	const struct mtk_cpufreq_platform_data *data;764	int err;765 766	np = of_find_node_by_path("/");767	if (!np)768		return -ENODEV;769 770	match = of_match_node(mtk_cpufreq_machines, np);771	of_node_put(np);772	if (!match) {773		pr_debug("Machine is not compatible with mtk-cpufreq\n");774		return -ENODEV;775	}776	data = match->data;777 778	err = platform_driver_register(&mtk_cpufreq_platdrv);779	if (err)780		return err;781 782	/*783	 * Since there's no place to hold device registration code and no784	 * device tree based way to match cpufreq driver yet, both the driver785	 * and the device registration codes are put here to handle defer786	 * probing.787	 */788	cpufreq_pdev = platform_device_register_data(NULL, "mtk-cpufreq", -1,789						     data, sizeof(*data));790	if (IS_ERR(cpufreq_pdev)) {791		pr_err("failed to register mtk-cpufreq platform device\n");792		platform_driver_unregister(&mtk_cpufreq_platdrv);793		return PTR_ERR(cpufreq_pdev);794	}795 796	return 0;797}798module_init(mtk_cpufreq_driver_init)799 800static void __exit mtk_cpufreq_driver_exit(void)801{802	platform_device_unregister(cpufreq_pdev);803	platform_driver_unregister(&mtk_cpufreq_platdrv);804}805module_exit(mtk_cpufreq_driver_exit)806 807MODULE_DESCRIPTION("MediaTek CPUFreq driver");808MODULE_AUTHOR("Pi-Cheng Chen <pi-cheng.chen@linaro.org>");809MODULE_LICENSE("GPL v2");810