[openwrt/openwrt] mediatek: improve MT7988 cpufreq driver and add support for MT7987

LEDE Commits lede-commits at lists.infradead.org
Wed Nov 5 06:23:08 PST 2025


dangole pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/2595e31220f8e515714a71deb781e3fdf8c483ef

commit 2595e31220f8e515714a71deb781e3fdf8c483ef
Author: Daniel Golle <daniel at makrotopia.org>
AuthorDate: Sun Oct 5 03:42:19 2025 +0100

    mediatek: improve MT7988 cpufreq driver and add support for MT7987
    
    Import patches to use cpufreq voltage calibration data from the efuse on
    MT7988, and add support for MT7987.
    
    Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 ...-support-to-adjust-cpu-volt-by-efuse-cali.patch | 106 +++++++++++++++++++++
 ...dd-cpu-volt-correction-support-for-mt7988.patch |  33 +++++++
 ...using-efuse-cali-data-for-mt7988-cpu-volt.patch |  48 ++++++++++
 ...43-cpufreq-add-support-to-fix-voltage-cpu.patch |  21 ++++
 ...4-cpufreq-mediatek-Add-support-for-MT7987.patch |  23 +++++
 .../965-dts-mt7988a-add-trng-support.patch         |   2 +-
 6 files changed, 232 insertions(+), 1 deletion(-)

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
index 0000000000..9aebab6689
--- /dev/null
+++ b/target/linux/mediatek/patches-6.12/840-cpufreq-add-support-to-adjust-cpu-volt-by-efuse-cali.patch
@@ -0,0 +1,106 @@
+From fbb1d181782f990c0ac5f39d4aa9eda5c39cb442 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih at 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
index 0000000000..43397d8529
--- /dev/null
+++ b/target/linux/mediatek/patches-6.12/841-cpufreq-add-cpu-volt-correction-support-for-mt7988.patch
@@ -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
index 0000000000..30115a2358
--- /dev/null
+++ b/target/linux/mediatek/patches-6.12/842-mediatek-enable-using-efuse-cali-data-for-mt7988-cpu-volt.patch
@@ -0,0 +1,48 @@
+From c776eb44070d009375559d8c6eb8790edfe129a9 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih at 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
index 0000000000..b9f67c9faf
--- /dev/null
+++ b/target/linux/mediatek/patches-6.12/843-cpufreq-add-support-to-fix-voltage-cpu.patch
@@ -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
index 0000000000..e0c8c47400
--- /dev/null
+++ b/target/linux/mediatek/patches-6.12/844-cpufreq-mediatek-Add-support-for-MT7987.patch
@@ -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 },
diff --git a/target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch b/target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch
index 9c0b692418..77bd503437 100644
--- a/target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch
+++ b/target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch
@@ -8,7 +8,7 @@ Signed-off-by: Marcos Alano <marcoshalano at 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>;
  	};




More information about the lede-commits mailing list