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.ravulapa...@altera.com> Signed-off-by: Tien Fong Chee <tien.fong.c...@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