summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut@gmail.com>2011-11-08 23:18:24 +0000
committerStefano Babic <sbabic@denx.de>2011-11-11 11:36:58 +0100
commit3a4ce8335b89af37647d26f44d6eb476ce995fbb (patch)
tree6e6196b27e8b0e39a913a1d0e1be10104437c116
parent22fe68fbdc6baf4d55782fd9803e6133c49b533d (diff)
M28: Add memory detection into SPL
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>
-rw-r--r--board/denx/m28evk/Makefile7
-rw-r--r--board/denx/m28evk/m28evk.c18
-rw-r--r--board/denx/m28evk/mem_init.c27
-rw-r--r--include/configs/m28evk.h2
4 files changed, 50 insertions, 4 deletions
diff --git a/board/denx/m28evk/Makefile b/board/denx/m28evk/Makefile
index 47229e6ca9..b6f002fe36 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 118e2222a5..168ceeb6a5 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 066fe0d1a4..17d1f9b6a1 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 381b01e7a3..c8b0cf513e 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 */