[U-Boot] [PATCH v2 2/6] ddr: altera: Stratix10: Add multi-banks DRAM size check

Ley Foon Tan ley.foon.tan at intel.com
Thu Mar 21 17:24:01 UTC 2019


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 at intel.com>
Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
---
 drivers/ddr/altera/sdram_s10.c | 46 ++++++++++++++++++++++++++++++----
 1 file 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;
-- 
2.19.0



More information about the U-Boot mailing list