aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-sunxi
diff options
context:
space:
mode:
authorAndrey Skvortsov <andrej.skvortzov@gmail.com>2023-12-28 00:28:43 +0300
committerAndre Przywara <andre.przywara@arm.com>2024-03-05 01:16:56 +0000
commitf1e6a718ebab0682d80601db404e8d842767becf (patch)
tree1f571eb2fe497216da69d4213d77a497c6cc300c /arch/arm/mach-sunxi
parent978808d2b9f46db5e9782090ed3c168e6d4183e6 (diff)
downloadu-boot-f1e6a718ebab0682d80601db404e8d842767becf.zip
u-boot-f1e6a718ebab0682d80601db404e8d842767becf.tar.gz
u-boot-f1e6a718ebab0682d80601db404e8d842767becf.tar.bz2
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>
Diffstat (limited to 'arch/arm/mach-sunxi')
-rw-r--r--arch/arm/mach-sunxi/dram_helpers.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index 110825b..83dbe4c 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -33,13 +33,25 @@ void mctl_await_completion(u32 *reg, u32 mask, u32 val)
#ifndef CONFIG_MACH_SUNIV
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, base);
writel(0xaa55aa55, base + offset);
dsb();
/* Check if the same value is actually observed when reading back */
- return readl(base) ==
- readl(base + offset);
+ ret = readl(base) == readl(base + offset);
+
+ /* Restore original values */
+ writel(val_base, base);
+ writel(val_offset, base + offset);
+ return ret;
}
/*