[U-Boot] [PATCH 17/20] M28: Add memory detection into SPL

Marek Vasut
2011-11-09T09:18:24Z

This code allows the DDR DRAM size to be detected at runtime. The RAM size is
stored into two scratch registers, from which it is then fetched in U-Boot.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Detlev Zundel <dzu@denx.de>

---
board/denx/m28evk/Makefile | 7 ++++++-
board/denx/m28evk/m28evk.c | 18 ++++++++++++++++--
board/denx/m28evk/mem_init.c | 27 +++++++++++++++++++++++++++
include/configs/m28evk.h | 2 +-
4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/board/denx/m28evk/Makefile b/board/denx/m28evk/Makefile
index 47229e6..b6f002f 100644
--- a/board/denx/m28evk/Makefile
+++ b/board/denx/m28evk/Makefile
@@ -30,7 +30,7 @@ COBJS := m28evk.o
endif

ifdef CONFIG_SPL_BUILD
-COBJS := mem_init.o mmc_boot.o power_init.o
+COBJS := mem_init.o mmc_boot.o power_init.o memsize.o
endif

SRCS := $(COBJS:.o=.c)
@@ -41,6 +41,11 @@ $(LIB): $(obj).depend $(OBJS)

all: $(ALL)

+ifdef CONFIG_SPL_BUILD
+memsize.c:
+ ln -sf $(TOPDIR)/common/memsize.c $@
+endif
+
#########################################################################

# defines $(obj).depend target
diff --git a/board/denx/m28evk/m28evk.c b/board/denx/m28evk/m28evk.c
index 118e222..168ceeb 100644
--- a/board/denx/m28evk/m28evk.c
+++ b/board/denx/m28evk/m28evk.c
@@ -63,10 +63,24 @@ int board_init(void)
return 0;
}

+#define HW_DIGCTRL_SCRATCH0 0x8001c280
+#define HW_DIGCTRL_SCRATCH1 0x8001c290
int dram_init(void)
{
- /* dram_init must store complete ramsize in gd->ram_size */
- gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
+ uint32_t sz[2];
+
+ sz[0] = readl(HW_DIGCTRL_SCRATCH0);
+ sz[1] = readl(HW_DIGCTRL_SCRATCH1);
+
+ if (sz[0] != sz[1]) {
+ printf("MX28:\n"
+ "Error, the RAM size in HW_DIGCTRL_SCRATCH0 and\n"
+ "HW_DIGCTRL_SCRATCH1 is not the same. Please\n"
+ "verify these two registers contain valid RAM size!\n");
+ hang();
+ }
+
+ gd->ram_size = sz[0];
return 0;
}

diff --git a/board/denx/m28evk/mem_init.c b/board/denx/m28evk/mem_init.c
index 066fe0d..17d1f9b 100644
--- a/board/denx/m28evk/mem_init.c
+++ b/board/denx/m28evk/mem_init.c
@@ -165,6 +165,31 @@ void mx28_mem_setup_vddd(void)
&power_regs->hw_power_vdddctrl);
}

+#define HW_DIGCTRL_SCRATCH0 0x8001c280
+#define HW_DIGCTRL_SCRATCH1 0x8001c290
+void data_abort_memdetect_handler(void) __attribute__((naked));
+void data_abort_memdetect_handler(void)
+{
+ asm volatile("subs pc, r14, #4");
+}
+
+void mx28_mem_get_size(void)
+{
+ uint32_t sz, da;
+ uint32_t *vt = (uint32_t *)0x20;
+
+ /* Replace the DABT handler. */
+ da = vt[4];
+ vt[4] = (uint32_t)&data_abort_memdetect_handler;
+
+ sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
+ writel(sz, HW_DIGCTRL_SCRATCH0);
+ writel(sz, HW_DIGCTRL_SCRATCH1);
+
+ /* Restore the old DABT handler. */
+ vt[4] = da;
+}
+
void mx28_mem_init(void)
{
struct mx28_clkctrl_regs *clkctrl_regs =
@@ -210,4 +235,6 @@ void mx28_mem_init(void)
early_delay(10000);

mx28_mem_setup_cpu_and_hbus();
+
+ mx28_mem_get_size();
}
diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h
index 381b01e..c8b0cf5 100644
--- a/include/configs/m28evk.h
+++ b/include/configs/m28evk.h
@@ -81,7 +81,7 @@
*/
#define CONFIG_NR_DRAM_BANKS 1 /* 2 banks of DRAM */
#define PHYS_SDRAM_1 0x40000000 /* Base address */
-#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB */
+#define PHYS_SDRAM_1_SIZE 0x40000000 /* Max 1 GB RAM */
#define CONFIG_STACKSIZE 0x00010000 /* 128 KB stack */
#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
--
1.7.7.1