[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