
Some Allwinner SoCs can use 3GiB DRAM (part of 4GiB or larger module).
As the common get_ram_size function cannot detect non-pow-of-2 memory, add special detect code into the DRAM size code in main U-Boot.
Signed-off-by: Icenowy Zheng icenowy@aosc.io --- board/sunxi/board.c | 23 +++++++++++++++++++++++ include/configs/sunxi-common.h | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 8891961dcc..8d707cbac2 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -256,7 +256,30 @@ int board_init(void)
int dram_init(void) { +#if PHYS_SDRAM_0_SIZE == (SZ_2G + SZ_1G) + /* + * get_ram_size() doesn't support non-pow-of-2 sizes, so the detection + * of 3GiB DRAM is implemented here. + * It just checks whether the DRAM is bigger than 2GiB, as the DRAM + * module is usually 4GiB in this case (and 1GiB is not accessible). + */ + u32 save_0, save_2g; + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, SZ_2G); + if (gd->ram_size == SZ_2G) { + save_0 = readl(PHYS_SDRAM_0); + save_2g = readl(PHYS_SDRAM_0 + SZ_2G); + writel(0, PHYS_SDRAM_0); + writel(0xaa55aa55, PHYS_SDRAM_0 + SZ_2G); + dsb(); + if (readl(PHYS_SDRAM_0) != readl(PHYS_SDRAM_0 + SZ_2G)) { + gd->ram_size = SZ_2G + SZ_1G; + writel(save_2g, PHYS_SDRAM_0 + SZ_2G); + } + writel(save_0, PHYS_SDRAM_0); + } +#else gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); +#endif
return 0; } diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 9b3944ad13..177647e009 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -111,7 +111,7 @@
#define CONFIG_NR_DRAM_BANKS 1 #define PHYS_SDRAM_0 CONFIG_SYS_SDRAM_BASE -#define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */ +#define PHYS_SDRAM_0_SIZE CONFIG_SUNXI_DRAM_MAX_SIZE
#ifdef CONFIG_AHCI #define CONFIG_SCSI_AHCI_PLAT