1010#include <linux/cpumask.h>
1111#include <linux/module.h>
1212#include <linux/of.h>
13+ #include <linux/of_platform.h>
1314#include <linux/platform_device.h>
1415#include <linux/pm_opp.h>
1516#include <linux/regulator/consumer.h>
1617
17- #define MIN_VOLT_SHIFT (100000)
18- #define MAX_VOLT_SHIFT (200000)
19- #define MAX_VOLT_LIMIT (1150000)
2018#define VOLT_TOL (10000)
2119
20+ struct mtk_cpufreq_platform_data {
21+ int min_volt_shift ;
22+ int max_volt_shift ;
23+ int proc_max_volt ;
24+ int sram_min_volt ;
25+ int sram_max_volt ;
26+ };
27+
2228/*
2329 * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS
2430 * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
@@ -41,6 +47,7 @@ struct mtk_cpu_dvfs_info {
4147 int intermediate_voltage ;
4248 bool need_voltage_tracking ;
4349 int pre_vproc ;
50+ const struct mtk_cpufreq_platform_data * soc_data ;
4451};
4552
4653static struct platform_device * cpufreq_pdev ;
@@ -62,6 +69,7 @@ static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu)
6269static int mtk_cpufreq_voltage_tracking (struct mtk_cpu_dvfs_info * info ,
6370 int new_vproc )
6471{
72+ const struct mtk_cpufreq_platform_data * soc_data = info -> soc_data ;
6573 struct regulator * proc_reg = info -> proc_reg ;
6674 struct regulator * sram_reg = info -> sram_reg ;
6775 int pre_vproc , pre_vsram , new_vsram , vsram , vproc , ret ;
@@ -73,7 +81,8 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
7381 return pre_vproc ;
7482 }
7583 /* Vsram should not exceed the maximum allowed voltage of SoC. */
76- new_vsram = min (new_vproc + MIN_VOLT_SHIFT , MAX_VOLT_LIMIT );
84+ new_vsram = min (new_vproc + soc_data -> min_volt_shift ,
85+ soc_data -> sram_max_volt );
7786
7887 if (pre_vproc < new_vproc ) {
7988 /*
@@ -96,10 +105,11 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
96105 return pre_vproc ;
97106 }
98107
99- vsram = min (new_vsram , pre_vproc + MAX_VOLT_SHIFT );
108+ vsram = min (new_vsram ,
109+ pre_vproc + soc_data -> min_volt_shift );
100110
101- if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT ) {
102- vsram = MAX_VOLT_LIMIT ;
111+ if (vsram + VOLT_TOL >= soc_data -> sram_max_volt ) {
112+ vsram = soc_data -> sram_max_volt ;
103113
104114 /*
105115 * If the target Vsram hits the maximum voltage,
@@ -117,7 +127,7 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
117127 ret = regulator_set_voltage (sram_reg , vsram ,
118128 vsram + VOLT_TOL );
119129
120- vproc = vsram - MIN_VOLT_SHIFT ;
130+ vproc = vsram - soc_data -> min_volt_shift ;
121131 }
122132 if (ret )
123133 return ret ;
@@ -151,7 +161,8 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
151161 return pre_vsram ;
152162 }
153163
154- vproc = max (new_vproc , pre_vsram - MAX_VOLT_SHIFT );
164+ vproc = max (new_vproc ,
165+ pre_vsram - soc_data -> max_volt_shift );
155166 ret = regulator_set_voltage (proc_reg , vproc ,
156167 vproc + VOLT_TOL );
157168 if (ret )
@@ -160,10 +171,11 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
160171 if (vproc == new_vproc )
161172 vsram = new_vsram ;
162173 else
163- vsram = max (new_vsram , vproc + MIN_VOLT_SHIFT );
174+ vsram = max (new_vsram ,
175+ vproc + soc_data -> min_volt_shift );
164176
165- if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT ) {
166- vsram = MAX_VOLT_LIMIT ;
177+ if (vsram + VOLT_TOL >= soc_data -> sram_max_volt ) {
178+ vsram = soc_data -> sram_max_volt ;
167179
168180 /*
169181 * If the target Vsram hits the maximum voltage,
@@ -194,13 +206,14 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
194206
195207static int mtk_cpufreq_set_voltage (struct mtk_cpu_dvfs_info * info , int vproc )
196208{
209+ const struct mtk_cpufreq_platform_data * soc_data = info -> soc_data ;
197210 int ret ;
198211
199212 if (info -> need_voltage_tracking )
200213 ret = mtk_cpufreq_voltage_tracking (info , vproc );
201214 else
202215 ret = regulator_set_voltage (info -> proc_reg , vproc ,
203- MAX_VOLT_LIMIT );
216+ soc_data -> proc_max_volt );
204217 if (!ret )
205218 info -> pre_vproc = vproc ;
206219
@@ -509,9 +522,17 @@ static struct cpufreq_driver mtk_cpufreq_driver = {
509522
510523static int mtk_cpufreq_probe (struct platform_device * pdev )
511524{
525+ const struct mtk_cpufreq_platform_data * data ;
512526 struct mtk_cpu_dvfs_info * info , * tmp ;
513527 int cpu , ret ;
514528
529+ data = dev_get_platdata (& pdev -> dev );
530+ if (!data ) {
531+ dev_err (& pdev -> dev ,
532+ "failed to get mtk cpufreq platform data\n" );
533+ return - ENODEV ;
534+ }
535+
515536 for_each_possible_cpu (cpu ) {
516537 info = mtk_cpu_dvfs_info_lookup (cpu );
517538 if (info )
@@ -523,6 +544,7 @@ static int mtk_cpufreq_probe(struct platform_device *pdev)
523544 goto release_dvfs_info_list ;
524545 }
525546
547+ info -> soc_data = data ;
526548 ret = mtk_cpu_dvfs_info_init (info , cpu );
527549 if (ret ) {
528550 dev_err (& pdev -> dev ,
@@ -558,20 +580,27 @@ static struct platform_driver mtk_cpufreq_platdrv = {
558580 .probe = mtk_cpufreq_probe ,
559581};
560582
583+ static const struct mtk_cpufreq_platform_data mt2701_platform_data = {
584+ .min_volt_shift = 100000 ,
585+ .max_volt_shift = 200000 ,
586+ .proc_max_volt = 1150000 ,
587+ .sram_min_volt = 0 ,
588+ .sram_max_volt = 1150000 ,
589+ };
590+
561591/* List of machines supported by this driver */
562592static const struct of_device_id mtk_cpufreq_machines [] __initconst = {
563- { .compatible = "mediatek,mt2701" , },
564- { .compatible = "mediatek,mt2712" , },
565- { .compatible = "mediatek,mt7622" , },
566- { .compatible = "mediatek,mt7623" , },
567- { .compatible = "mediatek,mt8167" , },
568- { .compatible = "mediatek,mt817x" , },
569- { .compatible = "mediatek,mt8173" , },
570- { .compatible = "mediatek,mt8176" , },
571- { .compatible = "mediatek,mt8183" , },
572- { .compatible = "mediatek,mt8365" , },
573- { .compatible = "mediatek,mt8516" , },
574-
593+ { .compatible = "mediatek,mt2701" , .data = & mt2701_platform_data },
594+ { .compatible = "mediatek,mt2712" , .data = & mt2701_platform_data },
595+ { .compatible = "mediatek,mt7622" , .data = & mt2701_platform_data },
596+ { .compatible = "mediatek,mt7623" , .data = & mt2701_platform_data },
597+ { .compatible = "mediatek,mt8167" , .data = & mt2701_platform_data },
598+ { .compatible = "mediatek,mt817x" , .data = & mt2701_platform_data },
599+ { .compatible = "mediatek,mt8173" , .data = & mt2701_platform_data },
600+ { .compatible = "mediatek,mt8176" , .data = & mt2701_platform_data },
601+ { .compatible = "mediatek,mt8183" , .data = & mt2701_platform_data },
602+ { .compatible = "mediatek,mt8365" , .data = & mt2701_platform_data },
603+ { .compatible = "mediatek,mt8516" , .data = & mt2701_platform_data },
575604 { }
576605};
577606MODULE_DEVICE_TABLE (of , mtk_cpufreq_machines );
@@ -580,6 +609,7 @@ static int __init mtk_cpufreq_driver_init(void)
580609{
581610 struct device_node * np ;
582611 const struct of_device_id * match ;
612+ const struct mtk_cpufreq_platform_data * data ;
583613 int err ;
584614
585615 np = of_find_node_by_path ("/" );
@@ -592,6 +622,7 @@ static int __init mtk_cpufreq_driver_init(void)
592622 pr_debug ("Machine is not compatible with mtk-cpufreq\n" );
593623 return - ENODEV ;
594624 }
625+ data = match -> data ;
595626
596627 err = platform_driver_register (& mtk_cpufreq_platdrv );
597628 if (err )
@@ -603,7 +634,8 @@ static int __init mtk_cpufreq_driver_init(void)
603634 * and the device registration codes are put here to handle defer
604635 * probing.
605636 */
606- cpufreq_pdev = platform_device_register_simple ("mtk-cpufreq" , -1 , NULL , 0 );
637+ cpufreq_pdev = platform_device_register_data (NULL , "mtk-cpufreq" , -1 ,
638+ data , sizeof (* data ));
607639 if (IS_ERR (cpufreq_pdev )) {
608640 pr_err ("failed to register mtk-cpufreq platform device\n" );
609641 platform_driver_unregister (& mtk_cpufreq_platdrv );
0 commit comments