[PATCH] arm: stm32mp1: activate data cache in SPL and before relocation

Patrick Delaunay patrick.delaunay at st.com
Mon Mar 30 09:46:13 CEST 2020


Activate the data cache in SPL and in U-Boot before relocation
- before relocation, the TLB is located after U-Boot
  (CONFIG_SYS_TEXT_BASE and an assumed 2MB max size)
  and all the DDR is marked cacheable
- in SPL, the TLB is located at the end of SYSRAM, just after the stack
  (CONFIG_SPL_STACK) with size PGTABLE_SIZE = 16kB
  and all the SYSRAM is marked cacheable

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

Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com>
---

Example of bootstage report on STM32MP157C-DK2

1/ For trusted boot chain with TF-A

a) Before the patch

    STM32MP> bootstage report
    Timer summary in microseconds (9 records):
           Mark    Elapsed  Stage
              0          0  reset
        583,290    583,290  board_init_f
      2,348,898  1,765,608  board_init_r
      2,664,580    315,682  id=64
      2,704,027     39,447  id=65
      2,704,729        702  main_loop
      5,563,519  2,858,790  id=175

    Accumulated time:
                    41,696  dm_r
                   615,561  dm_f

b) After the patch
    STM32MP> bootstage report

Timer summary in microseconds (9 records):
       Mark    Elapsed  Stage
          0          0  reset
    577,841    577,841  board_init_f
    722,178    144,337  board_init_r
  1,038,458    316,280  id=64
  1,078,298     39,840  id=65
  1,078,999        701  main_loop
  4,169,020  3,090,021  id=175

Accumulated time:
                36,330  dm_f
                41,999  dm_r

2/ And for the basic boot chain with SPL

a) Before the patch:

    STM32MP> bootstage report
    Timer summary in microseconds (12 records):
           Mark    Elapsed  Stage
              0          0  reset
        195,613    195,613  SPL
        837,867    642,254  end SPL
        840,117      2,250  board_init_f
      2,739,639  1,899,522  board_init_r
      3,066,815    327,176  id=64
      3,103,377     36,562  id=65
      3,104,078        701  main_loop
      3,142,171     38,093  id=175

    Accumulated time:
                    38,124  dm_spl
                    41,956  dm_r
                   648,861  dm_f

b) After the patch

    STM32MP> bootstage report
    Timer summary in microseconds (12 records):
           Mark    Elapsed  Stage
              0          0  reset
        195,859    195,859  SPL
        330,190    134,331  end SPL
        332,408      2,218  board_init_f
        482,688    150,280  board_init_r
        808,694    326,006  id=64
        845,029     36,335  id=65
        845,730        701  main_loop
      3,281,876  2,436,146  id=175

    Accumulated time:
                     3,169  dm_spl
                    36,041  dm_f
                    41,701  dm_r


 arch/arm/mach-stm32mp/cpu.c       | 28 ++++++++++++++++++++++++-
 arch/arm/mach-stm32mp/dram_init.c | 35 +++++++++++++++++++++++++++++++
 include/configs/stm32mp1.h        |  4 ++--
 3 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 36a9205819..579468a1a0 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -193,6 +193,26 @@ int arch_cpu_init(void)
 {
 	u32 boot_mode;
 
+	/*
+	 * initialialize the MMU and activate data cache
+	 * in SPL or in U- Boot pre-reloc stage
+	 */
+	gd->arch.tlb_size = PGTABLE_SIZE;
+#if defined(CONFIG_SPL_BUILD)
+#if (STM32_SYSRAM_BASE + STM32_SYSRAM_SIZE - CONFIG_SPL_STACK < PGTABLE_SIZE)
+#error "The reserved memory for SPL PGTABLE is not enough."
+#endif
+	gd->arch.tlb_addr = CONFIG_SPL_STACK;
+#else
+	/* TLB is located after U-Boot, assumed 2MB as max size */
+	gd->arch.tlb_addr = CONFIG_SYS_TEXT_BASE + SZ_2M;
+#endif
+	dcache_enable();
+	/*
+	 * MMU/TLB is updated in enable_caches() for U-Boot after relocation
+	 * or is deactivated in U-Boot start.S::cpu_init_cp15 for SPL
+	 */
+
 	/* early armv7 timer init: needed for polling */
 	timer_init();
 
@@ -225,7 +245,13 @@ 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 */
+	/* deactivate the data cache, early enabled in arch_cpu_init() */
+	dcache_disable();
+	/*
+	 * update MMU after relocation, the TLB location was udpated in
+	 * board_f.c::reserve_mmu, and enable the data cache
+	 */
 	dcache_enable();
 }
 
diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c
index 3233415eff..15b39ecc03 100644
--- a/arch/arm/mach-stm32mp/dram_init.c
+++ b/arch/arm/mach-stm32mp/dram_init.c
@@ -7,9 +7,29 @@
 #include <dm.h>
 #include <lmb.h>
 #include <ram.h>
+#include <asm/cache.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static void set_mmu_dcache(u32 addr, u32 size)
+{
+	int	i;
+	u32 start, end;
+
+	start = addr >> MMU_SECTION_SHIFT;
+	end = ((u64)addr + (u64)size) >> MMU_SECTION_SHIFT;
+
+	for (i = start; i < end; i++) {
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+		set_section_dcache(i, DCACHE_WRITETHROUGH);
+#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC)
+		set_section_dcache(i, DCACHE_WRITEALLOC);
+#else
+		set_section_dcache(i, DCACHE_WRITEBACK);
+#endif
+	}
+}
+
 int dram_init(void)
 {
 	struct ram_info ram;
@@ -49,3 +69,18 @@ ulong board_get_usable_ram_top(ulong total_size)
 
 	return gd->ram_top;
 }
+
+void dram_bank_mmu_setup(int bank)
+{
+	if (gd->flags & GD_FLG_RELOC) {
+		debug("%s: bank: %d\n", __func__, bank);
+		set_mmu_dcache(gd->bd->bi_dram[bank].start,
+			       gd->bd->bi_dram[bank].size);
+	} else {
+#if defined(CONFIG_SPL_BUILD)
+		set_mmu_dcache(STM32_SYSRAM_BASE, STM32_SYSRAM_SIZE);
+#else
+		set_mmu_dcache(STM32_DDR_BASE, STM32_DDR_SIZE);
+#endif
+	}
+}
diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index c34a720e0c..5203fc93ad 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -58,8 +58,8 @@
 
 /* limit SYSRAM usage to first 128 KB */
 #define CONFIG_SPL_MAX_SIZE		0x00020000
-#define CONFIG_SPL_STACK		(STM32_SYSRAM_BASE + \
-					 STM32_SYSRAM_SIZE)
+/* stack at STM32_SYSRAM_BASE + STM32_SYSRAM_SIZE - PGTABLE_SIZE (=16kB) */
+#define CONFIG_SPL_STACK		0x2FFFC000
 #endif /* #ifdef CONFIG_SPL */
 
 #define CONFIG_SYS_MEMTEST_START	STM32_DDR_BASE
-- 
2.17.1



More information about the U-Boot mailing list