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 <[email protected]> --- 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

