* [PATCH 0/3] Tegra114: Fix CPU DFLL voltages
@ 2026-10-29 9:32 Patrick Fischer via B4 Relay
2026-10-29 9:32 ` [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets Patrick Fischer via B4 Relay
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Patrick Fischer via B4 Relay @ 2026-10-29 9:32 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter
Cc: Mikko Perttunen, Svyatoslav Ryhel, Prashant Gaikwad,
Stephen Boyd, Brian Masney, Jerome Brunet, linux-clk,
linux-tegra, linux-kernel, stable, Patrick Fischer
Since the Tegra114 CPU DFLL got its CVB tables in v6.18, it computes
the CPU OPP voltages from tegra_sku_info.cpu_speedo_value and the step
of the vdd_cpu regulator. On a Tegra Note 7 (Tegra114, TPS65913) every
CPU OPP from 306 MHz to 1810.5 MHz ends up at 1000 mV, and the DFLL
never changes vdd_cpu: it stays at the 1.10 V left by the bootloader,
and the CPU runs at about 1.34 GHz whatever cpufreq requests. Three
bugs cause this:
1. Since 2014 the speedo code reads the Tegra114 speedo fuses at offsets
that are 0x100 too large.
2. It never stores the CPU and SoC speedo values in tegra_sku_info, so
the DFLL computes with speedo 0, which overflows in
round_cvb_voltage().
3. The DFLL takes the voltage step from regulator_get_linear_step(),
which is 0 for the Palmas SMPS. Every OPP is rounded to 0 and so
clamped to the minimum, and the I2C LUT holds a single selector.
On its own, patch 3 fixes the Xiaomi Mi Pad (Tegra124 with Palmas). On
Tegra114, which includes the TF701T, it needs patches 1 and 2: with
speedo 0 every OPP would still overflow to 1000 mV. That is why the
three patches go together, all with Cc: stable.
Since patch 3 is only useful on Tegra114 together with patches 1 and 2,
it would be easiest to take all three through the Tegra tree.
The Tegra Note 7 device tree is not in mainline yet; I used
Svyatoslav's tegratab series on top of v7.3, with these patches
applied. Results on a P1640 (Tegra114 A02, SKU 5, CPU speedo ID 1):
- The fuse values match what the vendor kernel prints for this device:
CPU speedo 1742, SoC speedo 1156, CPU and SoC process 1 (before:
SoC process 0).
- CPU OPPs: 1000 mV up to 1122 MHz, then 1040, 1070, 1110, 1150, 1180,
1220 and 1270 mV at 1810.5 MHz, as computed from the CVB table.
Before: all 1000 mV.
- The DFLL LUT holds selectors 0x38 to 0x53 (1000 mV to 1270 mV)
instead of a single selector 0.
- The DFLL rate follows cpufreq within 2% from 306 MHz to 1708.5 MHz,
with vdd_cpu between 1020 mV and 1260 mV. At 1810.5 MHz it stays at
about 1.74 GHz at the end of the LUT (1270 mV). Before: about
1.34 GHz at any request.
- At 1122 MHz under load on four cores for 480 s the CPU stays at
52 degC with 3.15 W from the battery, compared to 73 degC and 4.48 W
before.
- No errors in a memory test with 25 passes, in three 600 s load runs
with cpufreq limits of 1428, 1606.5 and 1810.5 MHz (throttled to
about 1.0 to 1.2 GHz by a board thermal zone), and in 316 s at
1810.5 MHz with that trip raised (DFLL at about 1.73 GHz, 1270 mV, closed
loop throughout, stopped by the test at 98 degC).
Svyatoslav measured the CPU OPPs on an Asus TF701T (CPU speedo ID 2):
without the series all of them are at 1000 mV; with it they are
1000 mV up to 1122 MHz, then 1020, 1050, 1090, 1120, 1150, 1190, 1240
and 1290 mV at 1912.5 MHz. The speedo IDs come from the SKU and do not
change, so the core, EMC and GPU OPPs stay the same, which he confirmed
on the TF701T.
Tool use (see Documentation/process/generated-content.rst): the patches,
their changelogs and this cover letter were prepared with an LLM coding
assistant (Claude Code). It compared the fuse offsets with the vendor
kernel, read the fuse words on the device, traced the zero voltage step
through the DFLL code, wrote the code changes and drafted the texts from
my measurements and instructions. I reviewed the changes and ran all
tests on the device.
---
Patrick Fischer (3):
soc/tegra: fuse: Fix Tegra114 speedo fuse offsets
soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values
clk: tegra: dfll: Get the voltage step of range-based regulators
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 26 ++++++++++++++++++++++++++
drivers/soc/tegra/fuse/speedo-tegra114.c | 16 ++++++++++++----
2 files changed, 38 insertions(+), 4 deletions(-)
---
base-commit: c339f4010dea8b0d754f84ace70cd1b089878ef8
change-id: 20261026-upstream-speedo-t114-3567735d5a2c
Best regards,
--
Patrick Fischer <admin@tsv-stahl-riesa.de>
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets
2026-10-29 9:32 [PATCH 0/3] Tegra114: Fix CPU DFLL voltages Patrick Fischer via B4 Relay
@ 2026-10-29 9:32 ` Patrick Fischer via B4 Relay
2026-10-29 10:11 ` Svyatoslav Ryhel
2026-11-02 7:41 ` Mikko Perttunen
2026-10-29 9:33 ` [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values Patrick Fischer via B4 Relay
2026-10-29 9:33 ` [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators Patrick Fischer via B4 Relay
2 siblings, 2 replies; 10+ messages in thread
From: Patrick Fischer via B4 Relay @ 2026-10-29 9:32 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter
Cc: Mikko Perttunen, Svyatoslav Ryhel, Prashant Gaikwad,
Stephen Boyd, Brian Masney, Jerome Brunet, linux-clk,
linux-tegra, linux-kernel, stable, Patrick Fischer
From: Patrick Fischer <admin@tsv-stahl-riesa.de>
tegra_fuse_read_early() takes offsets relative to the start of the fuse
words at FUSE_BEGIN (0x100). When the fuse driver moved out of
mach-tegra, the Tegra30 speedo code was converted to such offsets
(FUSE_SPEEDO_CALIB_0 0x114 became 0x14), and the Tegra124 code uses
them as well. The Tegra114 code kept the absolute offsets from the
vendor kernel, so since then it reads the CPU and SoC speedo values and
the A01 CPU2/3 fuses 0x100 bytes too far.
On a Tegra Note 7 (Tegra114 A02, SKU 5) the fuses at the correct
offsets 0x2c and 0x34 read 718 and 1156. That gives CPU speedo 1742 and
SoC speedo 1156, which is exactly what the vendor kernel prints for this
device. The current code reads 172094 and 0, and so reports SoC process
0 instead of 1.
Today only the reported process IDs depend on these values, since the
Tegra114 core OPPs are selected by the SoC speedo ID and the CPU DVFS
tables apply to all process IDs. The CPU speedo value is needed,
however, to compute correct CPU DFLL voltages, which the next patch
fixes.
Fixes: 783c8f4c8445 ("soc/tegra: Add efuse driver for Tegra")
Cc: stable@vger.kernel.org
Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
---
drivers/soc/tegra/fuse/speedo-tegra114.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
index 6695702bdb4c..1e6c2b5be759 100644
--- a/drivers/soc/tegra/fuse/speedo-tegra114.c
+++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
@@ -14,6 +14,11 @@
#define SOC_PROCESS_CORNERS 2
#define CPU_PROCESS_CORNERS 2
+#define FUSE_CPU_SPEEDO_1 0x2c
+#define FUSE_SOC_SPEEDO_0 0x34
+#define FUSE_OPT_CPU23_DISABLE 0x16c
+#define FUSE_OPT_CPU23_REENABLE 0x170
+
enum {
THRESHOLD_INDEX_0,
THRESHOLD_INDEX_1,
@@ -63,8 +68,8 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
}
if (rev == TEGRA_REVISION_A01) {
- tmp = tegra_fuse_read_early(0x270) << 1;
- tmp |= tegra_fuse_read_early(0x26c);
+ tmp = tegra_fuse_read_early(FUSE_OPT_CPU23_REENABLE) << 1;
+ tmp |= tegra_fuse_read_early(FUSE_OPT_CPU23_DISABLE);
if (!tmp)
sku_info->cpu_speedo_id = 0;
}
@@ -84,8 +89,8 @@ void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
rev_sku_to_speedo_ids(sku_info, &threshold);
- cpu_speedo_val = tegra_fuse_read_early(0x12c) + 1024;
- soc_speedo_val = tegra_fuse_read_early(0x134);
+ cpu_speedo_val = tegra_fuse_read_early(FUSE_CPU_SPEEDO_1) + 1024;
+ soc_speedo_val = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
for (i = 0; i < CPU_PROCESS_CORNERS; i++)
if (cpu_speedo_val < cpu_process_speedos[threshold][i])
--
2.56.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets
2026-10-29 9:32 ` [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets Patrick Fischer via B4 Relay
@ 2026-10-29 10:11 ` Svyatoslav Ryhel
2026-11-02 7:41 ` Mikko Perttunen
1 sibling, 0 replies; 10+ messages in thread
From: Svyatoslav Ryhel @ 2026-10-29 10:11 UTC (permalink / raw)
To: admin
Cc: Thierry Reding, Jonathan Hunter, Mikko Perttunen,
Prashant Gaikwad, Stephen Boyd, Brian Masney, Jerome Brunet,
linux-clk, linux-tegra, linux-kernel, stable
чт, 29 жовт. 2026 р. о 11:33 Patrick Fischer via B4 Relay
<devnull+admin.tsv-stahl-riesa.de@kernel.org> пише:
>
> From: Patrick Fischer <admin@tsv-stahl-riesa.de>
>
> tegra_fuse_read_early() takes offsets relative to the start of the fuse
> words at FUSE_BEGIN (0x100). When the fuse driver moved out of
> mach-tegra, the Tegra30 speedo code was converted to such offsets
> (FUSE_SPEEDO_CALIB_0 0x114 became 0x14), and the Tegra124 code uses
> them as well. The Tegra114 code kept the absolute offsets from the
> vendor kernel, so since then it reads the CPU and SoC speedo values and
> the A01 CPU2/3 fuses 0x100 bytes too far.
>
> On a Tegra Note 7 (Tegra114 A02, SKU 5) the fuses at the correct
> offsets 0x2c and 0x34 read 718 and 1156. That gives CPU speedo 1742 and
> SoC speedo 1156, which is exactly what the vendor kernel prints for this
> device. The current code reads 172094 and 0, and so reports SoC process
> 0 instead of 1.
>
> Today only the reported process IDs depend on these values, since the
> Tegra114 core OPPs are selected by the SoC speedo ID and the CPU DVFS
> tables apply to all process IDs. The CPU speedo value is needed,
> however, to compute correct CPU DFLL voltages, which the next patch
> fixes.
>
> Fixes: 783c8f4c8445 ("soc/tegra: Add efuse driver for Tegra")
> Cc: stable@vger.kernel.org
> Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
> ---
> drivers/soc/tegra/fuse/speedo-tegra114.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
> index 6695702bdb4c..1e6c2b5be759 100644
> --- a/drivers/soc/tegra/fuse/speedo-tegra114.c
> +++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
> @@ -14,6 +14,11 @@
> #define SOC_PROCESS_CORNERS 2
> #define CPU_PROCESS_CORNERS 2
>
> +#define FUSE_CPU_SPEEDO_1 0x2c
> +#define FUSE_SOC_SPEEDO_0 0x34
> +#define FUSE_OPT_CPU23_DISABLE 0x16c
> +#define FUSE_OPT_CPU23_REENABLE 0x170
> +
> enum {
> THRESHOLD_INDEX_0,
> THRESHOLD_INDEX_1,
> @@ -63,8 +68,8 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
> }
>
> if (rev == TEGRA_REVISION_A01) {
> - tmp = tegra_fuse_read_early(0x270) << 1;
> - tmp |= tegra_fuse_read_early(0x26c);
> + tmp = tegra_fuse_read_early(FUSE_OPT_CPU23_REENABLE) << 1;
> + tmp |= tegra_fuse_read_early(FUSE_OPT_CPU23_DISABLE);
> if (!tmp)
> sku_info->cpu_speedo_id = 0;
> }
> @@ -84,8 +89,8 @@ void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
>
> rev_sku_to_speedo_ids(sku_info, &threshold);
>
> - cpu_speedo_val = tegra_fuse_read_early(0x12c) + 1024;
> - soc_speedo_val = tegra_fuse_read_early(0x134);
> + cpu_speedo_val = tegra_fuse_read_early(FUSE_CPU_SPEEDO_1) + 1024;
> + soc_speedo_val = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
>
> for (i = 0; i < CPU_PROCESS_CORNERS; i++)
> if (cpu_speedo_val < cpu_process_speedos[threshold][i])
>
> --
> 2.56.0
Thanks!
Tested-by: Svyatoslav Ryhel <clamor95@gmail.com> # Tegratab (P1988)
and ASUS TF701T
Reviewed-by: Svyatoslav Ryhel <clamor95@gmail.com>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets
2026-10-29 9:32 ` [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets Patrick Fischer via B4 Relay
2026-10-29 10:11 ` Svyatoslav Ryhel
@ 2026-11-02 7:41 ` Mikko Perttunen
1 sibling, 0 replies; 10+ messages in thread
From: Mikko Perttunen @ 2026-11-02 7:41 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, linux-clk
Cc: Svyatoslav Ryhel, Prashant Gaikwad, Stephen Boyd, Brian Masney,
Jerome Brunet, linux-clk, linux-tegra, linux-kernel, stable,
Patrick Fischer, admin
On Thursday, October 29, 2026 6:32 PM Patrick Fischer via B4 Relay wrote:
> From: Patrick Fischer <admin@tsv-stahl-riesa.de>
>
> tegra_fuse_read_early() takes offsets relative to the start of the fuse
> words at FUSE_BEGIN (0x100). When the fuse driver moved out of
> mach-tegra, the Tegra30 speedo code was converted to such offsets
> (FUSE_SPEEDO_CALIB_0 0x114 became 0x14), and the Tegra124 code uses
> them as well. The Tegra114 code kept the absolute offsets from the
> vendor kernel, so since then it reads the CPU and SoC speedo values and
> the A01 CPU2/3 fuses 0x100 bytes too far.
>
> On a Tegra Note 7 (Tegra114 A02, SKU 5) the fuses at the correct
> offsets 0x2c and 0x34 read 718 and 1156. That gives CPU speedo 1742 and
> SoC speedo 1156, which is exactly what the vendor kernel prints for this
> device. The current code reads 172094 and 0, and so reports SoC process
> 0 instead of 1.
>
> Today only the reported process IDs depend on these values, since the
> Tegra114 core OPPs are selected by the SoC speedo ID and the CPU DVFS
> tables apply to all process IDs. The CPU speedo value is needed,
> however, to compute correct CPU DFLL voltages, which the next patch
> fixes.
>
> Fixes: 783c8f4c8445 ("soc/tegra: Add efuse driver for Tegra")
> Cc: stable@vger.kernel.org
> Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
> ---
> drivers/soc/tegra/fuse/speedo-tegra114.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
> index 6695702bdb4c..1e6c2b5be759 100644
> --- a/drivers/soc/tegra/fuse/speedo-tegra114.c
> +++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
> @@ -14,6 +14,11 @@
> #define SOC_PROCESS_CORNERS 2
> #define CPU_PROCESS_CORNERS 2
>
> +#define FUSE_CPU_SPEEDO_1 0x2c
> +#define FUSE_SOC_SPEEDO_0 0x34
> +#define FUSE_OPT_CPU23_DISABLE 0x16c
> +#define FUSE_OPT_CPU23_REENABLE 0x170
> +
> enum {
> THRESHOLD_INDEX_0,
> THRESHOLD_INDEX_1,
> @@ -63,8 +68,8 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
> }
>
> if (rev == TEGRA_REVISION_A01) {
> - tmp = tegra_fuse_read_early(0x270) << 1;
> - tmp |= tegra_fuse_read_early(0x26c);
> + tmp = tegra_fuse_read_early(FUSE_OPT_CPU23_REENABLE) << 1;
> + tmp |= tegra_fuse_read_early(FUSE_OPT_CPU23_DISABLE);
> if (!tmp)
> sku_info->cpu_speedo_id = 0;
> }
> @@ -84,8 +89,8 @@ void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
>
> rev_sku_to_speedo_ids(sku_info, &threshold);
>
> - cpu_speedo_val = tegra_fuse_read_early(0x12c) + 1024;
> - soc_speedo_val = tegra_fuse_read_early(0x134);
> + cpu_speedo_val = tegra_fuse_read_early(FUSE_CPU_SPEEDO_1) + 1024;
> + soc_speedo_val = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
>
> for (i = 0; i < CPU_PROCESS_CORNERS; i++)
> if (cpu_speedo_val < cpu_process_speedos[threshold][i])
>
> --
> 2.56.0
>
>
>
Nice!
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
Tested-by: Mikko Perttunen <mperttunen@nvidia.com> # Dalmore
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values
2026-10-29 9:32 [PATCH 0/3] Tegra114: Fix CPU DFLL voltages Patrick Fischer via B4 Relay
2026-10-29 9:32 ` [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets Patrick Fischer via B4 Relay
@ 2026-10-29 9:33 ` Patrick Fischer via B4 Relay
2026-10-29 10:11 ` Svyatoslav Ryhel
2026-11-02 7:47 ` Mikko Perttunen
2026-10-29 9:33 ` [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators Patrick Fischer via B4 Relay
2 siblings, 2 replies; 10+ messages in thread
From: Patrick Fischer via B4 Relay @ 2026-10-29 9:33 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter
Cc: Mikko Perttunen, Svyatoslav Ryhel, Prashant Gaikwad,
Stephen Boyd, Brian Masney, Jerome Brunet, linux-clk,
linux-tegra, linux-kernel, stable, Patrick Fischer
From: Patrick Fischer <admin@tsv-stahl-riesa.de>
The Tegra114 CPU DFLL computes its OPP voltages from the CVB tables
added in commit 5aba939e80f4 ("clk: tegra: dfll: Add CVB tables for
Tegra114"), using tegra_sku_info.cpu_speedo_value. The Tegra114 speedo
code computes this value but never stores it, so the DFLL uses speedo
0 and only the c0 coefficient remains. For CPU speedo IDs 1 to 3 c0 is
2190643 to 3395401, so "mv * 1000" in round_cvb_voltage() overflows and
the OPP voltages are wrong.
This is currently hidden by a zero voltage step with Palmas regulators,
fixed in the next patch. With both fixes the CPU OPPs range from 1000 mV
to 1270 mV on a device with CPU speedo 1742, which matches the vendor
kernel.
Store the SoC speedo value as well, as Tegra124 and Tegra210 do.
Fixes: 5aba939e80f4 ("clk: tegra: dfll: Add CVB tables for Tegra114")
Cc: stable@vger.kernel.org
Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
---
drivers/soc/tegra/fuse/speedo-tegra114.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
index 1e6c2b5be759..8bf1a1b1287a 100644
--- a/drivers/soc/tegra/fuse/speedo-tegra114.c
+++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
@@ -92,6 +92,9 @@ void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
cpu_speedo_val = tegra_fuse_read_early(FUSE_CPU_SPEEDO_1) + 1024;
soc_speedo_val = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
+ sku_info->cpu_speedo_value = cpu_speedo_val;
+ sku_info->soc_speedo_value = soc_speedo_val;
+
for (i = 0; i < CPU_PROCESS_CORNERS; i++)
if (cpu_speedo_val < cpu_process_speedos[threshold][i])
break;
--
2.56.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values
2026-10-29 9:33 ` [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values Patrick Fischer via B4 Relay
@ 2026-10-29 10:11 ` Svyatoslav Ryhel
2026-11-02 7:47 ` Mikko Perttunen
1 sibling, 0 replies; 10+ messages in thread
From: Svyatoslav Ryhel @ 2026-10-29 10:11 UTC (permalink / raw)
To: admin
Cc: Thierry Reding, Jonathan Hunter, Mikko Perttunen,
Prashant Gaikwad, Stephen Boyd, Brian Masney, Jerome Brunet,
linux-clk, linux-tegra, linux-kernel, stable
чт, 29 жовт. 2026 р. о 11:33 Patrick Fischer via B4 Relay
<devnull+admin.tsv-stahl-riesa.de@kernel.org> пише:
>
> From: Patrick Fischer <admin@tsv-stahl-riesa.de>
>
> The Tegra114 CPU DFLL computes its OPP voltages from the CVB tables
> added in commit 5aba939e80f4 ("clk: tegra: dfll: Add CVB tables for
> Tegra114"), using tegra_sku_info.cpu_speedo_value. The Tegra114 speedo
> code computes this value but never stores it, so the DFLL uses speedo
> 0 and only the c0 coefficient remains. For CPU speedo IDs 1 to 3 c0 is
> 2190643 to 3395401, so "mv * 1000" in round_cvb_voltage() overflows and
> the OPP voltages are wrong.
>
> This is currently hidden by a zero voltage step with Palmas regulators,
> fixed in the next patch. With both fixes the CPU OPPs range from 1000 mV
> to 1270 mV on a device with CPU speedo 1742, which matches the vendor
> kernel.
>
> Store the SoC speedo value as well, as Tegra124 and Tegra210 do.
>
> Fixes: 5aba939e80f4 ("clk: tegra: dfll: Add CVB tables for Tegra114")
> Cc: stable@vger.kernel.org
> Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
> ---
> drivers/soc/tegra/fuse/speedo-tegra114.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
> index 1e6c2b5be759..8bf1a1b1287a 100644
> --- a/drivers/soc/tegra/fuse/speedo-tegra114.c
> +++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
> @@ -92,6 +92,9 @@ void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
> cpu_speedo_val = tegra_fuse_read_early(FUSE_CPU_SPEEDO_1) + 1024;
> soc_speedo_val = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
>
> + sku_info->cpu_speedo_value = cpu_speedo_val;
> + sku_info->soc_speedo_value = soc_speedo_val;
> +
> for (i = 0; i < CPU_PROCESS_CORNERS; i++)
> if (cpu_speedo_val < cpu_process_speedos[threshold][i])
> break;
>
> --
> 2.56.0
>
Thanks!
Tested-by: Svyatoslav Ryhel <clamor95@gmail.com> # Tegratab (P1988)
and ASUS TF701T
Reviewed-by: Svyatoslav Ryhel <clamor95@gmail.com>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values
2026-10-29 9:33 ` [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values Patrick Fischer via B4 Relay
2026-10-29 10:11 ` Svyatoslav Ryhel
@ 2026-11-02 7:47 ` Mikko Perttunen
1 sibling, 0 replies; 10+ messages in thread
From: Mikko Perttunen @ 2026-11-02 7:47 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, linux-clk
Cc: Svyatoslav Ryhel, Prashant Gaikwad, Stephen Boyd, Brian Masney,
Jerome Brunet, linux-clk, linux-tegra, linux-kernel, stable,
Patrick Fischer, admin
On Thursday, October 29, 2026 6:33 PM Patrick Fischer via B4 Relay wrote:
> From: Patrick Fischer <admin@tsv-stahl-riesa.de>
>
> The Tegra114 CPU DFLL computes its OPP voltages from the CVB tables
> added in commit 5aba939e80f4 ("clk: tegra: dfll: Add CVB tables for
> Tegra114"), using tegra_sku_info.cpu_speedo_value. The Tegra114 speedo
> code computes this value but never stores it, so the DFLL uses speedo
> 0 and only the c0 coefficient remains. For CPU speedo IDs 1 to 3 c0 is
> 2190643 to 3395401, so "mv * 1000" in round_cvb_voltage() overflows and
> the OPP voltages are wrong.
>
> This is currently hidden by a zero voltage step with Palmas regulators,
> fixed in the next patch. With both fixes the CPU OPPs range from 1000 mV
> to 1270 mV on a device with CPU speedo 1742, which matches the vendor
> kernel.
>
> Store the SoC speedo value as well, as Tegra124 and Tegra210 do.
>
> Fixes: 5aba939e80f4 ("clk: tegra: dfll: Add CVB tables for Tegra114")
> Cc: stable@vger.kernel.org
> Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
> ---
> drivers/soc/tegra/fuse/speedo-tegra114.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
> index 1e6c2b5be759..8bf1a1b1287a 100644
> --- a/drivers/soc/tegra/fuse/speedo-tegra114.c
> +++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
> @@ -92,6 +92,9 @@ void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
> cpu_speedo_val = tegra_fuse_read_early(FUSE_CPU_SPEEDO_1) + 1024;
> soc_speedo_val = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
>
> + sku_info->cpu_speedo_value = cpu_speedo_val;
> + sku_info->soc_speedo_value = soc_speedo_val;
> +
> for (i = 0; i < CPU_PROCESS_CORNERS; i++)
> if (cpu_speedo_val < cpu_process_speedos[threshold][i])
> break;
>
> --
> 2.56.0
>
>
>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
Tested-by: Mikko Perttunen <mperttunen@nvidia.com> # Dalmore
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators
2026-10-29 9:32 [PATCH 0/3] Tegra114: Fix CPU DFLL voltages Patrick Fischer via B4 Relay
2026-10-29 9:32 ` [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets Patrick Fischer via B4 Relay
2026-10-29 9:33 ` [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values Patrick Fischer via B4 Relay
@ 2026-10-29 9:33 ` Patrick Fischer via B4 Relay
2026-10-29 10:15 ` Svyatoslav Ryhel
2026-11-02 8:30 ` Mikko Perttunen
2 siblings, 2 replies; 10+ messages in thread
From: Patrick Fischer via B4 Relay @ 2026-10-29 9:33 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter
Cc: Mikko Perttunen, Svyatoslav Ryhel, Prashant Gaikwad,
Stephen Boyd, Brian Masney, Jerome Brunet, linux-clk,
linux-tegra, linux-kernel, stable, Patrick Fischer
From: Patrick Fischer <admin@tsv-stahl-riesa.de>
get_alignment_from_regulator() takes the voltage step from
regulator_get_linear_step(), which returns desc->uV_step. Regulators
described by linear ranges, such as the SMPS of the TI Palmas PMIC,
leave uV_step at 0.
With a step of 0, round_cvb_voltage() returns 0 for every OPP, which is
then clamped to min_millivolts, so all CPU OPPs get the same voltage.
The I2C LUT is broken as well: find_vdd_map_entry_exact() and
find_vdd_map_entry_min() divide by the step, and on ARMv7 with hardware
division the result is 0, so selector 0 matches every voltage. The LUT
ends up with a single entry and the DFLL never changes vdd_cpu.
This affects boards that run the DFLL in I2C mode with a Palmas SMPS as
vdd_cpu. In mainline these are the Xiaomi Mi Pad (Tegra124, since v6.19)
and the Asus Transformer Pad TF701T (Tegra114, DFLL enabled for v7.4).
The AS3722 and MAX77621 used by the other DFLL boards report a linear
step, and the PWM mode does not use the regulator.
On a Tegra Note 7 (Tegra114, TPS65913) all 16 CPU OPPs are at 1000 mV
and vdd_cpu stays at the 1.10 V left by the bootloader. The CPU runs at
about 1.34 GHz whatever cpufreq requests. With this patch the OPPs range
from 1000 mV to 1270 mV, the LUT holds the 1000 mV to 1270 mV selectors
and the DFLL follows cpufreq up to 1708.5 MHz.
If the regulator reports no linear step, use the smallest step between
the voltages that are usable on the board. Fail the probe if there is
none instead of running with a step of 0.
Fixes: b3cf8d069505 ("clk: tegra: dfll: CVB calculation alignment with the regulator")
Cc: stable@vger.kernel.org
Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
---
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
index 457a77c5bb62..5bdea4775076 100644
--- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
+++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
@@ -642,6 +642,7 @@ static int get_alignment_from_regulator(struct device *dev,
struct rail_alignment *align)
{
struct regulator *reg = regulator_get(dev, "vdd-cpu");
+ int i, n_voltages, uv, prev_uv = 0;
if (IS_ERR(reg))
return PTR_ERR(reg);
@@ -649,8 +650,33 @@ static int get_alignment_from_regulator(struct device *dev,
align->offset_uv = regulator_list_voltage(reg, 0);
align->step_uv = regulator_get_linear_step(reg);
+ /*
+ * Regulators described by linear ranges (e.g. the Palmas SMPS) don't
+ * report a linear step. Use the smallest step between the voltages
+ * that are usable on this board instead.
+ */
+ if (!align->step_uv) {
+ n_voltages = regulator_count_voltages(reg);
+ for (i = 0; i < n_voltages; i++) {
+ uv = regulator_list_voltage(reg, i);
+ if (uv <= 0)
+ continue;
+
+ if (prev_uv && uv > prev_uv &&
+ (!align->step_uv || uv - prev_uv < align->step_uv))
+ align->step_uv = uv - prev_uv;
+
+ prev_uv = uv;
+ }
+ }
+
regulator_put(reg);
+ if (!align->step_uv) {
+ dev_err(dev, "failed to get vdd-cpu voltage step\n");
+ return -EINVAL;
+ }
+
return 0;
}
--
2.56.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators
2026-10-29 9:33 ` [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators Patrick Fischer via B4 Relay
@ 2026-10-29 10:15 ` Svyatoslav Ryhel
2026-11-02 8:30 ` Mikko Perttunen
1 sibling, 0 replies; 10+ messages in thread
From: Svyatoslav Ryhel @ 2026-10-29 10:15 UTC (permalink / raw)
To: admin
Cc: Thierry Reding, Jonathan Hunter, Mikko Perttunen,
Prashant Gaikwad, Stephen Boyd, Brian Masney, Jerome Brunet,
linux-clk, linux-tegra, linux-kernel, stable
чт, 29 жовт. 2026 р. о 11:33 Patrick Fischer via B4 Relay
<devnull+admin.tsv-stahl-riesa.de@kernel.org> пише:
>
> From: Patrick Fischer <admin@tsv-stahl-riesa.de>
>
> get_alignment_from_regulator() takes the voltage step from
> regulator_get_linear_step(), which returns desc->uV_step. Regulators
> described by linear ranges, such as the SMPS of the TI Palmas PMIC,
> leave uV_step at 0.
>
> With a step of 0, round_cvb_voltage() returns 0 for every OPP, which is
> then clamped to min_millivolts, so all CPU OPPs get the same voltage.
> The I2C LUT is broken as well: find_vdd_map_entry_exact() and
> find_vdd_map_entry_min() divide by the step, and on ARMv7 with hardware
> division the result is 0, so selector 0 matches every voltage. The LUT
> ends up with a single entry and the DFLL never changes vdd_cpu.
>
> This affects boards that run the DFLL in I2C mode with a Palmas SMPS as
> vdd_cpu. In mainline these are the Xiaomi Mi Pad (Tegra124, since v6.19)
> and the Asus Transformer Pad TF701T (Tegra114, DFLL enabled for v7.4).
> The AS3722 and MAX77621 used by the other DFLL boards report a linear
> step, and the PWM mode does not use the regulator.
>
> On a Tegra Note 7 (Tegra114, TPS65913) all 16 CPU OPPs are at 1000 mV
> and vdd_cpu stays at the 1.10 V left by the bootloader. The CPU runs at
> about 1.34 GHz whatever cpufreq requests. With this patch the OPPs range
> from 1000 mV to 1270 mV, the LUT holds the 1000 mV to 1270 mV selectors
> and the DFLL follows cpufreq up to 1708.5 MHz.
>
> If the regulator reports no linear step, use the smallest step between
> the voltages that are usable on the board. Fail the probe if there is
> none instead of running with a step of 0.
>
> Fixes: b3cf8d069505 ("clk: tegra: dfll: CVB calculation alignment with the regulator")
> Cc: stable@vger.kernel.org
> Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
> ---
> drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
> index 457a77c5bb62..5bdea4775076 100644
> --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
> +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
> @@ -642,6 +642,7 @@ static int get_alignment_from_regulator(struct device *dev,
> struct rail_alignment *align)
> {
> struct regulator *reg = regulator_get(dev, "vdd-cpu");
> + int i, n_voltages, uv, prev_uv = 0;
>
> if (IS_ERR(reg))
> return PTR_ERR(reg);
> @@ -649,8 +650,33 @@ static int get_alignment_from_regulator(struct device *dev,
> align->offset_uv = regulator_list_voltage(reg, 0);
> align->step_uv = regulator_get_linear_step(reg);
>
> + /*
> + * Regulators described by linear ranges (e.g. the Palmas SMPS) don't
> + * report a linear step. Use the smallest step between the voltages
> + * that are usable on this board instead.
> + */
> + if (!align->step_uv) {
> + n_voltages = regulator_count_voltages(reg);
> + for (i = 0; i < n_voltages; i++) {
> + uv = regulator_list_voltage(reg, i);
> + if (uv <= 0)
> + continue;
> +
> + if (prev_uv && uv > prev_uv &&
> + (!align->step_uv || uv - prev_uv < align->step_uv))
> + align->step_uv = uv - prev_uv;
> +
> + prev_uv = uv;
> + }
> + }
> +
> regulator_put(reg);
>
> + if (!align->step_uv) {
> + dev_err(dev, "failed to get vdd-cpu voltage step\n");
> + return -EINVAL;
> + }
> +
> return 0;
> }
>
>
> --
> 2.56.0
>
I can confirm capping CPU opps at 1000mV and this patch fixes this. I
have tested on Tegra Note 7, ASUS Transformer Pad TF701T and Xiaomi Mi
Pad which are all affected.
Tested-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Svyatoslav Ryhel <clamor95@gmail.com>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators
2026-10-29 9:33 ` [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators Patrick Fischer via B4 Relay
2026-10-29 10:15 ` Svyatoslav Ryhel
@ 2026-11-02 8:30 ` Mikko Perttunen
1 sibling, 0 replies; 10+ messages in thread
From: Mikko Perttunen @ 2026-11-02 8:30 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, linux-clk
Cc: Svyatoslav Ryhel, Prashant Gaikwad, Stephen Boyd, Brian Masney,
Jerome Brunet, linux-clk, linux-tegra, linux-kernel, stable,
Patrick Fischer, admin
On Thursday, October 29, 2026 6:33 PM Patrick Fischer via B4 Relay wrote:
> From: Patrick Fischer <admin@tsv-stahl-riesa.de>
>
> get_alignment_from_regulator() takes the voltage step from
> regulator_get_linear_step(), which returns desc->uV_step. Regulators
> described by linear ranges, such as the SMPS of the TI Palmas PMIC,
> leave uV_step at 0.
>
> With a step of 0, round_cvb_voltage() returns 0 for every OPP, which is
> then clamped to min_millivolts, so all CPU OPPs get the same voltage.
> The I2C LUT is broken as well: find_vdd_map_entry_exact() and
> find_vdd_map_entry_min() divide by the step, and on ARMv7 with hardware
> division the result is 0, so selector 0 matches every voltage. The LUT
> ends up with a single entry and the DFLL never changes vdd_cpu.
>
> This affects boards that run the DFLL in I2C mode with a Palmas SMPS as
> vdd_cpu. In mainline these are the Xiaomi Mi Pad (Tegra124, since v6.19)
> and the Asus Transformer Pad TF701T (Tegra114, DFLL enabled for v7.4).
> The AS3722 and MAX77621 used by the other DFLL boards report a linear
> step, and the PWM mode does not use the regulator.
>
> On a Tegra Note 7 (Tegra114, TPS65913) all 16 CPU OPPs are at 1000 mV
> and vdd_cpu stays at the 1.10 V left by the bootloader. The CPU runs at
> about 1.34 GHz whatever cpufreq requests. With this patch the OPPs range
> from 1000 mV to 1270 mV, the LUT holds the 1000 mV to 1270 mV selectors
> and the DFLL follows cpufreq up to 1708.5 MHz.
>
> If the regulator reports no linear step, use the smallest step between
> the voltages that are usable on the board. Fail the probe if there is
> none instead of running with a step of 0.
>
> Fixes: b3cf8d069505 ("clk: tegra: dfll: CVB calculation alignment with the regulator")
> Cc: stable@vger.kernel.org
> Signed-off-by: Patrick Fischer <admin@tsv-stahl-riesa.de>
> ---
> drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
> index 457a77c5bb62..5bdea4775076 100644
> --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
> +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
> @@ -642,6 +642,7 @@ static int get_alignment_from_regulator(struct device *dev,
> struct rail_alignment *align)
> {
> struct regulator *reg = regulator_get(dev, "vdd-cpu");
> + int i, n_voltages, uv, prev_uv = 0;
>
> if (IS_ERR(reg))
> return PTR_ERR(reg);
> @@ -649,8 +650,33 @@ static int get_alignment_from_regulator(struct device *dev,
> align->offset_uv = regulator_list_voltage(reg, 0);
> align->step_uv = regulator_get_linear_step(reg);
>
> + /*
> + * Regulators described by linear ranges (e.g. the Palmas SMPS) don't
> + * report a linear step. Use the smallest step between the voltages
> + * that are usable on this board instead.
> + */
> + if (!align->step_uv) {
> + n_voltages = regulator_count_voltages(reg);
> + for (i = 0; i < n_voltages; i++) {
> + uv = regulator_list_voltage(reg, i);
> + if (uv <= 0)
> + continue;
> +
> + if (prev_uv && uv > prev_uv &&
> + (!align->step_uv || uv - prev_uv < align->step_uv))
> + align->step_uv = uv - prev_uv;
> +
> + prev_uv = uv;
> + }
> + }
> +
I think this is a bit of a kludge that happens to work on Palmas but not
necessarily every other regulator. However, all Tegra114 devices there
will ever be already exist, so it's probably fine.
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
> regulator_put(reg);
>
> + if (!align->step_uv) {
> + dev_err(dev, "failed to get vdd-cpu voltage step\n");
> + return -EINVAL;
> + }
> +
> return 0;
> }
>
>
> --
> 2.56.0
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-11-02 8:31 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-29 9:32 [PATCH 0/3] Tegra114: Fix CPU DFLL voltages Patrick Fischer via B4 Relay
2026-10-29 9:32 ` [PATCH 1/3] soc/tegra: fuse: Fix Tegra114 speedo fuse offsets Patrick Fischer via B4 Relay
2026-10-29 10:11 ` Svyatoslav Ryhel
2026-11-02 7:41 ` Mikko Perttunen
2026-10-29 9:33 ` [PATCH 2/3] soc/tegra: fuse: Store Tegra114 CPU and SoC speedo values Patrick Fischer via B4 Relay
2026-10-29 10:11 ` Svyatoslav Ryhel
2026-11-02 7:47 ` Mikko Perttunen
2026-10-29 9:33 ` [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators Patrick Fischer via B4 Relay
2026-10-29 10:15 ` Svyatoslav Ryhel
2026-11-02 8:30 ` Mikko Perttunen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®