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

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 --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*/
participants (1)
-
teik.heng.chong@intel.com