aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-5.15/350-13-cpufreq-mediatek-Link-CCI-device-to-CPU.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/patches-5.15/350-13-cpufreq-mediatek-Link-CCI-device-to-CPU.patch')
-rw-r--r--target/linux/mediatek/patches-5.15/350-13-cpufreq-mediatek-Link-CCI-device-to-CPU.patch188
1 files changed, 188 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches-5.15/350-13-cpufreq-mediatek-Link-CCI-device-to-CPU.patch b/target/linux/mediatek/patches-5.15/350-13-cpufreq-mediatek-Link-CCI-device-to-CPU.patch
new file mode 100644
index 0000000000..eeaa466c32
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/350-13-cpufreq-mediatek-Link-CCI-device-to-CPU.patch
@@ -0,0 +1,188 @@
+From 15aaf74fb734a3e69b10d00b97b322711b81e222 Mon Sep 17 00:00:00 2001
+From: Rex-BC Chen <rex-bc.chen@mediatek.com>
+Date: Thu, 5 May 2022 19:52:22 +0800
+Subject: [PATCH 13/21] cpufreq: mediatek: Link CCI device to CPU
+
+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.
+
+Before CCI devfreq is ready, we record the voltage when booting to
+kernel and use the max(cpu target voltage, booting voltage) to
+prevent cpufreq adjust to the lower voltage which will cause the CCI
+crash because of high frequency and low voltage.
+
+- 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@mediatek.com>
+Signed-off-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Kevin Hilman <khilman@baylibre.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 82 +++++++++++++++++++++++++++++-
+ 1 file changed, 81 insertions(+), 1 deletion(-)
+
+--- 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 ccifreq_supported;
+ };
+
+ /*
+@@ -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;
+@@ -45,6 +47,7 @@ struct mtk_cpu_dvfs_info {
+ struct list_head list_head;
+ int intermediate_voltage;
+ bool need_voltage_tracking;
++ int vproc_on_boot;
+ int pre_vproc;
+ /* Avoid race condition for regulators between notify and policy */
+ struct mutex reg_lock;
+@@ -53,6 +56,7 @@ struct mtk_cpu_dvfs_info {
+ unsigned long current_freq;
+ const struct mtk_cpufreq_platform_data *soc_data;
+ int vtrack_max;
++ bool ccifreq_bound;
+ };
+
+ static struct platform_device *cpufreq_pdev;
+@@ -171,6 +175,28 @@ static int mtk_cpufreq_set_voltage(struc
+ return ret;
+ }
+
++static bool is_ccifreq_ready(struct mtk_cpu_dvfs_info *info)
++{
++ struct device_link *sup_link;
++
++ if (info->ccifreq_bound)
++ 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->ccifreq_bound = true;
++
++ return true;
++}
++
+ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
+ unsigned int index)
+ {
+@@ -213,6 +239,14 @@ static int mtk_cpufreq_set_target(struct
+ dev_pm_opp_put(opp);
+
+ /*
++ * If MediaTek cci is supported but is not ready, we will use the value
++ * of max(target cpu voltage, booting voltage) to prevent high freqeuncy
++ * low voltage crash.
++ */
++ if (info->soc_data->ccifreq_supported && !is_ccifreq_ready(info))
++ vproc = max(vproc, info->vproc_on_boot);
++
++ /*
+ * If the new voltage or the intermediate voltage is higher than the
+ * current voltage, scale up voltage first.
+ */
+@@ -333,6 +367,23 @@ static int mtk_cpufreq_opp_notifier(stru
+ 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, "mediatek,cci", 0);
++ if (IS_ERR_OR_NULL(np))
++ return NULL;
++
++ pdev = of_find_device_by_node(np);
++ of_node_put(np);
++ if (IS_ERR_OR_NULL(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;
+@@ -347,6 +398,16 @@ static int mtk_cpu_dvfs_info_init(struct
+ }
+ info->cpu_dev = cpu_dev;
+
++ info->ccifreq_bound = false;
++ if (info->soc_data->ccifreq_supported) {
++ 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);
+@@ -410,6 +471,15 @@ static int mtk_cpu_dvfs_info_init(struct
+ if (ret)
+ goto out_disable_mux_clock;
+
++ if (info->soc_data->ccifreq_supported) {
++ info->vproc_on_boot = regulator_get_voltage(info->proc_reg);
++ if (info->vproc_on_boot < 0) {
++ dev_err(info->cpu_dev,
++ "invalid Vproc value: %d\n", info->vproc_on_boot);
++ goto out_disable_inter_clock;
++ }
++ }
++
+ /* Search a safe voltage for intermediate frequency. */
+ rate = clk_get_rate(info->inter_clk);
+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
+@@ -617,6 +687,16 @@ static const struct mtk_cpufreq_platform
+ .proc_max_volt = 1150000,
+ .sram_min_volt = 0,
+ .sram_max_volt = 1150000,
++ .ccifreq_supported = 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,
++ .ccifreq_supported = true,
+ };
+
+ /* List of machines supported by this driver */
+@@ -629,7 +709,7 @@ static const struct of_device_id mtk_cpu
+ { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data },
+ { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data },
+ { .compatible = "mediatek,mt8176", .data = &mt2701_platform_data },
+- { .compatible = "mediatek,mt8183", .data = &mt2701_platform_data },
++ { .compatible = "mediatek,mt8183", .data = &mt8183_platform_data },
+ { .compatible = "mediatek,mt8365", .data = &mt2701_platform_data },
+ { .compatible = "mediatek,mt8516", .data = &mt2701_platform_data },
+ { }