From: Jia-Wei Chang <jia-wei.chang@xxxxxxxxxxxx> In some MediaTek SoCs, like MT8183, CPU and CCI share the same power supplies. Cpufreq needs to check if CCI devfreq exists and wait until CCI devfreq ready before scaling frequency. - Add is_ccifreq_ready() to link CCI device to CPI, and CPU will start DVFS when CCI is ready. - Add platform data for MT8183. Signed-off-by: Jia-Wei Chang <jia-wei.chang@xxxxxxxxxxxx> --- drivers/cpufreq/mediatek-cpufreq.c | 69 +++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index b08ab7c14818..cebe5af2ef5d 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -22,6 +22,7 @@ struct mtk_cpufreq_platform_data { int proc_max_volt; int sram_min_volt; int sram_max_volt; + bool is_ccifreq_support; }; /* @@ -38,6 +39,7 @@ struct mtk_cpufreq_platform_data { struct mtk_cpu_dvfs_info { struct cpumask cpus; struct device *cpu_dev; + struct device *cci_dev; struct regulator *proc_reg; struct regulator *sram_reg; struct clk *cpu_clk; @@ -52,6 +54,7 @@ struct mtk_cpu_dvfs_info { int opp_cpu; unsigned long opp_freq; const struct mtk_cpufreq_platform_data *soc_data; + bool is_ccifreq_bounded; }; static struct platform_device *cpufreq_pdev; @@ -171,6 +174,29 @@ static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) return ret; } +static bool is_ccifreq_ready(struct mtk_cpu_dvfs_info *info) +{ + struct device_link *sup_link; + + if (info->is_ccifreq_bounded) + return true; + + sup_link = device_link_add(info->cpu_dev, info->cci_dev, + DL_FLAG_AUTOREMOVE_CONSUMER); + if (!sup_link) { + dev_err(info->cpu_dev, "cpu%d: sup_link is NULL\n", + info->opp_cpu); + return false; + } + + if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND) + return false; + + info->is_ccifreq_bounded = true; + + return true; +} + static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { @@ -183,6 +209,9 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, long freq_hz, old_freq_hz; int vproc, old_vproc, inter_vproc, target_vproc, ret; + if (info->soc_data->is_ccifreq_support && !is_ccifreq_ready(info)) + return 0; + inter_vproc = info->intermediate_voltage; freq_hz = freq_table[index].frequency * 1000; @@ -329,6 +358,23 @@ static int mtk_cpufreq_opp_notifier(struct notifier_block *nb, return notifier_from_errno(ret); } +static struct device *of_get_cci(struct device *cpu_dev) +{ + struct device_node *np; + struct platform_device *pdev; + + np = of_parse_phandle(cpu_dev->of_node, "cci", 0); + if (IS_ERR(np)) + return NULL; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (IS_ERR(pdev)) + return NULL; + + return &pdev->dev; +} + static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) { struct device *cpu_dev; @@ -343,6 +389,17 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) } info->cpu_dev = cpu_dev; + info->is_ccifreq_bounded = false; + if (info->soc_data->is_ccifreq_support) { + info->cci_dev = of_get_cci(info->cpu_dev); + if (IS_ERR_OR_NULL(info->cci_dev)) { + ret = PTR_ERR(info->cci_dev); + dev_err(cpu_dev, "cpu%d: failed to get cci device\n", + cpu); + return -ENODEV; + } + } + info->cpu_clk = clk_get(cpu_dev, "cpu"); if (IS_ERR(info->cpu_clk)) { ret = PTR_ERR(info->cpu_clk); @@ -620,6 +677,16 @@ static const struct mtk_cpufreq_platform_data mtk_platform_data = { .proc_max_volt = 1150000, .sram_min_volt = 0, .sram_max_volt = 1150000, + .is_ccifreq_support = false, +}; + +static const struct mtk_cpufreq_platform_data mt8183_platform_data = { + .min_volt_shift = 100000, + .max_volt_shift = 200000, + .proc_max_volt = 1150000, + .sram_min_volt = 0, + .sram_max_volt = 1150000, + .is_ccifreq_support = true, }; /* List of machines supported by this driver */ @@ -632,7 +699,7 @@ static const struct of_device_id mtk_cpufreq_machines[] __initconst = { { .compatible = "mediatek,mt817x", .data = &mtk_platform_data }, { .compatible = "mediatek,mt8173", .data = &mtk_platform_data }, { .compatible = "mediatek,mt8176", .data = &mtk_platform_data }, - { .compatible = "mediatek,mt8183", .data = &mtk_platform_data }, + { .compatible = "mediatek,mt8183", .data = &mt8183_platform_data }, { .compatible = "mediatek,mt8365", .data = &mtk_platform_data }, { .compatible = "mediatek,mt8516", .data = &mtk_platform_data }, { } -- 2.18.0