diff options
author | Jon Nettleton <jon@solid-run.com> | 2018-06-07 16:17:37 +0300 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2018-06-18 16:50:55 +0200 |
commit | 51f957adf77575075b69a95a37f118653532892c (patch) | |
tree | bb89e127ee83d3d776642ca72485dc30f2571644 | |
parent | 73708200f05501c5d9b7cb6d0a29b0839120b3c0 (diff) | |
download | u-boot-51f957adf77575075b69a95a37f118653532892c.tar.gz u-boot-51f957adf77575075b69a95a37f118653532892c.tar.xz u-boot-51f957adf77575075b69a95a37f118653532892c.zip |
mx6cuboxi: fix 4GB ddr memory detection
The soms with 4GB ddr have a rowaddr of 16 not 15, this allows
the detection mechanism to properly identify them as 4GB.
However these soms can be populated with whatever amount of
memory the customer requests therefor we need a ram stride test.
We can not use the get_ram_size() function because not all 4GB's
of DDR is addressable on a 32-bit architecture. Therefore instead
we use a memory stride of 128MB's and look for the address that
the memory wraps. This function is used for all som types to
catch most memory configurations.
This is a revised version of Rabeeh Khoury's original code.
Signed-off-by: Jon Nettleton <jon@solid-run.com>
Signed-off-by: Rabeeh Khoury <rabeeh@solid-run.com>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
-rw-r--r-- | board/solidrun/mx6cuboxi/mx6cuboxi.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index 1567cf0c91..38d89f0130 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -64,9 +64,51 @@ enum board_type { UNKNOWN = 0x03, }; +#define MEM_STRIDE 0x4000000 +static u32 get_ram_size_stride_test(u32 *base, u32 maxsize) +{ + volatile u32 *addr; + u32 save[64]; + u32 cnt; + u32 size; + int i = 0; + + /* First save the data */ + for (cnt = 0; cnt < maxsize; cnt += MEM_STRIDE) { + addr = (volatile u32 *)((u32)base + cnt); /* pointer arith! */ + sync (); + save[i++] = *addr; + sync (); + } + + /* First write a signature */ + * (volatile u32 *)base = 0x12345678; + for (size = MEM_STRIDE; size < maxsize; size += MEM_STRIDE) { + * (volatile u32 *)((u32)base + size) = size; + sync (); + if (* (volatile u32 *)((u32)base) == size) { /* We reached the overlapping address */ + break; + } + } + + /* Restore the data */ + for (cnt = (maxsize - MEM_STRIDE); i > 0; cnt -= MEM_STRIDE) { + addr = (volatile u32 *)((u32)base + cnt); /* pointer arith! */ + sync (); + *addr = save[i--]; + sync (); + } + + return (size); +} + int dram_init(void) { - gd->ram_size = imx_ddr_size(); + u32 max_size = imx_ddr_size(); + + gd->ram_size = get_ram_size_stride_test((u32 *) CONFIG_SYS_SDRAM_BASE, + (u32)max_size); + return 0; } @@ -626,7 +668,7 @@ static struct mx6_ddr3_cfg mem_ddr_4g = { .density = 4, .width = 16, .banks = 8, - .rowaddr = 15, + .rowaddr = 16, .coladdr = 10, .pagesz = 2, .trcd = 1375, |