clk: soc: tegra: Add DFLL tune high margin voltage

Added DFLL tune high margin voltage entry in CVB table. This allows to
replace current fixed margin defined as number of DFLL voltage steps
with per-table/per-chip margin in millivolts, and convert it to steps
during DFLL initialization.

Bug 1967884

Change-Id: I56268ae2faf9cc633b9f988cacbfd0ea3ba77ff3
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1576307
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Alex Frid authored and Thomas Makin committed 2026-08-28 19:17:10 -05:00
1 parent cbf2e8abe9
commit 3543245775
4 files changed
+44 -5

No files matched your search

+37 -5
View File
@@ -886,10 +886,10 @@ static void dfll_load_i2c_lut(struct tegra_dfll *td)
u32 val;
for (i = 0; i < MAX_DFLL_VOLTAGES; i++) {
if (i < td->lut_min)
lut_index = td->lut_min;
else if (i > td->lut_max)
lut_index = td->lut_max;
if (i < td->lut_bottom)
lut_index = td->lut_bottom;
else if (i > td->lut_size - 1)
lut_index = td->lut_size - 1;
else
lut_index = i;
@@ -1020,6 +1020,28 @@ static int find_lut_index_for_rate(struct tegra_dfll *td, unsigned long rate)
return -ENOENT;
}
/**
* find_mv_out_cap - find the out_map index with voltage >= @mv
* @td: DFLL instance
* @mv: millivolts
*
* Find the lut index with voltage greater than or equal to @mv,
* and return it. If all of the voltages in out_map are less than
* @mv, then return the lut index * corresponding to the highest
* possible voltage, even though it's less than @mv.
*/
static u8 find_mv_out_cap(struct tegra_dfll *td, int mv)
{
u8 i;
for (i = td->lut_bottom; i < td->lut_size; i++) {
if (td->lut_uv[i] >= mv * 1000)
return i;
}
return i - 1; /* maximum possible output */
}
/**
* dfll_calculate_rate_request - calculate DFLL parameters for a given rate
* @td: DFLL instance
@@ -1704,7 +1726,17 @@ static void dfll_init_tuning_thresholds(struct tegra_dfll *td)
if ((out_min + 2) > max_voltage_index)
return;
out_start = out_min + DFLL_TUNE_HIGH_MARGIN_STEPS;
if (td->soc->cvb->cpu_dfll_data.tune_high_margin_millivolts) {
unsigned int mv;
mv = td->soc->tune_high_min_millivolts +
td->soc->cvb->cpu_dfll_data.tune_high_margin_millivolts;
if (mv * 1000 > td->lut_uv[max_voltage_index])
return;
out_start = max((u8)(out_min + 1), find_mv_out_cap(td, mv));
} else {
out_start = out_min + DFLL_TUNE_HIGH_MARGIN_STEPS;
}
if (out_start > max_voltage_index)
return;
+2
View File
@@ -31,6 +31,8 @@ struct tegra_dfll_soc_data {
unsigned long max_freq;
const struct cvb_table *cvb;
struct rail_alignment alignment;
unsigned int min_millivolts;
unsigned int tune_high_min_millivolts;
void (*init_clock_trimmers)(void);
void (*set_clock_trimmers_high)(void);
@@ -685,6 +685,7 @@ static struct cvb_table tegra210b01_cpu_cvb_tables[] = {
.tune1_low = 0x012207ff,
.tune1_high = 0x03FFF7FF,
.tune_high_min_millivolts = 850,
.tune_high_margin_millivolts = 38,
}
},
{
@@ -697,6 +698,7 @@ static struct cvb_table tegra210b01_cpu_cvb_tables[] = {
.tune0_high = 0x0000ffff,
.tune1_low = 0x021107ff,
.tune_high_min_millivolts = 850,
.tune_high_margin_millivolts = 38,
}
},
{
@@ -709,6 +711,7 @@ static struct cvb_table tegra210b01_cpu_cvb_tables[] = {
.tune0_high = 0x0000ffff,
.tune1_low = 0x021107ff,
.tune_high_min_millivolts = 850,
.tune_high_margin_millivolts = 38,
}
},
{
@@ -720,6 +723,7 @@ static struct cvb_table tegra210b01_cpu_cvb_tables[] = {
.tune0_low = 0x0000ffcf,
.tune1_low = 0x012207ff,
.tune_high_min_millivolts = 850,
.tune_high_margin_millivolts = 38,
}
},
};
+1
View File
@@ -34,6 +34,7 @@ struct cvb_cpu_dfll_data {
u32 tune1_low;
u32 tune1_high;
unsigned int tune_high_min_millivolts;
unsigned int tune_high_margin_millivolts;
};
struct cvb_table {