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> Reviewed-by: Fabio Estevam <festevam@gmail.com>
This commit is contained in:

committed by
Fabio Estevam

parent
78d898eec0
commit
ac9153c74f
@@ -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
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user