[PATCH v2] 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 --- V2: Include linux/sizes.h to fix build error due to SZ_64K undefined --- arch/arm/mach-imx/imx8m/soc.c | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index f30178ae213..986687e9ce4 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -32,6 +32,7 @@ #include <imx_sip.h> #include <linux/bitops.h> #include <linux/bitfield.h> +#include <linux/sizes.h>
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
/*

Subject: [PATCH v2] 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
Reviewed-by: Peng Fan peng.fan@nxp.com

On Thu, Sep 5, 2024 at 12:35 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.
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
V2: Include linux/sizes.h to fix build error due to SZ_64K undefined
Reviewed-by: Fabio Estevam festevam@gmail.com

On Thu, Sep 5, 2024 at 12:35 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.
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
Applied to u-boot-imx/next, thanks.
participants (3)
-
Fabio Estevam
-
Marek Vasut
-
Peng Fan