From c0491d4fb55eaa7a18cb46dfab886eeb195b9323 Mon Sep 17 00:00:00 2001 From: Hung-Te Lin Date: Tue, 6 Aug 2013 10:48:48 +0800 Subject: armv7/exynos: Fix and remove memory reset workarounds The memory corruption problem in Exynos suspend/resume process is caused by two things together: PHY_RESET and MRS command. After stop sending MRS on resume, we can now remove the workaround of skipping PHY_RESET. Change-Id: I64acc27c1d2bb549ae6ad7d32ecda94b0355972c Reviewed-on: https://gerrit.chromium.org/gerrit/64736 Tested-by: Hung-Te Lin Reviewed-by: David Hendricks Commit-Queue: Hung-Te Lin Reviewed-on: http://review.coreboot.org/4433 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/cpu/samsung/exynos5250/dmc_init_ddr3.c | 10 ++++++++-- src/cpu/samsung/exynos5420/dmc_init_ddr3.c | 12 +++++++++--- src/mainboard/google/snow/romstage.c | 7 ------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/cpu/samsung/exynos5250/dmc_init_ddr3.c b/src/cpu/samsung/exynos5250/dmc_init_ddr3.c index e3d46ab2d5..f2c228d339 100644 --- a/src/cpu/samsung/exynos5250/dmc_init_ddr3.c +++ b/src/cpu/samsung/exynos5250/dmc_init_ddr3.c @@ -158,8 +158,14 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, /* Send PALL command */ dmc_config_prech(mem, dmc); - /* Send NOP, MRS and ZQINIT commands */ - dmc_config_mrs(mem, dmc); + if (mem_reset) { + /* Send NOP, MRS and ZQINIT commands. + * Sending MRS command will reset the DRAM. We should not be + * reseting the DRAM after resume, this will lead to memory + * corruption as DRAM content is lost after DRAM reset + */ + dmc_config_mrs(mem, dmc); + } if (mem->gate_leveling_enable) { val = PHY_CON0_RESET_VAL; diff --git a/src/cpu/samsung/exynos5420/dmc_init_ddr3.c b/src/cpu/samsung/exynos5420/dmc_init_ddr3.c index 74ee7e93a1..ebfe1e1a0f 100644 --- a/src/cpu/samsung/exynos5420/dmc_init_ddr3.c +++ b/src/cpu/samsung/exynos5420/dmc_init_ddr3.c @@ -184,9 +184,15 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, int interleave_size, int reset) writel(mem->timing_power, &drex0->timingpower); writel(mem->timing_power, &drex1->timingpower); - /* Send NOP, MRS and ZQINIT commands */ - dmc_config_mrs(mem, drex0); - dmc_config_mrs(mem, drex1); + /* Send NOP, MRS and ZQINIT commands. + * Sending MRS command will reset the DRAM. We should not be + * reseting the DRAM after resume, this will lead to memory + * corruption as DRAM content is lost after DRAM reset. + */ + if (reset) { + dmc_config_mrs(mem, drex0); + dmc_config_mrs(mem, drex1); + } if (mem->gate_leveling_enable) { diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c index f69fb1f7eb..92fa21e4a1 100644 --- a/src/mainboard/google/snow/romstage.c +++ b/src/mainboard/google/snow/romstage.c @@ -141,13 +141,6 @@ static void setup_memory(struct mem_timings *mem, int is_resume) mem->mpll_mdiv, mem->frequency_mhz); - /* FIXME Currently memory initialization with mem_reset on normal boot - * will cause resume to fail (even if we don't do mem_reset on resume), - * and the workaround is to temporarily always enable "is_resume". - * This should be removed when the root cause of resume issue is found. - */ - is_resume = 1; - if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) { die("Failed to initialize memory controller.\n"); } -- cgit v1.2.3