[PATCH v2 6/6] drivers: ddr: altera: Improve DRAM init with Dcache

Naresh Kumar Ravulapalli nareshkumar.ravulapalli at altera.com
Mon May 26 20:03:28 CEST 2025


Initialize DRAM memory fully to bring it into a known state. The
process is improved by enabling the Dcache. Also, if hardware
watchdog is configured, it is reconfigured to avoid timeout.

Signed-off-by: Naresh Kumar Ravulapalli <nareshkumar.ravulapalli at altera.com>
Signed-off-by: Tien Fong Chee <tien.fong.chee at altera.com>
---
 drivers/ddr/altera/sdram_arria10.c |  3 +-
 drivers/ddr/altera/sdram_soc32.c   | 75 ++++++++++++++++++++++++++----
 drivers/ddr/altera/sdram_soc32.h   |  2 +-
 3 files changed, 68 insertions(+), 12 deletions(-)

diff --git a/drivers/ddr/altera/sdram_arria10.c b/drivers/ddr/altera/sdram_arria10.c
index a1288d5fb50..6cb5002208b 100644
--- a/drivers/ddr/altera/sdram_arria10.c
+++ b/drivers/ddr/altera/sdram_arria10.c
@@ -4,7 +4,6 @@
  * Copyright (C) 2025 Altera Corporation <www.altera.com>
  */
 
-#include <cpu_func.h>
 #include <errno.h>
 #include <fdtdec.h>
 #include <init.h>
@@ -719,7 +718,7 @@ int ddr_calibration_sequence(void)
 		puts("FW: Error Configuring Firewall\n");
 
 	if (sdram_is_ecc_enabled())
-		sdram_init_ecc_bits(gd->ram_size);
+		sdram_init_ecc_bits();
 
 	sdram_size_check();
 
diff --git a/drivers/ddr/altera/sdram_soc32.c b/drivers/ddr/altera/sdram_soc32.c
index 0b928a2352f..f63360f17d8 100644
--- a/drivers/ddr/altera/sdram_soc32.c
+++ b/drivers/ddr/altera/sdram_soc32.c
@@ -7,25 +7,82 @@
 #include <asm/system.h>
 #include <linux/sizes.h>
 #include "sdram_soc32.h"
+#include <watchdog.h>
+#include <wait_bit.h>
+#if !defined(CONFIG_HW_WATCHDOG)
+#include <asm/arch/reset_manager.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #define PGTABLE_OFF	0x4000
 
 /* Initialize SDRAM ECC bits to avoid false DBE */
-void sdram_init_ecc_bits(u32 size)
+void sdram_init_ecc_bits(void)
 {
-	icache_enable();
+	u32 start;
+	phys_addr_t start_addr, saved_start;
+	phys_size_t size, size_init, saved_size;
+	enum dcache_option option = DCACHE_WRITEBACK;
 
-	memset(0, 0, 0x8000);
-	gd->arch.tlb_addr = 0x4000;
-	gd->arch.tlb_size = PGTABLE_SIZE;
+	if (IS_ENABLED(CONFIG_SYS_ARM_CACHE_WRITETHROUGH))
+		option = DCACHE_WRITETHROUGH;
+	else if (IS_ENABLED(CONFIG_SYS_ARM_CACHE_WRITEALLOC))
+		option = DCACHE_WRITEALLOC;
+
+	start = get_timer(0);
+
+	start_addr = gd->bd->bi_dram[0].start;
+	size = gd->bd->bi_dram[0].size;
 
+	printf("DDRCAL: Initialize ECC RAM (%ld MiB).\n", size >> 20);
+
+	memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF);
+	gd->arch.tlb_addr = start_addr + PGTABLE_OFF;
+	gd->arch.tlb_size = PGTABLE_SIZE;
+	start_addr += PGTABLE_SIZE + PGTABLE_OFF;
+	size -= (PGTABLE_OFF + PGTABLE_SIZE);
 	dcache_enable();
 
-	printf("DDRCAL: Scrubbing ECC RAM (%i MiB).\n", size >> 20);
-	memset((void *)0x8000, 0, size - 0x8000);
-	flush_dcache_all();
-	printf("DDRCAL: Scrubbing ECC RAM done.\n");
+	saved_start = start_addr;
+	saved_size = size;
+	/* Set SDRAM region to writethrough to avoid false double-bit error. */
+	mmu_set_region_dcache_behaviour(saved_start, saved_size,
+					DCACHE_WRITETHROUGH);
+
+	while (size > 0) {
+		size_init = min((phys_addr_t)SZ_1G, (phys_addr_t)size);
+		memset((void *)start_addr, 0, size_init);
+		size -= size_init;
+		start_addr += size_init;
+
+		if (IS_ENABLED(CONFIG_HW_WATCHDOG)) {
+			/*
+			 * In case the watchdog is enabled,
+			 * make sure to (re-)configure watchdog
+			 * so that the defined timeout is valid.
+			 */
+			debug("%s: %d\n", __func__, __LINE__);
+			hw_watchdog_init();
+		} else {
+			/*
+			 * If the HW watchdog is NOT enabled,
+			 * make sure it is not running, because
+			 * it is enabled in the preloader and
+			 * causing boot loop if is not handled.
+			 */
+			debug("%s: %d\n", __func__, __LINE__);
+			socfpga_per_reset(SOCFPGA_RESET(L4WD0), 1);
+			socfpga_per_reset(SOCFPGA_RESET(L4WD0), 0);
+		}
+	}
+
 	dcache_disable();
+
+	/* Restore back to original dcache behaviour. */
+	mmu_set_region_dcache_behaviour(saved_start, saved_size,
+					option);
+
+	printf("DDRCAL: SDRAM-ECC successfully initialized within %d ms\n",
+	       (u32)get_timer(start));
 }
diff --git a/drivers/ddr/altera/sdram_soc32.h b/drivers/ddr/altera/sdram_soc32.h
index 4c6137e728d..85a951a5a74 100644
--- a/drivers/ddr/altera/sdram_soc32.h
+++ b/drivers/ddr/altera/sdram_soc32.h
@@ -6,6 +6,6 @@
 #ifndef	_SDRAM_SOC32_H_
 #define	_SDRAM_SOC32_H_
 
-void sdram_init_ecc_bits(u32 size);
+void sdram_init_ecc_bits(void);
 
 #endif /* _SDRAM_SOC32_H_ */
-- 
2.35.3



More information about the U-Boot mailing list