Re: [PATCH 3/3] clk: tegra: dfll: Get the voltage step of range-based regulators
From: Svyatoslav Ryhel
Date: Thu Oct 29 2026 - 06:17:15 EST
чт, 29 жовт. 2026 р. о 11:33 Patrick Fischer via B4 Relay
<devnull+admin.tsv-stahl-riesa.de@xxxxxxxxxx> пише:
>
> From: Patrick Fischer <admin@xxxxxxxxxxxxxxxxxx>
>
> 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@xxxxxxxxxxxxxxx
> Signed-off-by: Patrick Fischer <admin@xxxxxxxxxxxxxxxxxx>
> ---
> 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@xxxxxxxxx>
Reviewed-by: Svyatoslav Ryhel <clamor95@xxxxxxxxx>