diff options
author | Ley Foon Tan <ley.foon.tan@intel.com> | 2019-03-22 01:24:01 +0800 |
---|---|---|
committer | Marek Vasut <marex@denx.de> | 2019-04-17 22:20:17 +0200 |
commit | 6cd7134e7309a53f015a402e52e5863f29e366fd (patch) | |
tree | 826c653c4a9efe0076dca4f88fc5217ad8413afc /drivers/ddr | |
parent | b6f7ee5d1f980ffa63e22749e2deae6caa57227e (diff) | |
download | u-boot-6cd7134e7309a53f015a402e52e5863f29e366fd.tar.gz u-boot-6cd7134e7309a53f015a402e52e5863f29e366fd.tar.bz2 u-boot-6cd7134e7309a53f015a402e52e5863f29e366fd.zip |
ddr: altera: Stratix10: Add multi-banks DRAM size check
Stratix 10 maps dram from 0 to 128GB. There is a 2GB hole
in the memory for peripherals and other IO from 2GB to 4GB.
However the dram controller ignores upper address bits for
smaller dram configurations. Example: a 4GB dram
maps to multiple locations, every 4GB on the address.
Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
Diffstat (limited to 'drivers/ddr')
-rw-r--r-- | drivers/ddr/altera/sdram_s10.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/ddr/altera/sdram_s10.c b/drivers/ddr/altera/sdram_s10.c index 033ccca437..462c8feaef 100644 --- a/drivers/ddr/altera/sdram_s10.c +++ b/drivers/ddr/altera/sdram_s10.c @@ -7,12 +7,14 @@ #include <common.h> #include <errno.h> #include <div64.h> +#include <fdtdec.h> #include <asm/io.h> #include <wait_bit.h> #include <asm/arch/firewall_s10.h> #include <asm/arch/sdram_s10.h> #include <asm/arch/system_manager.h> #include <asm/arch/reset_manager.h> +#include <linux/sizes.h> DECLARE_GLOBAL_DATA_PTR; @@ -134,14 +136,35 @@ static int poll_hmc_clock_status(void) SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false); } -static void sdram_size_check(void) +static void sdram_size_check(bd_t *bd) { + phys_size_t total_ram_check = 0; + phys_size_t ram_check = 0; + phys_addr_t start = 0; + int bank; + /* Sanity check ensure correct SDRAM size specified */ debug("DDR: Running SDRAM size sanity check\n"); - if (get_ram_size(0, gd->ram_size) != gd->ram_size) { + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + start = bd->bi_dram[bank].start; + while (ram_check < bd->bi_dram[bank].size) { + ram_check += get_ram_size((void *)(start + ram_check), + (phys_size_t)SZ_1G); + } + total_ram_check += ram_check; + ram_check = 0; + } + + /* If the ram_size is 2GB smaller, we can assume the IO space is + * not mapped in. gd->ram_size is the actual size of the dram + * not the accessible size. + */ + if (total_ram_check != gd->ram_size) { puts("DDR: SDRAM size check failed!\n"); hang(); } + debug("DDR: SDRAM size check passed!\n"); } @@ -155,6 +178,8 @@ int sdram_mmr_init_full(unsigned int unused) u32 update_value, io48_value, ddrioctl; u32 i; int ret; + phys_size_t hw_size; + bd_t bd = {0}; /* Enable access to DDR from CPU master */ clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_DDRREG), @@ -346,9 +371,20 @@ int sdram_mmr_init_full(unsigned int unused) unsigned long long size = sdram_calculate_size(); /* If the size is invalid, use default Config size */ if (size <= 0) - gd->ram_size = PHYS_SDRAM_1_SIZE; + hw_size = PHYS_SDRAM_1_SIZE; else - gd->ram_size = size; + hw_size = size; + + /* Get bank configuration from devicetree */ + ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL, + (phys_size_t *)&gd->ram_size, &bd); + if (ret) { + puts("DDR: Failed to decode memory node\n"); + return -1; + } + + if (gd->ram_size != hw_size) + printf("DDR: Warning: DRAM size from device tree mismatch with hardware.\n"); printf("DDR: %lld MiB\n", gd->ram_size >> 20); @@ -374,7 +410,7 @@ int sdram_mmr_init_full(unsigned int unused) DDR_HMC_ECCCTL2_AWB_EN_SET_MSK)); } - sdram_size_check(); + sdram_size_check(&bd); debug("DDR: HMC init success\n"); return 0; |