M28: Add memory detection into SPL
authorMarek Vasut <marek.vasut@gmail.com>
Tue, 8 Nov 2011 23:18:24 +0000 (23:18 +0000)
committerStefano Babic <sbabic@denx.de>
Fri, 11 Nov 2011 10:36:58 +0000 (11:36 +0100)
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
board/denx/m28evk/m28evk.c
board/denx/m28evk/mem_init.c
include/configs/m28evk.h

index 47229e6..b6f002f 100644 (file)
@@ -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
index 118e222..168ceeb 100644 (file)
@@ -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;
 }
 
index 066fe0d..17d1f9b 100644 (file)
@@ -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();
 }
index 381b01e..c8b0cf5 100644 (file)
@@ -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 */