diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 13 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 17 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c | 6 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 16 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/ppa.c | 7 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/soc.c | 16 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/spl.c | 41 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/sec_firmware.c | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/start.S | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-fsl-layerscape/config.h | 1 |
10 files changed, 109 insertions, 13 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index fa386c6896..d8b285dcd7 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -135,6 +135,19 @@ config FSL_LS_PPA which is loaded during boot stage, and then remains resident in RAM and runs in the TrustZone after boot. Say y to enable it. + +config SPL_FSL_LS_PPA + bool "FSL Layerscape PPA firmware support for SPL build" + depends on !ARMV8_PSCI + select SPL_ARMV8_SEC_FIRMWARE_SUPPORT + select SEC_FIRMWARE_ARMV8_PSCI + select ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT if FSL_LSCH2 + help + The FSL Primary Protected Application (PPA) is a software component + which is loaded during boot stage, and then remains resident in RAM + and runs in the TrustZone after boot. This is to load PPA during SPL + stage instead of the RAM version of U-Boot. Once PPA is initialized, + the rest of U-Boot (including RAM version) runs at EL2. choice prompt "FSL Layerscape PPA firmware loading-media select" depends on FSL_LS_PPA diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index cba0095e6a..cb3a52c711 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -244,6 +244,14 @@ u64 get_page_table_size(void) int arch_cpu_init(void) { + /* + * This function is called before U-Boot relocates itself to speed up + * on system running. It is not necessary to run if performance is not + * critical. Skip if MMU is already enabled by SPL or other means. + */ + if (get_sctlr() & CR_M) + return 0; + icache_enable(); __asm_invalidate_dcache_all(); __asm_invalidate_tlb_all(); @@ -464,7 +472,7 @@ int cpu_eth_init(bd_t *bis) { int error = 0; -#ifdef CONFIG_FSL_MC_ENET +#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) error = fsl_mc_ldpaa_init(bis); #endif #ifdef CONFIG_FMAN_ENET @@ -530,7 +538,8 @@ int timer_init(void) unsigned long cntfrq = COUNTER_FREQUENCY_REAL; /* Update with accurate clock frequency */ - asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory"); + if (current_el() == 3) + asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory"); #endif #ifdef CONFIG_FSL_LSCH3 @@ -608,7 +617,7 @@ phys_size_t board_reserve_ram_top(phys_size_t ram_size) { phys_size_t ram_top = ram_size; -#ifdef CONFIG_FSL_MC_ENET +#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) /* The start address of MC reserved memory needs to be aligned. */ ram_top -= mc_get_dram_block_size(); ram_top &= ~(CONFIG_SYS_MC_RSV_MEM_ALIGN - 1); @@ -723,7 +732,7 @@ int dram_init_banksize(void) } #endif /* CONFIG_SYS_MEM_RESERVE_SECURE */ -#ifdef CONFIG_FSL_MC_ENET +#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) /* Assign memory for MC */ #ifdef CONFIG_SYS_DDR_BLOCK3_BASE if (gd->bd->bi_dram[2].size >= diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c index 955e0b7478..ef97556367 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c @@ -18,7 +18,7 @@ static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT]; static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT]; #endif -#ifdef CONFIG_FSL_MC_ENET +#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) int xfi_dpmac[XFI8 + 1]; int sgmii_dpmac[SGMII16 + 1]; #endif @@ -110,7 +110,7 @@ void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask, debug("Unknown SerDes lane protocol %d\n", lane_prtcl); else { serdes_prtcl_map[lane_prtcl] = 1; -#ifdef CONFIG_FSL_MC_ENET +#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) switch (lane_prtcl) { case QSGMII_A: case QSGMII_B: @@ -141,7 +141,7 @@ void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask, void fsl_serdes_init(void) { -#ifdef CONFIG_FSL_MC_ENET +#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) int i , j; for (i = XFI1, j = 1; i <= XFI8; i++, j++) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index f427356104..619d9b7a0e 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -73,6 +73,9 @@ ENDPROC(smp_kick_all_cpus) ENTRY(lowlevel_init) mov x29, lr /* Save LR */ + switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ +1: + #ifdef CONFIG_FSL_LSCH3 /* Set Wuo bit for RN-I 20 */ @@ -193,6 +196,7 @@ ENTRY(lowlevel_init) #endif #endif +100: branch_if_master x0, x1, 2f #if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY) @@ -201,6 +205,8 @@ ENTRY(lowlevel_init) #endif 2: + switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ +1: #ifdef CONFIG_FSL_TZPC_BP147 /* Set Non Secure access for all devices protected via TZPC */ ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */ @@ -266,8 +272,11 @@ ENTRY(lowlevel_init) isb dsb sy #endif +100: 1: #ifdef CONFIG_ARCH_LS1046A + switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ +1: /* Initialize the L2 RAM latency */ mrs x1, S3_1_c11_c0_2 mov x0, #0x1C7 @@ -279,6 +288,7 @@ ENTRY(lowlevel_init) orr x1, x1, #0x80 msr S3_1_c11_c0_2, x1 isb +100: #endif #if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD) @@ -379,11 +389,14 @@ ENTRY(__asm_flush_l3_dcache) /* * Return status in x0 * success 0 - * tmeout 1 for setting SFONLY, 2 for FAM, 3 for both + * timeout 1 for setting SFONLY, 2 for FAM, 3 for both */ mov x29, lr mov x8, #0 + switch_el x0, 1f, 100f, 100f /* skip if not in EL3 */ + +1: dsb sy mov x0, #0x1 /* HNFPSTAT_SFONLY */ bl hnf_set_pstate @@ -401,6 +414,7 @@ ENTRY(__asm_flush_l3_dcache) bl hnf_pstate_poll cbz x0, 1f add x8, x8, #0x2 +100: 1: mov x0, x8 mov lr, x29 diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c index 26c47a183c..35c612df05 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR; int ppa_init(void) { + unsigned int el = current_el(); void *ppa_fit_addr; u32 *boot_loc_ptr_l, *boot_loc_ptr_h; int ret; @@ -45,6 +46,12 @@ int ppa_init(void) #endif #endif + /* Skip if running at lower exception level */ + if (el < 3) { + debug("Skipping PPA init, running at EL%d\n", el); + return 0; + } + #ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR; debug("%s: PPA image load from XIP\n", __func__); diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 9e3cdd78af..0943e833d7 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -134,7 +134,7 @@ void erratum_a009635(void) static void erratum_rcw_src(void) { -#if defined(CONFIG_SPL) +#if defined(CONFIG_SPL) && defined(CONFIG_NAND_BOOT) u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE; u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE; u32 val; @@ -288,6 +288,10 @@ static void erratum_a008850_early(void) struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR; struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + /* Skip if running at lower exception level */ + if (current_el() < 3) + return; + /* disables propagation of barrier transactions to DDRC from CCI400 */ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); @@ -304,6 +308,10 @@ void erratum_a008850_post(void) struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; u32 tmp; + /* Skip if running at lower exception level */ + if (current_el() < 3) + return; + /* enable propagation of barrier transactions to DDRC from CCI400 */ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); @@ -455,8 +463,10 @@ void fsl_lsch2_early_init_f(void) * Enable snoop requests and DVM message requests for * Slave insterface S4 (A53 core cluster) */ - out_le32(&cci->slave[4].snoop_ctrl, - CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + if (current_el() == 3) { + out_le32(&cci->slave[4].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + } /* Erratum */ erratum_a008850_early(); /* part 1 of 2 */ diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index eb730e84a4..2776240be3 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -9,6 +9,9 @@ #include <asm/io.h> #include <fsl_ifc.h> #include <i2c.h> +#include <fsl_csu.h> +#include <asm/arch/fdt.h> +#include <asm/arch/ppa.h> DECLARE_GLOBAL_DATA_PTR; @@ -57,6 +60,12 @@ void spl_board_init(void) val = (in_le32(SMMU_NSCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK); out_le32(SMMU_NSCR0, val); #endif +#ifdef CONFIG_LAYERSCAPE_NS_ACCESS + enable_layerscape_ns_access(); +#endif +#ifdef CONFIG_SPL_FSL_LS_PPA + ppa_init(); +#endif } void board_init_f(ulong dummy) @@ -76,5 +85,35 @@ void board_init_f(ulong dummy) i2c_init_all(); #endif dram_init(); -} +#ifdef CONFIG_SPL_FSL_LS_PPA +#ifndef CONFIG_SYS_MEM_RESERVE_SECURE +#error Need secure RAM for PPA #endif + /* + * Secure memory location is determined in dram_init_banksize(). + * gd->ram_size is deducted by the size of secure ram. + */ + dram_init_banksize(); + + /* + * After dram_init_bank_size(), we know U-Boot only uses the first + * memory bank regardless how big the memory is. + */ + gd->ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; + + /* + * If PPA is loaded, U-Boot will resume running at EL2. + * Cache and MMU will be enabled. Need a place for TLB. + * U-Boot will be relocated to the end of available memory + * in first bank. At this point, we cannot know how much + * memory U-Boot uses. Put TLB table lower by SPL_TLB_SETBACK + * to avoid overlapping. As soon as the RAM version U-Boot sets + * up new MMU, this space is no longer needed. + */ + gd->ram_top -= SPL_TLB_SETBACK; + gd->arch.tlb_size = PGTABLE_SIZE; + gd->arch.tlb_addr = (gd->ram_top - gd->arch.tlb_size) & ~(0x10000 - 1); + gd->arch.tlb_allocated = gd->arch.tlb_addr; +#endif /* CONFIG_SPL_FSL_LS_PPA */ +} +#endif /* CONFIG_SPL_BUILD */ diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c index 4afa3ad8b1..fffce712d3 100644 --- a/arch/arm/cpu/armv8/sec_firmware.c +++ b/arch/arm/cpu/armv8/sec_firmware.c @@ -224,7 +224,7 @@ __weak bool sec_firmware_is_valid(const void *sec_firmware_img) */ unsigned int sec_firmware_support_psci_version(void) { - if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) + if (current_el() == SEC_FIRMWARE_TARGET_EL) return _sec_firmware_support_psci_version(); return PSCI_INVALID_VER; diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 354468b905..5c500be51d 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -91,9 +91,12 @@ save_boot_params_ret: * this bit should be set for A53/A57/A72. */ #ifdef CONFIG_ARMV8_SET_SMPEN + switch_el x1, 3f, 1f, 1f +3: mrs x0, S3_1_c15_c2_1 /* cpuectlr_el1 */ orr x0, x0, #0x40 msr S3_1_c15_c2_1, x0 +1: #endif /* Apply ARM core specific erratas */ diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index 93e6597d9e..79e94f9f2c 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -17,6 +17,7 @@ * To be aligned with MMU block size */ #define CONFIG_SYS_MEM_RESERVE_SECURE (2048 * 1024) /* 2MB */ +#define SPL_TLB_SETBACK 0x1000000 /* 16MB under effective memory top */ #ifdef CONFIG_ARCH_LS2080A #define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 4, 4 } |