[PATCH 4/5] rockchip: sdram: refactor bi_dram logic into separate function

Aaron Griffith aargri at gmail.com
Mon Dec 29 01:05:26 CET 2025


This part of rockchip_dram_init_banksize decides what to do with the
memory information it reads out of ATAGS. Right now, this is used to
add holes for reserved memory from mem_map and for BL31.

This change factors it out into a separate function. This function is
marked weak, so that a board or SoC can implement its own logic for
reserved memory. For example, the RK3506 has no BL31, and should not
reserve memory for it.

This new function body is a copy of the existing code with only two
small changes:

 * Replace index j with *next_bank in function body.

 * Increment *next_bank at the end of the function, rather than in the
   for-loop that calls this function. This makes the meaning of the
   *next_bank argument more consistent: it is always incremented when
   a bank is added.

Signed-off-by: Aaron Griffith <aargri at gmail.com>
---
 arch/arm/mach-rockchip/sdram.c | 234 ++++++++++++++++++++++-------------------
 1 file changed, 127 insertions(+), 107 deletions(-)

diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c
index 98c02570dc4e4a8315c25a5caad5d568db10c5d8..287073c0e50839cc9366baacbc47512dbe2b4476 100644
--- a/arch/arm/mach-rockchip/sdram.c
+++ b/arch/arm/mach-rockchip/sdram.c
@@ -105,6 +105,129 @@ static u32 js_hash(const void *buf, u32 len)
 	return hash;
 }
 
+/*
+ * Populate gd->bd->bi_dram[*next_bank] (and possibly banks after) with
+ * the memory region received from the TPL starting at start_addr with
+ * given size.
+ *
+ * Increment *next_bank by the number of used banks.
+ */
+__weak int rockchip_dram_init_banksize_add_bank(u8 *next_bank, phys_addr_t start_addr,
+						phys_size_t size)
+{
+	struct mm_region *tmp_mem_map = mem_map;
+	phys_addr_t end_addr;
+
+	/*
+	 * BL31 (TF-A) reserves the first 2MB but DDR_MEM tag may not
+	 * have it, so force this space as reserved.
+	 */
+	if (start_addr < CFG_SYS_SDRAM_BASE + SZ_2M) {
+		size -= CFG_SYS_SDRAM_BASE + SZ_2M - start_addr;
+		start_addr = CFG_SYS_SDRAM_BASE + SZ_2M;
+	}
+
+	/*
+	 * Put holes for reserved memory areas from mem_map.
+	 *
+	 * Only check for at most one overlap with one reserved memory
+	 * area.
+	 */
+	while (tmp_mem_map->size) {
+		const phys_addr_t rsrv_start = tmp_mem_map->phys;
+		const phys_size_t rsrv_size = tmp_mem_map->size;
+		const phys_addr_t rsrv_end = rsrv_start + rsrv_size;
+
+		/*
+		 * DRAM memories are expected by Arm to be marked as
+		 * Normal Write-back cacheable, Inner shareable[1], so
+		 * let's filter on that to put holes in non-DRAM areas.
+		 *
+		 * [1] https://developer.arm.com/documentation/102376/0200/Cacheability-and-shareability-attributes
+		 */
+		const u64 dram_attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			PTE_BLOCK_INNER_SHARE;
+		/*
+		 * (AttrIndx | SH) in Lower Attributes of Block
+		 * Descriptor[2].
+		 * [2] https://developer.arm.com/documentation/102376/0200/Describing-memory-in-AArch64
+		 */
+		const u64 attrs_mask = PMD_ATTRINDX_MASK | GENMASK(9, 8);
+
+		if ((tmp_mem_map->attrs & attrs_mask) == dram_attrs) {
+			tmp_mem_map++;
+			continue;
+		}
+
+		/*
+		 * If the start of the DDR_MEM tag is in a reserved
+		 * memory area, move start address and resize.
+		 */
+		if (start_addr >= rsrv_start && start_addr < rsrv_end) {
+			if (rsrv_end - start_addr > size) {
+				debug("Would be negative memory size\n");
+				return -EINVAL;
+			}
+
+			size -= rsrv_end - (start_addr - CFG_SYS_SDRAM_BASE);
+			start_addr = rsrv_end;
+			break;
+		}
+
+		if (start_addr < rsrv_start) {
+			end_addr = start_addr + size;
+
+			if (end_addr <= rsrv_start) {
+				tmp_mem_map++;
+				continue;
+			}
+
+			/*
+			 * If the memory area overlaps a reserved memory
+			 * area with start address outside of reserved
+			 * memory area and...
+			 *
+			 * ... ends in the middle of reserved memory
+			 * area, resize.
+			 */
+			if (end_addr <= rsrv_end) {
+				size = rsrv_start - start_addr;
+				break;
+			}
+
+			/*
+			 * ... ends after the reserved memory area,
+			 * split the region in two, one for before the
+			 * reserved memory area and one for after.
+			 */
+			gd->bd->bi_dram[*next_bank].start = start_addr;
+			gd->bd->bi_dram[*next_bank].size = rsrv_start - start_addr;
+
+			*next_bank += 1;
+
+			size = end_addr - rsrv_end;
+			start_addr = rsrv_end;
+
+			break;
+		}
+
+		tmp_mem_map++;
+	}
+
+	if (*next_bank > CONFIG_NR_DRAM_BANKS) {
+		debug("Too many banks, max allowed (%d)\n",
+		      CONFIG_NR_DRAM_BANKS);
+		return -ENOMEM;
+	}
+
+	gd->bd->bi_dram[*next_bank].start = start_addr;
+	gd->bd->bi_dram[*next_bank].size = size;
+
+	*next_bank += 1;
+
+	return 0;
+}
+
 static int rockchip_dram_init_banksize(void)
 {
 	const struct tag_header *tag_h = NULL;
@@ -168,116 +291,13 @@ static int rockchip_dram_init_banksize(void)
 	 * Rockchip guaranteed DDR_MEM is ordered so no need to worry about
 	 * bi_dram order.
 	 */
-	for (i = 0, j = 0; i < ddr_info->count; i++, j++) {
+	for (i = 0, j = 0; i < ddr_info->count; i++) {
 		phys_size_t size = ddr_info->bank[(i + ddr_info->count)];
 		phys_addr_t start_addr = ddr_info->bank[i];
-		struct mm_region *tmp_mem_map = mem_map;
-		phys_addr_t end_addr;
-
-		/*
-		 * BL31 (TF-A) reserves the first 2MB but DDR_MEM tag may not
-		 * have it, so force this space as reserved.
-		 */
-		if (start_addr < CFG_SYS_SDRAM_BASE + SZ_2M) {
-			size -= CFG_SYS_SDRAM_BASE + SZ_2M - start_addr;
-			start_addr = CFG_SYS_SDRAM_BASE + SZ_2M;
-		}
-
-		/*
-		 * Put holes for reserved memory areas from mem_map.
-		 *
-		 * Only check for at most one overlap with one reserved memory
-		 * area.
-		 */
-		while (tmp_mem_map->size) {
-			const phys_addr_t rsrv_start = tmp_mem_map->phys;
-			const phys_size_t rsrv_size = tmp_mem_map->size;
-			const phys_addr_t rsrv_end = rsrv_start + rsrv_size;
-
-			/*
-			 * DRAM memories are expected by Arm to be marked as
-			 * Normal Write-back cacheable, Inner shareable[1], so
-			 * let's filter on that to put holes in non-DRAM areas.
-			 *
-			 * [1] https://developer.arm.com/documentation/102376/0200/Cacheability-and-shareability-attributes
-			 */
-			const u64 dram_attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-				PTE_BLOCK_INNER_SHARE;
-			/*
-			 * (AttrIndx | SH) in Lower Attributes of Block
-			 * Descriptor[2].
-			 * [2] https://developer.arm.com/documentation/102376/0200/Describing-memory-in-AArch64
-			 */
-			const u64 attrs_mask = PMD_ATTRINDX_MASK | GENMASK(9, 8);
-
-			if ((tmp_mem_map->attrs & attrs_mask) == dram_attrs) {
-				tmp_mem_map++;
-				continue;
-			}
-
-			/*
-			 * If the start of the DDR_MEM tag is in a reserved
-			 * memory area, move start address and resize.
-			 */
-			if (start_addr >= rsrv_start && start_addr < rsrv_end) {
-				if (rsrv_end - start_addr > size) {
-					debug("Would be negative memory size\n");
-					return -EINVAL;
-				}
-
-				size -= rsrv_end - (start_addr - CFG_SYS_SDRAM_BASE);
-				start_addr = rsrv_end;
-				break;
-			}
-
-			if (start_addr < rsrv_start) {
-				end_addr = start_addr + size;
-
-				if (end_addr <= rsrv_start) {
-					tmp_mem_map++;
-					continue;
-				}
-
-				/*
-				 * If the memory area overlaps a reserved memory
-				 * area with start address outside of reserved
-				 * memory area and...
-				 *
-				 * ... ends in the middle of reserved memory
-				 * area, resize.
-				 */
-				if (end_addr <= rsrv_end) {
-					size = rsrv_start - start_addr;
-					break;
-				}
-
-				/*
-				 * ... ends after the reserved memory area,
-				 * split the region in two, one for before the
-				 * reserved memory area and one for after.
-				 */
-				gd->bd->bi_dram[j].start = start_addr;
-				gd->bd->bi_dram[j].size = rsrv_start - start_addr;
-
-				j++;
-
-				size = end_addr - rsrv_end;
-				start_addr = rsrv_end;
-
-				break;
-			}
-
-			tmp_mem_map++;
-		}
-
-		if (j > CONFIG_NR_DRAM_BANKS) {
-			debug("Too many banks, max allowed (%d)\n",
-			      CONFIG_NR_DRAM_BANKS);
-			return -ENOMEM;
-		}
+		int ret = rockchip_dram_init_banksize_add_bank(&j, start_addr, size);
 
-		gd->bd->bi_dram[j].start = start_addr;
-		gd->bd->bi_dram[j].size = size;
+		if (ret)
+			return ret;
 	}
 
 	return 0;

-- 
2.47.3



More information about the U-Boot mailing list