diff mbox series

ddr: socfpga: Improve A10 SDRAM ECC init function to support watchdog reset

Message ID 20220919005729.21002-1-teik.heng.chong@intel.com
State Needs Review / ACK, archived
Delegated to: Marek Vasut
Headers show
Series ddr: socfpga: Improve A10 SDRAM ECC init function to support watchdog reset | expand

Commit Message

Chong, Teik Heng Sept. 19, 2022, 12:57 a.m. UTC
From: Tien Fong Chee <tien.fong.chee@intel.com>

There is a potential risk that memset on DDR taking too long than the
timeout set for watchdog, hence the function is restructured so that
splitting up the DDR into chunks for memset and resetting the watchdog for
each chunk memory.

Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
Signed-off-by: Teik Heng Chong <teik.heng.chong@intel.com>
---
 drivers/ddr/altera/sdram_arria10.c | 38 ++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/drivers/ddr/altera/sdram_arria10.c b/drivers/ddr/altera/sdram_arria10.c
index 4a8f8dea1c..6eb7a34bc0 100644
--- a/drivers/ddr/altera/sdram_arria10.c
+++ b/drivers/ddr/altera/sdram_arria10.c
@@ -22,6 +22,7 @@ 
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
+#include <linux/sizes.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -48,6 +49,8 @@  static u64 sdram_size_calc(void);
 #define CORE2SEQ_INT_REQ	0xF
 #define SEQ2CORE_INT_RESP_BIT	3
 
+#define PGTABLE_OFF	0x4000
+
 static const struct socfpga_ecc_hmc *socfpga_ecc_hmc_base =
 		(void *)SOCFPGA_SDR_ADDRESS;
 static const struct socfpga_noc_ddr_scheduler *socfpga_noc_ddr_scheduler_base =
@@ -196,19 +199,44 @@  static int sdram_is_ecc_enabled(void)
 /* Initialize SDRAM ECC bits to avoid false DBE */
 static void sdram_init_ecc_bits(u32 size)
 {
-	icache_enable();
+	u32 start, size_init, start_addr;
+
+	start = get_timer(0);
+
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	gd->bd->bi_dram[0].size = size;
 
-	memset(0, 0, 0x8000);
-	gd->arch.tlb_addr = 0x4000;
+	gd->arch.tlb_addr = gd->bd->bi_dram[0].start + PGTABLE_OFF;
 	gd->arch.tlb_size = PGTABLE_SIZE;
 
+	memset((void *)gd->bd->bi_dram[0].start, 0, gd->arch.tlb_addr +
+	       gd->arch.tlb_size + SZ_1K);
+
+	icache_enable();
 	dcache_enable();
 
-	printf("DDRCAL: Scrubbing ECC RAM (%i MiB).\n", size >> 20);
-	memset((void *)0x8000, 0, size - 0x8000);
+	start_addr = gd->arch.tlb_addr + gd->arch.tlb_size;
+	size -= (gd->arch.tlb_addr + gd->arch.tlb_size);
+
+	printf("DDRCAL: Scrubbing ECC RAM (%d MiB).\n", size >> 20);
+
+
+	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;
+		WATCHDOG_RESET();
+	}
+
 	flush_dcache_all();
+
 	printf("DDRCAL: Scrubbing ECC RAM done.\n");
+
 	dcache_disable();
+
+	printf("DDRCAL: SDRAM-ECC initialized success with %d ms\n",
+	       (u32)get_timer(start));
 }
 
 /* Function to startup the SDRAM*/