From patchwork Fri Apr 3 09:25:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 237139 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Fri, 3 Apr 2020 11:25:36 +0200 Subject: [PATCH v2 1/2] arm: stm32mp: activate data cache in SPL and before relocation In-Reply-To: <20200403092537.19961-1-patrick.delaunay@st.com> References: <20200403092537.19961-1-patrick.delaunay@st.com> Message-ID: <20200403105644.v2.1.I2ff601b652f4995a3401dc67c2369a4187046ed8@changeid> Activate the data cache in SPL and in U-Boot before relocation. In arch_cpu_init(), the function early_enable_caches() sets the early TLB, early_tlb[] located .init section, and set cacheable: - for SPL, all the SYSRAM - for U-Boot, all the DDR After relocation, the function enable_caches() (called by board_r) reconfigures the MMU with new TLB location (reserved in board_f.c::reserve_mmu) and re-enable the data cache. This patch allows to reduce the execution time, particularly - for the device tree parsing in U-Boot pre-reloc stage (dm_extended_scan_fd =>dm_scan_fdt) - in I2C timing computation in SPL (stm32_i2c_choose_solution()) For example, the result on STM32MP157C-DK2 board is: 1,6s gain for trusted boot chain with TF-A 2,2s gain for basic boot chain with SPL As TLB is added in .data section, the binary size increased and the SPL load time by ROM code increased (30ms on DK2). Signed-off-by: Patrick Delaunay --- Changes in v2: - create a new function early_enable_caches - use TLB in .init section - use the default weak dram_bank_mmu_setup() and use mmu_set_region_dcache_behaviour() to setup the early MMU configuration - enable data cache on DDR in SPL, after DDR controller initialization arch/arm/mach-stm32mp/cpu.c | 43 ++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c index 36a9205819..c22c1a9bbc 100644 --- a/arch/arm/mach-stm32mp/cpu.c +++ b/arch/arm/mach-stm32mp/cpu.c @@ -75,6 +75,12 @@ #define PKG_SHIFT 27 #define PKG_MASK GENMASK(2, 0) +/* + * early TLB into the .data section so that it not get cleared + * with 16kB allignment (see TTBR0_BASE_ADDR_MASK) + */ +u8 early_tlb[PGTABLE_SIZE] __section(".data") __aligned(0x4000); + #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) #ifndef CONFIG_STM32MP1_TRUSTED static void security_init(void) @@ -186,6 +192,32 @@ u32 get_bootmode(void) TAMP_BOOT_MODE_SHIFT; } +/* + * initialize the MMU and activate cache in SPL or in U- Boot pre-reloc stage + * MMU/TLB is updated in enable_caches() for U-Boot after relocation + * or is deactivated in U-Boot entry function start.S::cpu_init_cp15 + */ +static void early_enable_caches(void) +{ + /* I-cache is already enabled in start.S: cpu_init_cp15 */ + + if (CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) + return; + + gd->arch.tlb_size = PGTABLE_SIZE; + gd->arch.tlb_addr = (unsigned long)&early_tlb; + + dcache_enable(); + + if (IS_ENABLED(CONFIG_SPL_BUILD)) + mmu_set_region_dcache_behaviour(STM32_SYSRAM_BASE, + STM32_SYSRAM_SIZE, + DCACHE_DEFAULT_OPTION); + else + mmu_set_region_dcache_behaviour(STM32_DDR_BASE, STM32_DDR_SIZE, + DCACHE_DEFAULT_OPTION); +} + /* * Early system init */ @@ -193,6 +225,8 @@ int arch_cpu_init(void) { u32 boot_mode; + early_enable_caches(); + /* early armv7 timer init: needed for polling */ timer_init(); @@ -225,7 +259,14 @@ int arch_cpu_init(void) void enable_caches(void) { - /* Enable D-cache. I-cache is already enabled in start.S */ + /* I-cache is already enabled in start.S: icache_enable() not needed */ + + /* deactivate the data cache, early enabled in arch_cpu_init() */ + dcache_disable(); + /* + * update MMU after relocation and enable the data cache + * warning: the TLB location udpated in board_f.c::reserve_mmu + */ dcache_enable(); }