@@ -22,6 +22,7 @@ struct mtk_cpufreq_platform_data {
2222 int proc_max_volt ;
2323 int sram_min_volt ;
2424 int sram_max_volt ;
25+ bool ccifreq_supported ;
2526};
2627
2728/*
@@ -38,13 +39,15 @@ struct mtk_cpufreq_platform_data {
3839struct mtk_cpu_dvfs_info {
3940 struct cpumask cpus ;
4041 struct device * cpu_dev ;
42+ struct device * cci_dev ;
4143 struct regulator * proc_reg ;
4244 struct regulator * sram_reg ;
4345 struct clk * cpu_clk ;
4446 struct clk * inter_clk ;
4547 struct list_head list_head ;
4648 int intermediate_voltage ;
4749 bool need_voltage_tracking ;
50+ int vproc_on_boot ;
4851 int pre_vproc ;
4952 /* Avoid race condition for regulators between notify and policy */
5053 struct mutex reg_lock ;
@@ -53,6 +56,7 @@ struct mtk_cpu_dvfs_info {
5356 unsigned long current_freq ;
5457 const struct mtk_cpufreq_platform_data * soc_data ;
5558 int vtrack_max ;
59+ bool ccifreq_bound ;
5660};
5761
5862static struct platform_device * cpufreq_pdev ;
@@ -171,6 +175,28 @@ static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
171175 return ret ;
172176}
173177
178+ static 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+
174200static int mtk_cpufreq_set_target (struct cpufreq_policy * policy ,
175201 unsigned int index )
176202{
@@ -212,6 +238,14 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
212238 vproc = dev_pm_opp_get_voltage (opp );
213239 dev_pm_opp_put (opp );
214240
241+ /*
242+ * If MediaTek cci is supported but is not ready, we will use the value
243+ * of max(target cpu voltage, booting voltage) to prevent high freqeuncy
244+ * low voltage crash.
245+ */
246+ if (info -> soc_data -> ccifreq_supported && !is_ccifreq_ready (info ))
247+ vproc = max (vproc , info -> vproc_on_boot );
248+
215249 /*
216250 * If the new voltage or the intermediate voltage is higher than the
217251 * current voltage, scale up voltage first.
@@ -333,6 +367,23 @@ static int mtk_cpufreq_opp_notifier(struct notifier_block *nb,
333367 return notifier_from_errno (ret );
334368}
335369
370+ static struct device * of_get_cci (struct device * cpu_dev )
371+ {
372+ struct device_node * np ;
373+ struct platform_device * pdev ;
374+
375+ np = of_parse_phandle (cpu_dev -> of_node , "mediatek,cci" , 0 );
376+ if (IS_ERR_OR_NULL (np ))
377+ return NULL ;
378+
379+ pdev = of_find_device_by_node (np );
380+ of_node_put (np );
381+ if (IS_ERR_OR_NULL (pdev ))
382+ return NULL ;
383+
384+ return & pdev -> dev ;
385+ }
386+
336387static int mtk_cpu_dvfs_info_init (struct mtk_cpu_dvfs_info * info , int cpu )
337388{
338389 struct device * cpu_dev ;
@@ -347,6 +398,16 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
347398 }
348399 info -> cpu_dev = cpu_dev ;
349400
401+ info -> ccifreq_bound = false;
402+ if (info -> soc_data -> ccifreq_supported ) {
403+ info -> cci_dev = of_get_cci (info -> cpu_dev );
404+ if (IS_ERR_OR_NULL (info -> cci_dev )) {
405+ ret = PTR_ERR (info -> cci_dev );
406+ dev_err (cpu_dev , "cpu%d: failed to get cci device\n" , cpu );
407+ return - ENODEV ;
408+ }
409+ }
410+
350411 info -> cpu_clk = clk_get (cpu_dev , "cpu" );
351412 if (IS_ERR (info -> cpu_clk )) {
352413 ret = PTR_ERR (info -> cpu_clk );
@@ -410,6 +471,15 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
410471 if (ret )
411472 goto out_disable_mux_clock ;
412473
474+ if (info -> soc_data -> ccifreq_supported ) {
475+ info -> vproc_on_boot = regulator_get_voltage (info -> proc_reg );
476+ if (info -> vproc_on_boot < 0 ) {
477+ dev_err (info -> cpu_dev ,
478+ "invalid Vproc value: %d\n" , info -> vproc_on_boot );
479+ goto out_disable_inter_clock ;
480+ }
481+ }
482+
413483 /* Search a safe voltage for intermediate frequency. */
414484 rate = clk_get_rate (info -> inter_clk );
415485 opp = dev_pm_opp_find_freq_ceil (cpu_dev , & rate );
@@ -617,6 +687,16 @@ static const struct mtk_cpufreq_platform_data mt2701_platform_data = {
617687 .proc_max_volt = 1150000 ,
618688 .sram_min_volt = 0 ,
619689 .sram_max_volt = 1150000 ,
690+ .ccifreq_supported = false,
691+ };
692+
693+ static const struct mtk_cpufreq_platform_data mt8183_platform_data = {
694+ .min_volt_shift = 100000 ,
695+ .max_volt_shift = 200000 ,
696+ .proc_max_volt = 1150000 ,
697+ .sram_min_volt = 0 ,
698+ .sram_max_volt = 1150000 ,
699+ .ccifreq_supported = true,
620700};
621701
622702/* List of machines supported by this driver */
@@ -629,7 +709,7 @@ static const struct of_device_id mtk_cpufreq_machines[] __initconst = {
629709 { .compatible = "mediatek,mt817x" , .data = & mt2701_platform_data },
630710 { .compatible = "mediatek,mt8173" , .data = & mt2701_platform_data },
631711 { .compatible = "mediatek,mt8176" , .data = & mt2701_platform_data },
632- { .compatible = "mediatek,mt8183" , .data = & mt2701_platform_data },
712+ { .compatible = "mediatek,mt8183" , .data = & mt8183_platform_data },
633713 { .compatible = "mediatek,mt8365" , .data = & mt2701_platform_data },
634714 { .compatible = "mediatek,mt8516" , .data = & mt2701_platform_data },
635715 { }
0 commit comments