@@ -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) {
- 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(C1D0U0, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C1D0U0);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C1D0U0, cval);
-
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C1D0U0] -
- __MOVAVG_AC(next, C1D0U0);
- 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[C1D0U0] =
- __MOVAVG_AC(next, C1D0U0);
- }
-
+ 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][1];
- }
-
- 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_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C1D0U1] -
- __MOVAVG_AC(next, C1D0U1);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
-
- if (tmdel > adel)
- adel = tmdel;
+ /* Dev[d] MSB */
+ value = tegra210_emc_mrr_read(emc, 2 - d, 19);
- if (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C1D0U1] =
- __MOVAVG_AC(next, C1D0U1);
- }
- }
-
- 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);
- }
+ for (c = 0; c < emc->num_channels; c++) {
+ temp[c][0] = (value & 0x00ff) << 8;
+ temp[c][1] = (value & 0xff00) << 0;
+ 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][1];
- }
+ /* Dev[d] LSB */
+ value = tegra210_emc_mrr_read(emc, 2 - d, 18);
- 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];
+ 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(C1D1U0, cval);
- else if (dvfs_update)
- __AVERAGE_PTFV(C1D1U0);
- else if (periodic_training_update)
- __WEIGHTED_UPDATE_PTFV(C1D1U0, 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[C1D1U0] -
- __MOVAVG_AC(next, C1D1U0);
- 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[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 (tmdel * 128 * next_timing_rate_mhz / 1000000 >
+ next->tree_margin)
+ next->current_dram_clktree[idx] =
+ __MOVAVG_AC(next, idx);
+ }
- if (dvfs_update || periodic_training_update) {
- tdel = next->current_dram_clktree[C1D1U1] -
- __MOVAVG_AC(next, C1D1U1);
- tmdel = (tdel < 0) ? -1 * tdel : tdel;
+ /* C[c]D[d]U[1] */
+ idx++;
- if (tmdel > adel)
- adel = tmdel;
+ 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 (tmdel * 128 * next_timing_rate_mhz / 1000000 >
- next->tree_margin)
- next->current_dram_clktree[C1D1U1] =
- __MOVAVG_AC(next, C1D1U1);
+ 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;
+
+ 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);
+ }
}
}
-done:
return adel;
}
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> --- drivers/memory/tegra/tegra210-emc-cc-r21021.c | 322 ++++++-------------------- 1 file changed, 67 insertions(+), 255 deletions(-)