]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
mediatek: improve MT7988 cpufreq driver and add support for MT7987
authorDaniel Golle <daniel@makrotopia.org>
Sun, 5 Oct 2025 02:42:19 +0000 (03:42 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Wed, 5 Nov 2025 14:19:40 +0000 (14:19 +0000)
Import patches to use cpufreq voltage calibration data from the efuse on
MT7988, and add support for MT7987.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
target/linux/mediatek/patches-6.12/840-cpufreq-add-support-to-adjust-cpu-volt-by-efuse-cali.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/841-cpufreq-add-cpu-volt-correction-support-for-mt7988.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/842-mediatek-enable-using-efuse-cali-data-for-mt7988-cpu-volt.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/843-cpufreq-add-support-to-fix-voltage-cpu.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/844-cpufreq-mediatek-Add-support-for-MT7987.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch

diff --git a/target/linux/mediatek/patches-6.12/840-cpufreq-add-support-to-adjust-cpu-volt-by-efuse-cali.patch b/target/linux/mediatek/patches-6.12/840-cpufreq-add-support-to-adjust-cpu-volt-by-efuse-cali.patch
new file mode 100644 (file)
index 0000000..9aebab6
--- /dev/null
@@ -0,0 +1,106 @@
+From fbb1d181782f990c0ac5f39d4aa9eda5c39cb442 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Tue, 4 Mar 2025 19:28:14 +0800
+Subject: [PATCH 1/2] cpufreq: add support to adjust cpu volt by efuse
+ calibration data
+
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 81 ++++++++++++++++++++++++++++--
+ 1 file changed, 76 insertions(+), 5 deletions(-)
+
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -15,14 +15,26 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/nvmem-consumer.h>
++
++struct mtk_cpufreq_corr_data {
++      unsigned int freq;
++      unsigned int vbase;
++      unsigned int vscale;
++      unsigned int vmax;
++};
+ struct mtk_cpufreq_platform_data {
++      /* cpufreq correction data specification */
++      const struct mtk_cpufreq_corr_data *corr_data;
+       int min_volt_shift;
+       int max_volt_shift;
+       int proc_max_volt;
+       int sram_min_volt;
+       int sram_max_volt;
+       bool ccifreq_supported;
++      /* whether voltage correction via nvmem is supported */
++      bool nvmem_volt_corr;
+ };
+ /*
+@@ -197,6 +209,50 @@ static bool is_ccifreq_ready(struct mtk_
+       return true;
+ }
++static int mtk_cpufreq_nvmem_volt_corr(struct mtk_cpu_dvfs_info *info,
++                                    struct cpufreq_policy *policy)
++{
++      const struct mtk_cpufreq_corr_data *corr_data;
++      unsigned int target_voltage;
++      struct nvmem_cell *cell;
++      unsigned int cal_data;
++      const u8 *buf;
++      size_t len;
++      int i;
++
++      cell = nvmem_cell_get(info->cpu_dev, "calibration-data");
++      if (IS_ERR(cell))
++              return PTR_ERR(cell);
++
++      buf = nvmem_cell_read(cell, &len);
++      nvmem_cell_put(cell);
++      if (IS_ERR(buf))
++              return PTR_ERR(buf);
++
++      cal_data = buf[0] & 0x1f;
++      pr_debug("%s: read vbinning value: %d\n", __func__, cal_data);
++      kfree(buf);
++      if (!info->soc_data->corr_data) {
++              pr_err("voltage correction data not found\n");
++              return -EINVAL;
++      }
++
++      corr_data = &info->soc_data->corr_data[0];
++      for (i = 0 ; i < corr_data->freq ; i++) {
++              target_voltage =  corr_data->vbase + cal_data * corr_data->vscale;
++              if (target_voltage > corr_data->vmax) {
++                      pr_warn("freq %u exceeds max voltage\n", corr_data->freq);
++                      pr_warn("force update voltage to %u\n", corr_data->vmax);
++                      target_voltage = corr_data->vmax;
++              }
++              dev_pm_opp_remove(info->cpu_dev, corr_data->freq);
++              dev_pm_opp_add(info->cpu_dev, corr_data->freq, target_voltage);
++              corr_data = &info->soc_data->corr_data[i + 1];
++      }
++
++      return 0;
++}
++
+ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
+                                 unsigned int index)
+ {
+@@ -584,6 +640,15 @@ static int mtk_cpufreq_init(struct cpufr
+               return -EINVAL;
+       }
++      if (info->soc_data->nvmem_volt_corr) {
++              ret = mtk_cpufreq_nvmem_volt_corr(info, policy);
++              if (ret) {
++                      pr_err("failed to correction voltage for cpu%d: %d\n",
++                             policy->cpu, ret);
++                      return ret;
++              }
++      }
++
+       ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
+       if (ret) {
+               dev_err(info->cpu_dev,
diff --git a/target/linux/mediatek/patches-6.12/841-cpufreq-add-cpu-volt-correction-support-for-mt7988.patch b/target/linux/mediatek/patches-6.12/841-cpufreq-add-cpu-volt-correction-support-for-mt7988.patch
new file mode 100644 (file)
index 0000000..43397d8
--- /dev/null
@@ -0,0 +1,33 @@
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -741,6 +741,16 @@ static struct platform_driver mtk_cpufre
+       .probe          = mtk_cpufreq_probe,
+ };
++struct mtk_cpufreq_corr_data mt7988_volt_corr_data[] = {
++      {
++              .freq = 1800000000,
++              .vbase = 850000,
++              .vscale = 10000,
++              .vmax = 1120000,
++      },
++      { } /* sentinel */
++};
++
+ static const struct mtk_cpufreq_platform_data mt2701_platform_data = {
+       .min_volt_shift = 100000,
+       .max_volt_shift = 200000,
+@@ -769,10 +779,12 @@ static const struct mtk_cpufreq_platform
+ static const struct mtk_cpufreq_platform_data mt7988_platform_data = {
+       .min_volt_shift = 100000,
+       .max_volt_shift = 200000,
+-      .proc_max_volt = 900000,
++      .proc_max_volt = 1120000,
+       .sram_min_volt = 0,
+       .sram_max_volt = 1150000,
+       .ccifreq_supported = true,
++      .nvmem_volt_corr = 1,
++      .corr_data = mt7988_volt_corr_data,
+ };
+ static const struct mtk_cpufreq_platform_data mt8183_platform_data = {
diff --git a/target/linux/mediatek/patches-6.12/842-mediatek-enable-using-efuse-cali-data-for-mt7988-cpu-volt.patch b/target/linux/mediatek/patches-6.12/842-mediatek-enable-using-efuse-cali-data-for-mt7988-cpu-volt.patch
new file mode 100644 (file)
index 0000000..30115a2
--- /dev/null
@@ -0,0 +1,48 @@
+From c776eb44070d009375559d8c6eb8790edfe129a9 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Tue, 4 Mar 2025 19:35:14 +0800
+Subject: [PATCH 2/2] cpufreq: mt7988: enable using efuse calibration data for
+ adjusting cpu volt
+
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -55,6 +55,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
+@@ -67,6 +69,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
+@@ -79,6 +83,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
+@@ -91,6 +97,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
diff --git a/target/linux/mediatek/patches-6.12/843-cpufreq-add-support-to-fix-voltage-cpu.patch b/target/linux/mediatek/patches-6.12/843-cpufreq-add-support-to-fix-voltage-cpu.patch
new file mode 100644 (file)
index 0000000..b9f67c9
--- /dev/null
@@ -0,0 +1,21 @@
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -35,6 +35,8 @@ struct mtk_cpufreq_platform_data {
+       bool ccifreq_supported;
+       /* whether voltage correction via nvmem is supported */
+       bool nvmem_volt_corr;
++      /* Flag indicating whether the processor voltage is fixed */
++      bool proc_fixed_volt;
+ };
+ /*
+@@ -176,6 +178,9 @@ static int mtk_cpufreq_set_voltage(struc
+       const struct mtk_cpufreq_platform_data *soc_data = info->soc_data;
+       int ret;
++      if (soc_data->proc_fixed_volt)
++              return 0;
++
+       if (info->need_voltage_tracking)
+               ret = mtk_cpufreq_voltage_tracking(info, vproc);
+       else
diff --git a/target/linux/mediatek/patches-6.12/844-cpufreq-mediatek-Add-support-for-MT7987.patch b/target/linux/mediatek/patches-6.12/844-cpufreq-mediatek-Add-support-for-MT7987.patch
new file mode 100644 (file)
index 0000000..e0c8c47
--- /dev/null
@@ -0,0 +1,23 @@
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -781,6 +781,12 @@ static const struct mtk_cpufreq_platform
+       .ccifreq_supported = false,
+ };
++static const struct mtk_cpufreq_platform_data mt7987_platform_data = {
++      .proc_max_volt = 1023000,
++      .ccifreq_supported = false,
++      .proc_fixed_volt = true,
++};
++
+ static const struct mtk_cpufreq_platform_data mt7988_platform_data = {
+       .min_volt_shift = 100000,
+       .max_volt_shift = 200000,
+@@ -825,6 +831,7 @@ static const struct of_device_id mtk_cpu
+       { .compatible = "mediatek,mt2712", .data = &mt2701_platform_data },
+       { .compatible = "mediatek,mt7622", .data = &mt7622_platform_data },
+       { .compatible = "mediatek,mt7623", .data = &mt7623_platform_data },
++      { .compatible = "mediatek,mt7987", .data = &mt7987_platform_data },
+       { .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data },
+       { .compatible = "mediatek,mt7988d", .data = &mt7988_platform_data },
+       { .compatible = "mediatek,mt8167", .data = &mt8516_platform_data },
index 9c0b69241819c30707551de9506e2521bef6b72a..77bd503437e2feb3ecc3c8d032cd11a685b00790 100644 (file)
@@ -8,7 +8,7 @@ Signed-off-by: Marcos Alano <marcoshalano@gmail.com>
 ---
 --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
 +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
-@@ -1319,4 +1319,8 @@
+@@ -1327,4 +1327,8 @@
                             <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
                             <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
        };