From: Marek Vasut Date: Thu, 5 Sep 2024 15:35:00 +0000 (+0200) Subject: ARM: imx: Enable MMU and dcache very early on i.MX8M X-Git-Url: http://git.dujemihanovic.xyz/html/%7B%7B%20%28.OutputFormats.Get?a=commitdiff_plain;h=ac9153c74f30c13ce773367166bcb44aa847ff67;p=u-boot.git ARM: imx: Enable MMU and dcache very early on i.MX8M Enable MMU and caches very early on in the boot process on i.MX8M in U-Boot proper. This allows board_init_f to run with icache and dcache enabled, which saves some 700 milliseconds of boot time on i.MX8M Plus based device. The 'bootstage report' output is below: Before: ``` Timer summary in microseconds (8 records): Mark Elapsed Stage 0 0 reset 961,363 961,363 board_init_f 1,818,874 857,511 board_init_r 1,921,474 102,600 eth_common_init 2,013,702 92,228 eth_initialize 2,015,238 1,536 main_loop Accumulated time: 32,775 dm_r 289,165 dm_f ``` After: ``` Timer summary in microseconds (8 records): Mark Elapsed Stage 0 0 reset 989,466 989,466 board_init_f 1,179,100 189,634 board_init_r 1,281,456 102,356 eth_common_init 1,373,857 92,401 eth_initialize 1,375,396 1,539 main_loop Accumulated time: 12,630 dm_f 32,635 dm_r ``` Signed-off-by: Marek Vasut Reviewed-by: Peng Fan Reviewed-by: Fabio Estevam --- diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index f30178ae21..986687e9ce 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -32,6 +32,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -206,6 +207,14 @@ void enable_caches(void) int entry = imx8m_find_dram_entry_in_mem_map(); u64 attrs = imx8m_mem_map[entry].attrs; + /* Deactivate the data cache, possibly enabled in arch_cpu_init() */ + dcache_disable(); + /* + * Force the call of setup_all_pgtables() in mmu_setup() by clearing tlb_fillptr + * to update the TLB location udpated in board_f.c::reserve_mmu + */ + gd->arch.tlb_fillptr = 0; + while (i < CONFIG_NR_DRAM_BANKS && entry < ARRAY_SIZE(imx8m_mem_map)) { if (gd->bd->bi_dram[i].start == 0) @@ -587,12 +596,50 @@ static void imx8m_setup_csu_tzasc(void) } } +/* + * Place early TLB into the .data section so that it will not + * get cleared, use 16 kiB alignment. + */ +#define EARLY_TLB_SIZE SZ_64K +u8 early_tlb[EARLY_TLB_SIZE] __section(".data") __aligned(0x4000); + +/* + * Initialize the MMU and activate cache in U-Boot pre-reloc stage + * MMU/TLB is updated in enable_caches() for U-Boot after relocation + */ +static void early_enable_caches(void) +{ + phys_size_t sdram_size; + int entry, ret; + + if (IS_ENABLED(CONFIG_SPL_BUILD)) + return; + + if (CONFIG_IS_ENABLED(SYS_ICACHE_OFF) || CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) + return; + + /* Use maximum available DRAM size in first bank. */ + ret = board_phys_sdram_size(&sdram_size); + if (ret) + return; + + entry = imx8m_find_dram_entry_in_mem_map(); + imx8m_mem_map[entry].size = max(sdram_size, (phys_size_t)0xc0000000); + + gd->arch.tlb_size = EARLY_TLB_SIZE; + gd->arch.tlb_addr = (unsigned long)&early_tlb; + + /* Enable MMU (default configuration) */ + dcache_enable(); +} + int arch_cpu_init(void) { struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) icache_enable(); + early_enable_caches(); #endif /*