[PATCH 3/6] memory: tegra114-emc: Always restore the auto-calibration interval

From: Patrick Fischer via B4 Relay

Date: Wed Nov 11 2026 - 05:19:51 EST


From: Patrick Fischer <admin@xxxxxxxxxxxxxxxxxx>

tegra114_emc_prepare_timing_change() disables pad auto-calibration for
every clock change by writing 0 to EMC_AUTO_CAL_INTERVAL. The interval
is only written back if EMC_CTT_TERM_CTRL differs between the old and
the new timing, which is not the case with the usual tables, so after
the first rate change auto-calibration stays off for good. Read back on
a Tegra Note 7 (P1640) after a few rate changes, EMC_AUTO_CAL_INTERVAL
is 0 and EMC_AUTO_CAL_STATUS no longer changes.

The Tegra124 driver this code is based on writes the interval back
unconditionally for DDR3 as part of its BGBIAS handling, which was left
out for Tegra114. The downstream Tegra114 driver (tegra11_emc.c,
rel-tegranote-r8) also restores it after every clock change.

Restore the interval unconditionally.

Fixes: dce208b5405f ("memory: tegra: Add Tegra114 EMC driver")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Patrick Fischer <admin@xxxxxxxxxxxxxxxxxx>
---
drivers/memory/tegra/tegra114-emc.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/memory/tegra/tegra114-emc.c b/drivers/memory/tegra/tegra114-emc.c
index 6ec1bb2c3ed0..9de3f2e728ea 100644
--- a/drivers/memory/tegra/tegra114-emc.c
+++ b/drivers/memory/tegra/tegra114-emc.c
@@ -706,7 +706,6 @@ static void tegra114_emc_complete_timing_change(struct tegra_emc *emc,
unsigned long rate)
{
struct emc_timing *timing = tegra114_emc_find_timing(emc, rate);
- struct emc_timing *last = &emc->last_timing;

if (!timing)
return;
@@ -714,10 +713,9 @@ static void tegra114_emc_complete_timing_change(struct tegra_emc *emc,
/* Wait until the state machine has settled */
emc_seq_wait_clkchange(emc);

- /* Restore AUTO_CAL */
- if (timing->emc_ctt_term_ctrl != last->emc_ctt_term_ctrl)
- writel(timing->emc_auto_cal_interval,
- emc->regs + EMC_AUTO_CAL_INTERVAL);
+ /* Restore AUTO_CAL, it was disabled for the clock change */
+ writel(timing->emc_auto_cal_interval,
+ emc->regs + EMC_AUTO_CAL_INTERVAL);

/* Restore dynamic self-refresh */
if (timing->emc_cfg & EMC_CFG_PWR_MASK)

--
2.56.0