1
0

memory: tegra: Loop update_clock_tree_delay()

As the current form of this function in a completely unrolled loop
over the RAM channels roll it up two levels to improve readability.

Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
Link: https://lore.kernel.org/r/20240704-tegra210_emcfreq-v4-5-3e450503c555@tecnico.ulisboa.pt
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
This commit is contained in:
Diogo Ivo
2024-07-04 12:31:24 +01:00
committed by Krzysztof Kozlowski
parent a238f62b36
commit adc720820f

View File

@@ -125,7 +125,7 @@ static u32 update_clock_tree_delay(struct tegra210_emc *emc, int type)
bool dvfs_pt1 = type == DVFS_PT1;
u32 temp[2][2], value, delay_us;
unsigned long cval = 0;
unsigned int i;
unsigned int c, d, idx;
if (dvfs_pt1 || periodic_training_update) {
delay_us = tegra210_emc_actual_osc_clocks(last->run_clocks);
@@ -136,276 +136,88 @@ static u32 update_clock_tree_delay(struct tegra210_emc *emc, int type)
udelay(delay_us);
}
/*
* Dev0 MSB.
*/
if (dvfs_pt1 || periodic_training_update) {
value = tegra210_emc_mrr_read(emc, 2, 19);
for (i = 0; i < emc->num_channels; i++) {
temp[i][0] = (value & 0x00ff) << 8;
temp[i][1] = (value & 0xff00) << 0;
value >>= 16;
}
/*
* Dev0 LSB.
*/
value = tegra210_emc_mrr_read(emc, 2, 18);
for (i = 0; i < emc->num_channels; i++) {
temp[i][0] |= (value & 0x00ff) >> 0;
temp[i][1] |= (value & 0xff00) >> 8;
value >>= 16;
}
}
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[0][0];
}
if (dvfs_pt1)
__INCREMENT_PTFV(C0D0U0, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C0D0U0);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C0D0U0, cval);
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C0D0U0] -
__MOVAVG_AC(next, C0D0U0);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C0D0U0] =
__MOVAVG_AC(next, C0D0U0);
}
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[0][1];
}
if (dvfs_pt1)
__INCREMENT_PTFV(C0D0U1, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C0D0U1);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C0D0U1, cval);
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C0D0U1] -
__MOVAVG_AC(next, C0D0U1);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (tmdel > adel)
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C0D0U1] =
__MOVAVG_AC(next, C0D0U1);
}
if (emc->num_channels > 1) {
for (d = 0; d < emc->num_devices; d++) {
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[1][0];
/* Dev[d] MSB */
value = tegra210_emc_mrr_read(emc, 2 - d, 19);
for (c = 0; c < emc->num_channels; c++) {
temp[c][0] = (value & 0x00ff) << 8;
temp[c][1] = (value & 0xff00) << 0;
value >>= 16;
}
/* Dev[d] LSB */
value = tegra210_emc_mrr_read(emc, 2 - d, 18);
for (c = 0; c < emc->num_channels; c++) {
temp[c][0] |= (value & 0x00ff) >> 0;
temp[c][1] |= (value & 0xff00) >> 8;
value >>= 16;
}
}
if (dvfs_pt1)
__INCREMENT_PTFV(C1D0U0, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C1D0U0);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C1D0U0, cval);
for (c = 0; c < emc->num_channels; c++) {
/* C[c]D[d]U[0] */
idx = c * 4 + d * 2;
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C1D0U0] -
__MOVAVG_AC(next, C1D0U0);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[c][0];
}
if (tmdel > adel)
if (dvfs_pt1)
__INCREMENT_PTFV(idx, cval);
else if (dvfs_update)
__AVERAGE_PTFV(idx);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(idx, cval);
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[idx] -
__MOVAVG_AC(next, idx);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C1D0U0] =
__MOVAVG_AC(next, C1D0U0);
}
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[idx] =
__MOVAVG_AC(next, idx);
}
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[1][1];
}
/* C[c]D[d]U[1] */
idx++;
if (dvfs_pt1)
__INCREMENT_PTFV(C1D0U1, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C1D0U1);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C1D0U1, cval);
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[c][1];
}
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C1D0U1] -
__MOVAVG_AC(next, C1D0U1);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (dvfs_pt1)
__INCREMENT_PTFV(idx, cval);
else if (dvfs_update)
__AVERAGE_PTFV(idx);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(idx, cval);
if (tmdel > adel)
adel = tmdel;
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[idx] -
__MOVAVG_AC(next, idx);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C1D0U1] =
__MOVAVG_AC(next, C1D0U1);
if (tmdel > adel)
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[idx] =
__MOVAVG_AC(next, idx);
}
}
}
if (emc->num_devices < 2)
goto done;
/*
* Dev1 MSB.
*/
if (dvfs_pt1 || periodic_training_update) {
value = tegra210_emc_mrr_read(emc, 1, 19);
for (i = 0; i < emc->num_channels; i++) {
temp[i][0] = (value & 0x00ff) << 8;
temp[i][1] = (value & 0xff00) << 0;
value >>= 16;
}
/*
* Dev1 LSB.
*/
value = tegra210_emc_mrr_read(emc, 1, 18);
for (i = 0; i < emc->num_channels; i++) {
temp[i][0] |= (value & 0x00ff) >> 0;
temp[i][1] |= (value & 0xff00) >> 8;
value >>= 16;
}
}
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[0][0];
}
if (dvfs_pt1)
__INCREMENT_PTFV(C0D1U0, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C0D1U0);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C0D1U0, cval);
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C0D1U0] -
__MOVAVG_AC(next, C0D1U0);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (tmdel > adel)
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C0D1U0] =
__MOVAVG_AC(next, C0D1U0);
}
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[0][1];
}
if (dvfs_pt1)
__INCREMENT_PTFV(C0D1U1, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C0D1U1);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C0D1U1, cval);
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C0D1U1] -
__MOVAVG_AC(next, C0D1U1);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (tmdel > adel)
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C0D1U1] =
__MOVAVG_AC(next, C0D1U1);
}
if (emc->num_channels > 1) {
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[1][0];
}
if (dvfs_pt1)
__INCREMENT_PTFV(C1D1U0, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C1D1U0);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C1D1U0, cval);
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C1D1U0] -
__MOVAVG_AC(next, C1D1U0);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (tmdel > adel)
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C1D1U0] =
__MOVAVG_AC(next, C1D1U0);
}
if (dvfs_pt1 || periodic_training_update) {
cval = tegra210_emc_actual_osc_clocks(last->run_clocks);
cval *= 1000000;
cval /= last_timing_rate_mhz * 2 * temp[1][1];
}
if (dvfs_pt1)
__INCREMENT_PTFV(C1D1U1, cval);
else if (dvfs_update)
__AVERAGE_PTFV(C1D1U1);
else if (periodic_training_update)
__WEIGHTED_UPDATE_PTFV(C1D1U1, cval);
if (dvfs_update || periodic_training_update) {
tdel = next->current_dram_clktree[C1D1U1] -
__MOVAVG_AC(next, C1D1U1);
tmdel = (tdel < 0) ? -1 * tdel : tdel;
if (tmdel > adel)
adel = tmdel;
if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
next->tree_margin)
next->current_dram_clktree[C1D1U1] =
__MOVAVG_AC(next, C1D1U1);
}
}
done:
return adel;
}