[PATCH] 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 marex@denx.de --- Cc: "NXP i.MX U-Boot Team" uboot-imx@nxp.com Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Tom Rini trini@konsulko.com Cc: u-boot@lists.denx.de --- arch/arm/mach-imx/imx8m/soc.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index be38ca52885..7ac26d501ac 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -206,6 +206,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 +595,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
/*

Hi Marek,
On Tue, Aug 27, 2024 at 5:04 PM Marek Vasut marex@denx.de wrote:
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.
Nice improvement!
Reviewed-by: Fabio Estevam festevam@gmail.com

Hi Marek,
On Tue, Aug 27, 2024 at 5:04 PM Marek Vasut marex@denx.de wrote:
+/*
- 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);
This causes a CI failure:
https://source.denx.de/u-boot/custodians/u-boot-imx/-/jobs/895190/raw
aarch64: + imx8mp_beacon +arch/arm/mach-imx/imx8m/soc.c:602:24: error: 'SZ_64K' undeclared here (not in a function) + 602 | #define EARLY_TLB_SIZE SZ_64K + | ^~~~~~ +arch/arm/mach-imx/imx8m/soc.c:603:14: note: in expansion of macro 'EARLY_TLB_SIZE' + 603 | u8 early_tlb[EARLY_TLB_SIZE] __section(".data") __aligned(0x4000); + | ^~~~~~~~~~~~~~ +make[3]: *** [scripts/Makefile.build:257: arch/arm/mach-imx/imx8m/soc.o] Error 1 +make[2]: *** [scripts/Makefile.build:397: arch/arm/mach-imx/imx8m] Error 2 +make[1]: *** [Makefile:1897: arch/arm/mach-imx] Error 2 +make: *** [Makefile:177: sub-make] Error 2
Please take a look.

On 8/31/24 1:16 PM, Fabio Estevam wrote:
Hi Marek,
On Tue, Aug 27, 2024 at 5:04 PM Marek Vasut marex@denx.de wrote:
+/*
- 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);
This causes a CI failure:
https://source.denx.de/u-boot/custodians/u-boot-imx/-/jobs/895190/raw
aarch64: + imx8mp_beacon
+arch/arm/mach-imx/imx8m/soc.c:602:24: error: 'SZ_64K' undeclared here (not in a function)
- 602 | #define EARLY_TLB_SIZE SZ_64K
| ^~~~~~
+arch/arm/mach-imx/imx8m/soc.c:603:14: note: in expansion of macro 'EARLY_TLB_SIZE'
- 603 | u8 early_tlb[EARLY_TLB_SIZE] __section(".data") __aligned(0x4000);
| ^~~~~~~~~~~~~~
+make[3]: *** [scripts/Makefile.build:257: arch/arm/mach-imx/imx8m/soc.o] Error 1 +make[2]: *** [scripts/Makefile.build:397: arch/arm/mach-imx/imx8m] Error 2 +make[1]: *** [Makefile:1897: arch/arm/mach-imx] Error 2 +make: *** [Makefile:177: sub-make] Error 2
Please take a look.
Missing linux/sizes.h , fixed in V2, thanks.
participants (2)
-
Fabio Estevam
-
Marek Vasut