mt8173-cpufreq.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. * Copyright (c) 2015 Linaro Ltd.
  3. * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/clk.h>
  15. #include <linux/cpu.h>
  16. #include <linux/cpu_cooling.h>
  17. #include <linux/cpufreq.h>
  18. #include <linux/cpumask.h>
  19. #include <linux/module.h>
  20. #include <linux/of.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/pm_opp.h>
  23. #include <linux/regulator/consumer.h>
  24. #include <linux/slab.h>
  25. #include <linux/thermal.h>
  26. #define MIN_VOLT_SHIFT (100000)
  27. #define MAX_VOLT_SHIFT (200000)
  28. #define MAX_VOLT_LIMIT (1150000)
  29. #define VOLT_TOL (10000)
  30. /*
  31. * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS
  32. * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
  33. * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two
  34. * voltage inputs need to be controlled under a hardware limitation:
  35. * 100mV < Vsram - Vproc < 200mV
  36. *
  37. * When scaling the clock frequency of a CPU clock domain, the clock source
  38. * needs to be switched to another stable PLL clock temporarily until
  39. * the original PLL becomes stable at target frequency.
  40. */
  41. struct mtk_cpu_dvfs_info {
  42. struct cpumask cpus;
  43. struct device *cpu_dev;
  44. struct regulator *proc_reg;
  45. struct regulator *sram_reg;
  46. struct clk *cpu_clk;
  47. struct clk *inter_clk;
  48. struct thermal_cooling_device *cdev;
  49. struct list_head list_head;
  50. int intermediate_voltage;
  51. bool need_voltage_tracking;
  52. };
  53. static LIST_HEAD(dvfs_info_list);
  54. static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu)
  55. {
  56. struct mtk_cpu_dvfs_info *info;
  57. list_for_each_entry(info, &dvfs_info_list, list_head) {
  58. if (cpumask_test_cpu(cpu, &info->cpus))
  59. return info;
  60. }
  61. return NULL;
  62. }
  63. static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
  64. int new_vproc)
  65. {
  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;
  69. old_vproc = regulator_get_voltage(proc_reg);
  70. if (old_vproc < 0) {
  71. pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
  72. return old_vproc;
  73. }
  74. /* Vsram should not exceed the maximum allowed voltage of SoC. */
  75. new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT);
  76. if (old_vproc < new_vproc) {
  77. /*
  78. * When scaling up voltages, Vsram and Vproc scale up step
  79. * by step. At each step, set Vsram to (Vproc + 200mV) first,
  80. * then set Vproc to (Vsram - 100mV).
  81. * Keep doing it until Vsram and Vproc hit target voltages.
  82. */
  83. do {
  84. old_vsram = regulator_get_voltage(sram_reg);
  85. if (old_vsram < 0) {
  86. pr_err("%s: invalid Vsram value: %d\n",
  87. __func__, old_vsram);
  88. return old_vsram;
  89. }
  90. old_vproc = regulator_get_voltage(proc_reg);
  91. if (old_vproc < 0) {
  92. pr_err("%s: invalid Vproc value: %d\n",
  93. __func__, old_vproc);
  94. return old_vproc;
  95. }
  96. vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT);
  97. if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
  98. vsram = MAX_VOLT_LIMIT;
  99. /*
  100. * If the target Vsram hits the maximum voltage,
  101. * try to set the exact voltage value first.
  102. */
  103. ret = regulator_set_voltage(sram_reg, vsram,
  104. vsram);
  105. if (ret)
  106. ret = regulator_set_voltage(sram_reg,
  107. vsram - VOLT_TOL,
  108. vsram);
  109. vproc = new_vproc;
  110. } else {
  111. ret = regulator_set_voltage(sram_reg, vsram,
  112. vsram + VOLT_TOL);
  113. vproc = vsram - MIN_VOLT_SHIFT;
  114. }
  115. if (ret)
  116. return ret;
  117. ret = regulator_set_voltage(proc_reg, vproc,
  118. vproc + VOLT_TOL);
  119. if (ret) {
  120. regulator_set_voltage(sram_reg, old_vsram,
  121. old_vsram);
  122. return ret;
  123. }
  124. } while (vproc < new_vproc || vsram < new_vsram);
  125. } else if (old_vproc > new_vproc) {
  126. /*
  127. * When scaling down voltages, Vsram and Vproc scale down step
  128. * by step. At each step, set Vproc to (Vsram - 200mV) first,
  129. * then set Vproc to (Vproc + 100mV).
  130. * Keep doing it until Vsram and Vproc hit target voltages.
  131. */
  132. do {
  133. old_vproc = regulator_get_voltage(proc_reg);
  134. if (old_vproc < 0) {
  135. pr_err("%s: invalid Vproc value: %d\n",
  136. __func__, old_vproc);
  137. return old_vproc;
  138. }
  139. old_vsram = regulator_get_voltage(sram_reg);
  140. if (old_vsram < 0) {
  141. pr_err("%s: invalid Vsram value: %d\n",
  142. __func__, old_vsram);
  143. return old_vsram;
  144. }
  145. vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT);
  146. ret = regulator_set_voltage(proc_reg, vproc,
  147. vproc + VOLT_TOL);
  148. if (ret)
  149. return ret;
  150. if (vproc == new_vproc)
  151. vsram = new_vsram;
  152. else
  153. vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT);
  154. if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
  155. vsram = MAX_VOLT_LIMIT;
  156. /*
  157. * If the target Vsram hits the maximum voltage,
  158. * try to set the exact voltage value first.
  159. */
  160. ret = regulator_set_voltage(sram_reg, vsram,
  161. vsram);
  162. if (ret)
  163. ret = regulator_set_voltage(sram_reg,
  164. vsram - VOLT_TOL,
  165. vsram);
  166. } else {
  167. ret = regulator_set_voltage(sram_reg, vsram,
  168. vsram + VOLT_TOL);
  169. }
  170. if (ret) {
  171. regulator_set_voltage(proc_reg, old_vproc,
  172. old_vproc);
  173. return ret;
  174. }
  175. } while (vproc > new_vproc + VOLT_TOL ||
  176. vsram > new_vsram + VOLT_TOL);
  177. }
  178. return 0;
  179. }
  180. static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
  181. {
  182. if (info->need_voltage_tracking)
  183. return mtk_cpufreq_voltage_tracking(info, vproc);
  184. else
  185. return regulator_set_voltage(info->proc_reg, vproc,
  186. vproc + VOLT_TOL);
  187. }
  188. static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
  189. unsigned int index)
  190. {
  191. struct cpufreq_frequency_table *freq_table = policy->freq_table;
  192. struct clk *cpu_clk = policy->clk;
  193. struct clk *armpll = clk_get_parent(cpu_clk);
  194. struct mtk_cpu_dvfs_info *info = policy->driver_data;
  195. struct device *cpu_dev = info->cpu_dev;
  196. struct dev_pm_opp *opp;
  197. long freq_hz, old_freq_hz;
  198. int vproc, old_vproc, inter_vproc, target_vproc, ret;
  199. inter_vproc = info->intermediate_voltage;
  200. old_freq_hz = clk_get_rate(cpu_clk);
  201. old_vproc = regulator_get_voltage(info->proc_reg);
  202. if (old_vproc < 0) {
  203. pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
  204. return old_vproc;
  205. }
  206. freq_hz = freq_table[index].frequency * 1000;
  207. opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  208. if (IS_ERR(opp)) {
  209. pr_err("cpu%d: failed to find OPP for %ld\n",
  210. policy->cpu, freq_hz);
  211. return PTR_ERR(opp);
  212. }
  213. vproc = dev_pm_opp_get_voltage(opp);
  214. dev_pm_opp_put(opp);
  215. /*
  216. * If the new voltage or the intermediate voltage is higher than the
  217. * current voltage, scale up voltage first.
  218. */
  219. target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
  220. if (old_vproc < target_vproc) {
  221. ret = mtk_cpufreq_set_voltage(info, target_vproc);
  222. if (ret) {
  223. pr_err("cpu%d: failed to scale up voltage!\n",
  224. policy->cpu);
  225. mtk_cpufreq_set_voltage(info, old_vproc);
  226. return ret;
  227. }
  228. }
  229. /* Reparent the CPU clock to intermediate clock. */
  230. ret = clk_set_parent(cpu_clk, info->inter_clk);
  231. if (ret) {
  232. pr_err("cpu%d: failed to re-parent cpu clock!\n",
  233. policy->cpu);
  234. mtk_cpufreq_set_voltage(info, old_vproc);
  235. WARN_ON(1);
  236. return ret;
  237. }
  238. /* Set the original PLL to target rate. */
  239. ret = clk_set_rate(armpll, freq_hz);
  240. if (ret) {
  241. pr_err("cpu%d: failed to scale cpu clock rate!\n",
  242. policy->cpu);
  243. clk_set_parent(cpu_clk, armpll);
  244. mtk_cpufreq_set_voltage(info, old_vproc);
  245. return ret;
  246. }
  247. /* Set parent of CPU clock back to the original PLL. */
  248. ret = clk_set_parent(cpu_clk, armpll);
  249. if (ret) {
  250. pr_err("cpu%d: failed to re-parent cpu clock!\n",
  251. policy->cpu);
  252. mtk_cpufreq_set_voltage(info, inter_vproc);
  253. WARN_ON(1);
  254. return ret;
  255. }
  256. /*
  257. * If the new voltage is lower than the intermediate voltage or the
  258. * original voltage, scale down to the new voltage.
  259. */
  260. if (vproc < inter_vproc || vproc < old_vproc) {
  261. ret = mtk_cpufreq_set_voltage(info, vproc);
  262. if (ret) {
  263. pr_err("cpu%d: failed to scale down voltage!\n",
  264. policy->cpu);
  265. clk_set_parent(cpu_clk, info->inter_clk);
  266. clk_set_rate(armpll, old_freq_hz);
  267. clk_set_parent(cpu_clk, armpll);
  268. return ret;
  269. }
  270. }
  271. return 0;
  272. }
  273. #define DYNAMIC_POWER "dynamic-power-coefficient"
  274. static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
  275. {
  276. struct mtk_cpu_dvfs_info *info = policy->driver_data;
  277. struct device_node *np = of_node_get(info->cpu_dev->of_node);
  278. u32 capacitance = 0;
  279. if (WARN_ON(!np))
  280. return;
  281. if (of_find_property(np, "#cooling-cells", NULL)) {
  282. of_property_read_u32(np, DYNAMIC_POWER, &capacitance);
  283. info->cdev = of_cpufreq_power_cooling_register(np,
  284. policy->related_cpus,
  285. capacitance,
  286. NULL);
  287. if (IS_ERR(info->cdev)) {
  288. dev_err(info->cpu_dev,
  289. "running cpufreq without cooling device: %ld\n",
  290. PTR_ERR(info->cdev));
  291. info->cdev = NULL;
  292. }
  293. }
  294. of_node_put(np);
  295. }
  296. static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
  297. {
  298. struct device *cpu_dev;
  299. struct regulator *proc_reg = ERR_PTR(-ENODEV);
  300. struct regulator *sram_reg = ERR_PTR(-ENODEV);
  301. struct clk *cpu_clk = ERR_PTR(-ENODEV);
  302. struct clk *inter_clk = ERR_PTR(-ENODEV);
  303. struct dev_pm_opp *opp;
  304. unsigned long rate;
  305. int ret;
  306. cpu_dev = get_cpu_device(cpu);
  307. if (!cpu_dev) {
  308. pr_err("failed to get cpu%d device\n", cpu);
  309. return -ENODEV;
  310. }
  311. cpu_clk = clk_get(cpu_dev, "cpu");
  312. if (IS_ERR(cpu_clk)) {
  313. if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
  314. pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
  315. else
  316. pr_err("failed to get cpu clk for cpu%d\n", cpu);
  317. ret = PTR_ERR(cpu_clk);
  318. return ret;
  319. }
  320. inter_clk = clk_get(cpu_dev, "intermediate");
  321. if (IS_ERR(inter_clk)) {
  322. if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
  323. pr_warn("intermediate clk for cpu%d not ready, retry.\n",
  324. cpu);
  325. else
  326. pr_err("failed to get intermediate clk for cpu%d\n",
  327. cpu);
  328. ret = PTR_ERR(inter_clk);
  329. goto out_free_resources;
  330. }
  331. proc_reg = regulator_get_exclusive(cpu_dev, "proc");
  332. if (IS_ERR(proc_reg)) {
  333. if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
  334. pr_warn("proc regulator for cpu%d not ready, retry.\n",
  335. cpu);
  336. else
  337. pr_err("failed to get proc regulator for cpu%d\n",
  338. cpu);
  339. ret = PTR_ERR(proc_reg);
  340. goto out_free_resources;
  341. }
  342. /* Both presence and absence of sram regulator are valid cases. */
  343. sram_reg = regulator_get_exclusive(cpu_dev, "sram");
  344. /* Get OPP-sharing information from "operating-points-v2" bindings */
  345. ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus);
  346. if (ret) {
  347. pr_err("failed to get OPP-sharing information for cpu%d\n",
  348. cpu);
  349. goto out_free_resources;
  350. }
  351. ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
  352. if (ret) {
  353. pr_warn("no OPP table for cpu%d\n", cpu);
  354. goto out_free_resources;
  355. }
  356. /* Search a safe voltage for intermediate frequency. */
  357. rate = clk_get_rate(inter_clk);
  358. opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
  359. if (IS_ERR(opp)) {
  360. pr_err("failed to get intermediate opp for cpu%d\n", cpu);
  361. ret = PTR_ERR(opp);
  362. goto out_free_opp_table;
  363. }
  364. info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
  365. dev_pm_opp_put(opp);
  366. info->cpu_dev = cpu_dev;
  367. info->proc_reg = proc_reg;
  368. info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg;
  369. info->cpu_clk = cpu_clk;
  370. info->inter_clk = inter_clk;
  371. /*
  372. * If SRAM regulator is present, software "voltage tracking" is needed
  373. * for this CPU power domain.
  374. */
  375. info->need_voltage_tracking = !IS_ERR(sram_reg);
  376. return 0;
  377. out_free_opp_table:
  378. dev_pm_opp_of_cpumask_remove_table(&info->cpus);
  379. out_free_resources:
  380. if (!IS_ERR(proc_reg))
  381. regulator_put(proc_reg);
  382. if (!IS_ERR(sram_reg))
  383. regulator_put(sram_reg);
  384. if (!IS_ERR(cpu_clk))
  385. clk_put(cpu_clk);
  386. if (!IS_ERR(inter_clk))
  387. clk_put(inter_clk);
  388. return ret;
  389. }
  390. static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
  391. {
  392. if (!IS_ERR(info->proc_reg))
  393. regulator_put(info->proc_reg);
  394. if (!IS_ERR(info->sram_reg))
  395. regulator_put(info->sram_reg);
  396. if (!IS_ERR(info->cpu_clk))
  397. clk_put(info->cpu_clk);
  398. if (!IS_ERR(info->inter_clk))
  399. clk_put(info->inter_clk);
  400. dev_pm_opp_of_cpumask_remove_table(&info->cpus);
  401. }
  402. static int mtk_cpufreq_init(struct cpufreq_policy *policy)
  403. {
  404. struct mtk_cpu_dvfs_info *info;
  405. struct cpufreq_frequency_table *freq_table;
  406. int ret;
  407. info = mtk_cpu_dvfs_info_lookup(policy->cpu);
  408. if (!info) {
  409. pr_err("dvfs info for cpu%d is not initialized.\n",
  410. policy->cpu);
  411. return -EINVAL;
  412. }
  413. ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
  414. if (ret) {
  415. pr_err("failed to init cpufreq table for cpu%d: %d\n",
  416. policy->cpu, ret);
  417. return ret;
  418. }
  419. ret = cpufreq_table_validate_and_show(policy, freq_table);
  420. if (ret) {
  421. pr_err("%s: invalid frequency table: %d\n", __func__, ret);
  422. goto out_free_cpufreq_table;
  423. }
  424. cpumask_copy(policy->cpus, &info->cpus);
  425. policy->driver_data = info;
  426. policy->clk = info->cpu_clk;
  427. return 0;
  428. out_free_cpufreq_table:
  429. dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
  430. return ret;
  431. }
  432. static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
  433. {
  434. struct mtk_cpu_dvfs_info *info = policy->driver_data;
  435. cpufreq_cooling_unregister(info->cdev);
  436. dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
  437. return 0;
  438. }
  439. static struct cpufreq_driver mt8173_cpufreq_driver = {
  440. .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
  441. CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
  442. .verify = cpufreq_generic_frequency_table_verify,
  443. .target_index = mtk_cpufreq_set_target,
  444. .get = cpufreq_generic_get,
  445. .init = mtk_cpufreq_init,
  446. .exit = mtk_cpufreq_exit,
  447. .ready = mtk_cpufreq_ready,
  448. .name = "mtk-cpufreq",
  449. .attr = cpufreq_generic_attr,
  450. };
  451. static int mt8173_cpufreq_probe(struct platform_device *pdev)
  452. {
  453. struct mtk_cpu_dvfs_info *info, *tmp;
  454. int cpu, ret;
  455. for_each_possible_cpu(cpu) {
  456. info = mtk_cpu_dvfs_info_lookup(cpu);
  457. if (info)
  458. continue;
  459. info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
  460. if (!info) {
  461. ret = -ENOMEM;
  462. goto release_dvfs_info_list;
  463. }
  464. ret = mtk_cpu_dvfs_info_init(info, cpu);
  465. if (ret) {
  466. dev_err(&pdev->dev,
  467. "failed to initialize dvfs info for cpu%d\n",
  468. cpu);
  469. goto release_dvfs_info_list;
  470. }
  471. list_add(&info->list_head, &dvfs_info_list);
  472. }
  473. ret = cpufreq_register_driver(&mt8173_cpufreq_driver);
  474. if (ret) {
  475. dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n");
  476. goto release_dvfs_info_list;
  477. }
  478. return 0;
  479. release_dvfs_info_list:
  480. list_for_each_entry_safe(info, tmp, &dvfs_info_list, list_head) {
  481. mtk_cpu_dvfs_info_release(info);
  482. list_del(&info->list_head);
  483. }
  484. return ret;
  485. }
  486. static struct platform_driver mt8173_cpufreq_platdrv = {
  487. .driver = {
  488. .name = "mt8173-cpufreq",
  489. },
  490. .probe = mt8173_cpufreq_probe,
  491. };
  492. /* List of machines supported by this driver */
  493. static const struct of_device_id mt8173_cpufreq_machines[] __initconst = {
  494. { .compatible = "mediatek,mt817x", },
  495. { .compatible = "mediatek,mt8173", },
  496. { .compatible = "mediatek,mt8176", },
  497. { }
  498. };
  499. static int __init mt8173_cpufreq_driver_init(void)
  500. {
  501. struct device_node *np;
  502. const struct of_device_id *match;
  503. struct platform_device *pdev;
  504. int err;
  505. np = of_find_node_by_path("/");
  506. if (!np)
  507. return -ENODEV;
  508. match = of_match_node(mt8173_cpufreq_machines, np);
  509. of_node_put(np);
  510. if (!match) {
  511. pr_warn("Machine is not compatible with mt8173-cpufreq\n");
  512. return -ENODEV;
  513. }
  514. err = platform_driver_register(&mt8173_cpufreq_platdrv);
  515. if (err)
  516. return err;
  517. /*
  518. * Since there's no place to hold device registration code and no
  519. * device tree based way to match cpufreq driver yet, both the driver
  520. * and the device registration codes are put here to handle defer
  521. * probing.
  522. */
  523. pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0);
  524. if (IS_ERR(pdev)) {
  525. pr_err("failed to register mtk-cpufreq platform device\n");
  526. return PTR_ERR(pdev);
  527. }
  528. return 0;
  529. }
  530. device_initcall(mt8173_cpufreq_driver_init);