mediatek: update mt7988 cpufreq and support mt7987
Some checks failed
OpenWrt-CI / Build OpenWrt Firmware (push) Has been cancelled

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>
This commit is contained in:
Daniel Golle
2025-10-05 03:42:19 +01:00
parent 8942bba343
commit 4f551e4612
6 changed files with 232 additions and 1 deletions

View File

@@ -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,

View File

@@ -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 = {

View File

@@ -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>;
};

View File

@@ -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

View File

@@ -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 },

View 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>;
};