It is been a while that the DDR ECC is missing.
Pull from Altera trunk and sync to mainstream.
This sdram_soc32 introduce the ecc setup.
Modifications are done to support dts memory@0
while old memory will work properly on gd->bd
Real ECC supported board test is required.

Signed-off-by: Brian Sune <[email protected]>
---
 drivers/ddr/altera/sdram_soc32.c | 71 ++++++++++++++++++++++++++++++++
 drivers/ddr/altera/sdram_soc32.h | 11 +++++
 2 files changed, 82 insertions(+)
 create mode 100644 drivers/ddr/altera/sdram_soc32.c
 create mode 100644 drivers/ddr/altera/sdram_soc32.h

diff --git a/drivers/ddr/altera/sdram_soc32.c b/drivers/ddr/altera/sdram_soc32.c
new file mode 100644
index 00000000000..e82146e448e
--- /dev/null
+++ b/drivers/ddr/altera/sdram_soc32.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ */
+
+#include <cpu_func.h>
+#include <dm.h>
+#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
+
+#define PGTABLE_OFF    0x4000
+
+/* Initialize SDRAM ECC bits to avoid false DBE */
+void sdram_init_ecc_bits(unsigned long long sdram_size)
+{
+       u32 start;
+       phys_addr_t start_addr;
+       phys_size_t size, size_init;
+
+       start = get_timer(0);
+
+       start_addr = 0;
+       size = sdram_size;
+
+       printf("DDRCAL: Scrubbing ECC RAM (%ld MiB).\n", size >> 20);
+
+       memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF);
+       start_addr += PGTABLE_SIZE + PGTABLE_OFF;
+       size -= PGTABLE_OFF + PGTABLE_SIZE;
+
+       dcache_enable();
+
+       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;
+
+               debug("%s: %d\n", __func__, __LINE__);
+
+#ifdef CONFIG_HW_WATCHDOG
+               /*
+                * In case the watchdog is enabled,
+                * make sure to (re-)configure watchdog
+                * so that the defined timeout is valid.
+                */
+               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.
+                */
+               socfpga_per_reset(SOCFPGA_RESET(L4WD0), 1);
+               socfpga_per_reset(SOCFPGA_RESET(L4WD0), 0);
+#endif
+       }
+
+       dcache_disable();
+
+       printf("DDRCAL: SDRAM-ECC initialized success with %d ms\n",
+              (u32)get_timer(start));
+}
+
diff --git a/drivers/ddr/altera/sdram_soc32.h b/drivers/ddr/altera/sdram_soc32.h
new file mode 100644
index 00000000000..7bd76eb560f
--- /dev/null
+++ b/drivers/ddr/altera/sdram_soc32.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ */
+
+#ifndef        _SDRAM_SOC32_H_
+#define        _SDRAM_SOC32_H_
+
+void sdram_init_ecc_bits(unsigned long long sdram_size);
+
+#endif /* _SDRAM_SOC32_H_ */
-- 
2.34.1

Reply via email to