From a4fc93b5b28f8c733fcc54a0bc428481edd583ee Mon Sep 17 00:00:00 2001
From: Andrey Skvortsov <andrej.skvortzov@gmail.com>
Date: Tue, 5 Mar 2024 20:30:10 -0500
Subject: [PATCH] sunxi: reorganize mctl_mem_matches_* functions

mctl_mem_matches and mctl_mem_matches_base identical functions. To
avoid code duplication move them to dram_helpers and make
mctl_mem_matches use generic mctl_mem_matches_base.

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm/include/asm/arch-sunxi/dram.h |  1 +
 arch/arm/mach-sunxi/dram_sunxi_dw.c    | 14 --------------
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
index 682daae6b1..9d21b49241 100644
--- a/arch/arm/include/asm/arch-sunxi/dram.h
+++ b/arch/arm/include/asm/arch-sunxi/dram.h
@@ -40,5 +40,6 @@
 unsigned long sunxi_dram_init(void);
 void mctl_await_completion(u32 *reg, u32 mask, u32 val);
 bool mctl_mem_matches(u32 offset);
+bool mctl_mem_matches_base(u32 offset, ulong base);
 
 #endif /* _SUNXI_DRAM_H */
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index 9382d3d0be..4dc1a19641 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -652,20 +652,6 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
 	return 0;
 }
 
-/*
- * Test if memory at offset offset matches memory at a certain base
- */
-static bool mctl_mem_matches_base(u32 offset, ulong base)
-{
-	/* Try to write different values to RAM at two addresses */
-	writel(0, base);
-	writel(0xaa55aa55, base + offset);
-	dsb();
-	/* Check if the same value is actually observed when reading back */
-	return readl(base) ==
-	       readl(base + offset);
-}
-
 static void mctl_auto_detect_dram_size_rank(uint16_t socid, struct dram_para *para, ulong base, struct rank_para *rank)
 {
 	/* detect row address bits */
-- 
2.39.2

From 1800c04c0212b87cebc6314cfd88d8b7e3f56970 Mon Sep 17 00:00:00 2001
From: Andrey Skvortsov <andrej.skvortzov@gmail.com>
Date: Tue, 5 Mar 2024 20:18:25 -0500
Subject: [PATCH] sunxi: restore modified memory

Current sunxi DRAM initialisation code does several test accesses to the
DRAM array to detect aliasing effects and so determine the correct
row/column configuration. This changes the DRAM content, which breaks
use cases like soft reset and Linux's ramoops mechanism.

Fix this problem by saving and restoring the content of the DRAM cells
that is used for the test writes.

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm/mach-sunxi/dram_helpers.c | 35 ++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index cdf2750f1c..83dbe4ca98 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -5,8 +5,9 @@
  * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
  */
 
-#include <common.h>
+#include <config.h>
 #include <time.h>
+#include <vsprintf.h>
 #include <asm/barriers.h>
 #include <asm/io.h>
 #include <asm/arch/dram.h>
@@ -25,19 +26,39 @@ void mctl_await_completion(u32 *reg, u32 mask, u32 val)
 }
 
 /*
- * Test if memory at offset offset matches memory at begin of DRAM
+ * Test if memory at offset matches memory at a certain base
  *
  * Note: dsb() is not available on ARMv5 in Thumb mode
  */
 #ifndef CONFIG_MACH_SUNIV
-bool mctl_mem_matches(u32 offset)
+bool mctl_mem_matches_base(u32 offset, ulong base)
 {
+	u32 val_base;
+	u32 val_offset;
+	bool ret;
+
+	/* Save original values */
+	val_base = readl(base);
+	val_offset = readl(base + offset);
+
 	/* Try to write different values to RAM at two addresses */
-	writel(0, CFG_SYS_SDRAM_BASE);
-	writel(0xaa55aa55, (ulong)CFG_SYS_SDRAM_BASE + offset);
+	writel(0, base);
+	writel(0xaa55aa55, base + offset);
 	dsb();
 	/* Check if the same value is actually observed when reading back */
-	return readl(CFG_SYS_SDRAM_BASE) ==
-	       readl((ulong)CFG_SYS_SDRAM_BASE + offset);
+	ret = readl(base) == readl(base + offset);
+
+	/* Restore original values */
+	writel(val_base, base);
+	writel(val_offset, base + offset);
+	return ret;
+}
+
+/*
+ * Test if memory at offset matches memory at begin of DRAM
+ */
+bool mctl_mem_matches(u32 offset)
+{
+	return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
 }
 #endif
-- 
2.39.2

From 4d6a96ec60255a18cbf0f79985b306de20c0a9c5 Mon Sep 17 00:00:00 2001
From: Patrick Yavitz <pyavitz@xxxxx.com>
Date: Tue, 5 Mar 2024 20:38:57 -0500
Subject: [PATCH] mach-sunxi: dram_helpers: add delay to steady dram detection

Signed-off-by: Patrick Yavitz <pyavitz@xxxxx.com>
---
 arch/arm/mach-sunxi/dram_helpers.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index 83dbe4ca98..df7845502d 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -11,6 +11,7 @@
 #include <asm/barriers.h>
 #include <asm/io.h>
 #include <asm/arch/dram.h>
+#include <linux/delay.h>
 
 /*
  * Wait up to 1s for value to be set in given part of reg.
@@ -45,6 +46,7 @@ bool mctl_mem_matches_base(u32 offset, ulong base)
 	writel(0, base);
 	writel(0xaa55aa55, base + offset);
 	dsb();
+	udelay(150);
 	/* Check if the same value is actually observed when reading back */
 	ret = readl(base) == readl(base + offset);
 
-- 
2.39.2

