summaryrefslogtreecommitdiff
path: root/drivers/ddr
diff options
context:
space:
mode:
authorLey Foon Tan <ley.foon.tan@intel.com>2019-03-22 01:24:01 +0800
committerMarek Vasut <marex@denx.de>2019-04-17 22:20:17 +0200
commit6cd7134e7309a53f015a402e52e5863f29e366fd (patch)
tree826c653c4a9efe0076dca4f88fc5217ad8413afc /drivers/ddr
parentb6f7ee5d1f980ffa63e22749e2deae6caa57227e (diff)
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.c46
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;