From: Anshul Dalal Date: Wed, 18 Jun 2025 12:42:09 +0000 (+0530) Subject: mach-k3: add dynamic mmu fixups for SPL stage X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b77066d73261;p=thirdparty%2Fu-boot.git mach-k3: add dynamic mmu fixups for SPL stage On platforms with spl splash support i.e CONFIG_VIDEO=y, the top of DDR is reserved for the framebuffer. The size for the framebuffer is computed at runtime by video_reserve. During the MMU configuration an entry corresponding to the framebuffer should be dynamically created to properly map the required space for the framebuffer. Therefore this patch adds k3_spl_mem_map_init which adds the required MMU entry by querying the gd after the framebuffer size has been computed in spl_reserve_video_from_ram_top. For non VIDEO=y platforms, the added k3_spl_mem_map_init function gets optimized out of the final binary so overall, the spl size is not impacted[1]. [1]: Tested on clang 19.1.7 and gcc 15.1.1 Signed-off-by: Anshul Dalal --- diff --git a/arch/arm/mach-k3/arm64/arm64-mmu.c b/arch/arm/mach-k3/arm64/arm64-mmu.c index 2fdd106fec4..74c855852e9 100644 --- a/arch/arm/mach-k3/arm64/arm64-mmu.c +++ b/arch/arm/mach-k3/arm64/arm64-mmu.c @@ -50,6 +50,10 @@ struct mm_region k3_mem_map[K3_MMU_REGIONS_COUNT] = { .size = SZ_128M, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE + }, { + /* Framebuffer reserved, size set at runtime */ + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE }, { /* List terminator */ 0, @@ -58,6 +62,46 @@ struct mm_region k3_mem_map[K3_MMU_REGIONS_COUNT] = { struct mm_region *mem_map = k3_mem_map; +int k3_spl_mem_map_init(void) +{ + unsigned int i; + int k3_map_idx = -EINVAL; + + for (i = 0; i < K3_MMU_REGIONS_COUNT; i++) { + if (k3_mem_map[i].virt == 0 && k3_mem_map[i].phys == 0 && + k3_mem_map[i].size == 0) { + k3_map_idx = i; + break; + } + } + + if (k3_map_idx == -EINVAL) { + pr_err("%s: Failed to find fixup region in MMU memory map\n", + __func__); + return -EINVAL; + } + + if (k3_map_idx >= K3_MMU_REGIONS_COUNT - 1) { + pr_err("%s: Not enough space in MMU map for the added entry\n", + __func__); + return -ENOMEM; + } + + if (CONFIG_IS_ENABLED(VIDEO)) { + k3_mem_map[k3_map_idx].virt = gd_video_bottom(); + k3_mem_map[k3_map_idx].phys = gd_video_bottom(); + k3_mem_map[k3_map_idx].size = + gd_video_top() - gd_video_bottom(); + k3_mem_map[k3_map_idx].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + k3_map_idx++; + } + + k3_mem_map[k3_map_idx] = (const struct mm_region){ 0 }; + + return 0; +} + static int dt_reserved_cmp(const void *a, const void *b) { const struct fdt_resource *val_a = a, *val_b = b; diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index f8c53b286eb..723076ee874 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -15,6 +15,7 @@ #include #include #include "common.h" +#include "mach/k3-ddr.h" #include #include #include @@ -268,9 +269,6 @@ void spl_enable_cache(void) dram_init(); - /* reserve TLB table */ - gd->arch.tlb_size = PGTABLE_SIZE; - gd->ram_top += get_effective_memsize(); gd->relocaddr = gd->ram_top; @@ -278,6 +276,15 @@ void spl_enable_cache(void) if (ret) panic("Failed to reserve framebuffer memory (%d)\n", ret); + if (IS_ENABLED(CONFIG_ARM64)) { + ret = k3_spl_mem_map_init(); + if (ret) + panic("Failed to perform MMU fixups: %d\n", ret); + } + + /* reserve TLB table */ + gd->arch.tlb_size = PGTABLE_SIZE; + gd->arch.tlb_addr = gd->relocaddr - gd->arch.tlb_size; gd->arch.tlb_addr &= ~(0x10000 - 1); debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr, diff --git a/arch/arm/mach-k3/include/mach/k3-ddr.h b/arch/arm/mach-k3/include/mach/k3-ddr.h index 0b164ebf5e6..375a1a85945 100644 --- a/arch/arm/mach-k3/include/mach/k3-ddr.h +++ b/arch/arm/mach-k3/include/mach/k3-ddr.h @@ -17,6 +17,9 @@ int dram_init_banksize(void); void fixup_ddr_driver_for_ecc(struct spl_image_info *spl_image); void fixup_memory_node(struct spl_image_info *spl_image); +/* Performs MMU memory map fixups at SPL stage */ +int k3_spl_mem_map_init(void); + /* * Modifies the MMU memory map based on DDR size and reserved-memory * nodes in DT