@@ -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*/