sunxi: Fill memory before comparing it when doing dram init on sun6i
authorHans de Goede <hdegoede@redhat.com>
Mon, 8 Dec 2014 12:58:53 +0000 (13:58 +0100)
committerHans de Goede <hdegoede@redhat.com>
Wed, 14 Jan 2015 13:56:37 +0000 (14:56 +0100)
The sun8i boot0 code fills the DRAM with a "random" pattern before comparing
it at different offsets to do columns, etc. detection. The sun6i boot0 code
does not do it, instead relying on the memory contents being random enough
to begin with for the memcmp to properly detect the wrap-around address, iow
it is working purely by chance. Since our sun6i dram code was modelled after
the boot0 code it contained the same issue.

This commit fixes this by filling the memory with a unique, distinct pattern.

The new mctl_mem_fill function this introduces is added as an inline helper
in dram.h, so that it can be shared with the sun8i dram code.

While at it move mctl_mem_matches to dram.h for re-use in sun8i too.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
arch/arm/cpu/armv7/sunxi/dram_sun6i.c
arch/arm/include/asm/arch-sunxi/dram.h

index 05f8e7638f7d8655e978c64794ecad994b7f9239..31b7dd50a97163767eea669717ae4828f37e452c 100644 (file)
@@ -326,20 +326,6 @@ static void mctl_port_cfg(void)
        writel(0x00000307, &mctl_com->mbagcr[5]);
 }
 
-static bool mctl_mem_matches(u32 offset)
-{
-       const int match_count = 64;
-       int i, matches = 0;
-
-       for (i = 0; i < match_count; i++) {
-               if (readl(CONFIG_SYS_SDRAM_BASE + i * 4) ==
-                   readl(CONFIG_SYS_SDRAM_BASE + offset + i * 4))
-                       matches++;
-       }
-
-       return matches == match_count;
-}
-
 unsigned long sunxi_dram_init(void)
 {
        struct sunxi_mctl_com_reg * const mctl_com =
@@ -391,6 +377,7 @@ unsigned long sunxi_dram_init(void)
                    MCTL_CR_BANK(1) | MCTL_CR_RANK(1));
 
        /* Detect and set page size */
+       mctl_mem_fill();
        for (columns = 7; columns < 20; columns++) {
                if (mctl_mem_matches(1 << columns))
                        break;
index 18924f5c9cb4473a1d5ef967172ceb7270f05cb7..0bf718c3a4bbd6ee491727d72bafc8ce2dcfba4d 100644 (file)
@@ -22,6 +22,8 @@
 #include <asm/arch/dram_sun4i.h>
 #endif
 
+#define MCTL_MEM_FILL_MATCH_COUNT 64
+
 unsigned long sunxi_dram_init(void);
 
 /*
@@ -37,4 +39,31 @@ static inline void mctl_await_completion(u32 *reg, u32 mask, u32 val)
        }
 }
 
+/*
+ * Fill beginning of DRAM with "random" data for mctl_mem_matches()
+ */
+static inline void mctl_mem_fill(void)
+{
+       int i;
+
+       for (i = 0; i < MCTL_MEM_FILL_MATCH_COUNT; i++)
+               writel(0xaa55aa55 + i, CONFIG_SYS_SDRAM_BASE + i * 4);
+}
+
+/*
+ * Test if memory at offset offset matches memory at begin of DRAM
+ */
+static inline bool mctl_mem_matches(u32 offset)
+{
+       int i, matches = 0;
+
+       for (i = 0; i < MCTL_MEM_FILL_MATCH_COUNT; i++) {
+               if (readl(CONFIG_SYS_SDRAM_BASE + i * 4) ==
+                   readl(CONFIG_SYS_SDRAM_BASE + offset + i * 4))
+                       matches++;
+       }
+
+       return matches == MCTL_MEM_FILL_MATCH_COUNT;
+}
+
 #endif /* _SUNXI_DRAM_H */