diff --git a/arch/arm/mach-socfpga/include/mach/sdram_s10.h b/arch/arm/mach-socfpga/include/mach/sdram_s10.h
index 89e355010d..354f80bfce 100644
--- a/arch/arm/mach-socfpga/include/mach/sdram_s10.h
+++ b/arch/arm/mach-socfpga/include/mach/sdram_s10.h
@@ -23,6 +23,7 @@ void setup_memory_banks(phys_addr_t bank_addr[], phys_size_t bank_size[]);
 #define ECCCTRL1			0x100
 #define ECCCTRL2			0x104
 #define ERRINTEN			0x110
+#define ERRINTENS			0x114
 #define INTMODE				0x11c
 #define INTSTAT				0x120
 #define AUTOWB_CORRADDR			0x138
@@ -53,6 +54,10 @@ void setup_memory_banks(phys_addr_t bank_addr[], phys_size_t bank_size[]);
 #define DDR_HMC_SEQ2CORE_INT_RESP_MASK		BIT(3)
 #define DDR_HMC_HPSINTFCSEL_ENABLE_MASK		0x001f1f1f
 
+#define	DDR_HMC_ERRINTEN_INTMASK				\
+		(DDR_HMC_ERRINTEN_SERRINTEN_EN_SET_MSK |	\
+		 DDR_HMC_ERRINTEN_DERRINTEN_EN_SET_MSK)
+
 /* NOC DDR scheduler */
 #define DDR_SCH_ID_COREID		0
 #define DDR_SCH_ID_REVID		0x4
@@ -181,4 +186,8 @@ void setup_memory_banks(phys_addr_t bank_addr[], phys_size_t bank_size[]);
 #define CALTIMING9_CFG_4_ACT_TO_ACT(x)			\
 	(((x) >> 0) & 0xFF)
 
+/* Firewall DDR scheduler MPFE */
+#define FW_HMC_ADAPTOR_REG_ADDR			0xf8020004
+#define FW_HMC_ADAPTOR_MPU_MASK			BIT(0)
+
 #endif /* _SDRAM_S10_H_ */
diff --git a/drivers/ddr/altera/sdram_s10.c b/drivers/ddr/altera/sdram_s10.c
index ae4e5ea2fd..2c691d3bee 100644
--- a/drivers/ddr/altera/sdram_s10.c
+++ b/drivers/ddr/altera/sdram_s10.c
@@ -22,6 +22,8 @@ static const struct socfpga_system_manager *sysmgr_regs =
 
 #define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
 
+#define PGTABLE_OFF	0x4000
+
 /* The followring are the supported configurations */
 u32 ddr_config[] = {
 	/* DDR_CONFIG(Address order,Bank,Column,Row) */
@@ -135,6 +137,71 @@ static int poll_hmc_clock_status(void)
 				 SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false);
 }
 
+static void sdram_clear_mem(phys_addr_t addr, phys_size_t size)
+{
+	phys_size_t i;
+
+	if (addr % CONFIG_SYS_CACHELINE_SIZE) {
+		printf("DDR: address 0x%lx not cacheline size aligned.\n",
+		       (ulong)addr);
+		hang();
+	}
+
+	if (size % CONFIG_SYS_CACHELINE_SIZE) {
+		printf("DDR: size 0x%lx not multiple of cacheline size\n",
+		       (ulong)size);
+		hang();
+	}
+
+	/* Use DC ZVA instruction to clear memory to zeros by a cache line */
+	for (i = 0; i < size; i = i + CONFIG_SYS_CACHELINE_SIZE) {
+		asm("dc zva, %0"
+		     :
+		     : "r"(addr));
+		addr += CONFIG_SYS_CACHELINE_SIZE;
+	}
+}
+
+static void sdram_init_ecc_bits(phys_addr_t *bank_start, phys_size_t *bank_size)
+{
+	phys_size_t size, size_init;
+	phys_addr_t start_addr;
+	int bank;
+	unsigned int start = get_timer(0);
+
+	icache_enable();
+
+	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+		start_addr = bank_start[bank];
+		size = bank_size[bank];
+
+		if (bank == 0) {
+			/* Initialize small block for page table */
+			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();
+		}
+
+		while (size) {
+			size_init = min((phys_addr_t)SZ_1G, (phys_addr_t)size);
+			sdram_clear_mem(start_addr, size_init);
+			size -= size_init;
+			start_addr += size_init;
+			WATCHDOG_RESET();
+		}
+	}
+
+	dcache_disable();
+	icache_disable();
+
+	printf("SDRAM-ECC: Initialized success with %d ms\n",
+	       (unsigned int)get_timer(start));
+}
+
 static void sdram_size_check(phys_addr_t bank_start[], phys_size_t bank_size[])
 {
 	phys_size_t total_ram_check = 0;
@@ -451,6 +518,15 @@ int sdram_mmr_init_full(unsigned int unused)
 		setbits_le32(SOCFPGA_SDR_ADDRESS + ECCCTRL2,
 			     (DDR_HMC_ECCCTL2_RMW_EN_SET_MSK |
 			      DDR_HMC_ECCCTL2_AWB_EN_SET_MSK));
+		writel(DDR_HMC_ERRINTEN_INTMASK,
+		       SOCFPGA_SDR_ADDRESS + ERRINTENS);
+
+		/* Enable non-secure writes to HMC Adapter for SDRAM ECC */
+		writel(FW_HMC_ADAPTOR_MPU_MASK, FW_HMC_ADAPTOR_REG_ADDR);
+
+		/* Initialize memory content if not from warm reset */
+		if (!cpu_has_been_warmreset())
+			sdram_init_ecc_bits(bank_start, bank_size);
 	} else {
 		clrbits_le32(SOCFPGA_SDR_ADDRESS + ECCCTRL1,
 			     (DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK |
