From: Tien Fong Chee <[email protected]>

A double-bit ECC error (DBE) means the retained DDR contents can no longer
be trusted. Detect the DBE status and force a full DDR init and
calibration in that case instead of taking the retention / warm-reset skip
path.

Signed-off-by: Tien Fong Chee <[email protected]>
Signed-off-by: Chen Huei Lok <[email protected]>
---
 drivers/ddr/altera/sdram_n5x.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
index 9c3f07b409d..f6ce15bffaa 100644
--- a/drivers/ddr/altera/sdram_n5x.c
+++ b/drivers/ddr/altera/sdram_n5x.c
@@ -421,6 +421,17 @@ enum data_process {
        LOADING
 };
 
+bool is_ddr_dbe_triggered(void)
+{
+       u32 reg = readl(socfpga_get_sysmgr_addr() +
+                       SYSMGR_SOC64_BOOT_SCRATCH_COLD8);
+
+       if (reg & ALT_SYSMGR_SCRATCH_REG_8_DDR_DBE_MASK)
+               return true;
+
+       return false;
+}
+
 void ddr_init_inprogress(bool start)
 {
        if (start)
@@ -479,17 +490,20 @@ bool is_ddr_init_skipped(u32 reg)
 
        reset_type_print(reset_t);
 
-       if (reset_t == WARM_RESET) {
-               debug("%s: DDR init is skipped\n", __func__);
-               return true;
-       }
-
-       if (reset_t == COLD_RESET) {
-               if (is_ddr_retention_enabled(reg)) {
-                       debug("%s: DDR retention bit is set\n", __func__);
+       if (!is_ddr_dbe_triggered()) {
+               if (reset_t == WARM_RESET) {
                        debug("%s: DDR init is skipped\n", __func__);
                        return true;
                }
+
+               if (reset_t == COLD_RESET) {
+                       if (is_ddr_retention_enabled(reg)) {
+                               debug("%s: DDR retention bit is set\n",
+                                     __func__);
+                               debug("%s: DDR init is skipped\n", __func__);
+                               return true;
+                       }
+               }
        }
 
        debug("%s: DDR init is required\n", __func__);
@@ -501,7 +515,8 @@ bool is_ddr_calibration_skipped(u32 reg)
        enum reset_type reset_t = get_reset_type(reg);
 
        if ((reset_t == NCONFIG || reset_t == JTAG_CONFIG ||
-            reset_t == RSU_RECONFIG) && is_ddr_retention_enabled(reg)) {
+            reset_t == RSU_RECONFIG) && is_ddr_retention_enabled(reg) &&
+            !is_ddr_dbe_triggered()) {
                debug("%s: DDR retention bit is set\n", __func__);
                return true;
        }
-- 
2.43.7

Reply via email to