1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <platform_def.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <arch_helpers.h> 12*91f16700Schasinglulu #include <common/bl_common.h> 13*91f16700Schasinglulu #include <common/debug.h> 14*91f16700Schasinglulu #include <common/desc_image_load.h> 15*91f16700Schasinglulu #include <drivers/mmc.h> 16*91f16700Schasinglulu #include <lib/xlat_tables/xlat_mmu_helpers.h> 17*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_defs.h> 18*91f16700Schasinglulu #include <lib/mmio.h> 19*91f16700Schasinglulu #include <lib/optee_utils.h> 20*91f16700Schasinglulu #include <lib/utils.h> 21*91f16700Schasinglulu 22*91f16700Schasinglulu #include <imx_aips.h> 23*91f16700Schasinglulu #include <imx_caam.h> 24*91f16700Schasinglulu #include <imx_clock.h> 25*91f16700Schasinglulu #include <imx_csu.h> 26*91f16700Schasinglulu #include <imx_gpt.h> 27*91f16700Schasinglulu #include <imx_uart.h> 28*91f16700Schasinglulu #include <imx_snvs.h> 29*91f16700Schasinglulu #include <imx_wdog.h> 30*91f16700Schasinglulu #include <imx7_def.h> 31*91f16700Schasinglulu 32*91f16700Schasinglulu #ifndef AARCH32_SP_OPTEE 33*91f16700Schasinglulu #error "Must build with OPTEE support included" 34*91f16700Schasinglulu #endif 35*91f16700Schasinglulu 36*91f16700Schasinglulu uintptr_t plat_get_ns_image_entrypoint(void) 37*91f16700Schasinglulu { 38*91f16700Schasinglulu return IMX7_UBOOT_BASE; 39*91f16700Schasinglulu } 40*91f16700Schasinglulu 41*91f16700Schasinglulu static uint32_t imx7_get_spsr_for_bl32_entry(void) 42*91f16700Schasinglulu { 43*91f16700Schasinglulu return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, 44*91f16700Schasinglulu DISABLE_ALL_EXCEPTIONS); 45*91f16700Schasinglulu } 46*91f16700Schasinglulu 47*91f16700Schasinglulu static uint32_t imx7_get_spsr_for_bl33_entry(void) 48*91f16700Schasinglulu { 49*91f16700Schasinglulu return SPSR_MODE32(MODE32_svc, 50*91f16700Schasinglulu plat_get_ns_image_entrypoint() & 0x1, 51*91f16700Schasinglulu SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); 52*91f16700Schasinglulu } 53*91f16700Schasinglulu 54*91f16700Schasinglulu int bl2_plat_handle_post_image_load(unsigned int image_id) 55*91f16700Schasinglulu { 56*91f16700Schasinglulu int err = 0; 57*91f16700Schasinglulu bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 58*91f16700Schasinglulu bl_mem_params_node_t *hw_cfg_mem_params = NULL; 59*91f16700Schasinglulu 60*91f16700Schasinglulu bl_mem_params_node_t *pager_mem_params = NULL; 61*91f16700Schasinglulu bl_mem_params_node_t *paged_mem_params = NULL; 62*91f16700Schasinglulu 63*91f16700Schasinglulu assert(bl_mem_params); 64*91f16700Schasinglulu 65*91f16700Schasinglulu switch (image_id) { 66*91f16700Schasinglulu case BL32_IMAGE_ID: 67*91f16700Schasinglulu pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); 68*91f16700Schasinglulu assert(pager_mem_params); 69*91f16700Schasinglulu 70*91f16700Schasinglulu paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); 71*91f16700Schasinglulu assert(paged_mem_params); 72*91f16700Schasinglulu 73*91f16700Schasinglulu err = parse_optee_header(&bl_mem_params->ep_info, 74*91f16700Schasinglulu &pager_mem_params->image_info, 75*91f16700Schasinglulu &paged_mem_params->image_info); 76*91f16700Schasinglulu if (err != 0) 77*91f16700Schasinglulu WARN("OPTEE header parse error.\n"); 78*91f16700Schasinglulu 79*91f16700Schasinglulu /* 80*91f16700Schasinglulu * When ATF loads the DTB the address of the DTB is passed in 81*91f16700Schasinglulu * arg2, if an hw config image is present use the base address 82*91f16700Schasinglulu * as DTB address an pass it as arg2 83*91f16700Schasinglulu */ 84*91f16700Schasinglulu hw_cfg_mem_params = get_bl_mem_params_node(HW_CONFIG_ID); 85*91f16700Schasinglulu 86*91f16700Schasinglulu bl_mem_params->ep_info.args.arg0 = 87*91f16700Schasinglulu bl_mem_params->ep_info.args.arg1; 88*91f16700Schasinglulu bl_mem_params->ep_info.args.arg1 = 0; 89*91f16700Schasinglulu if (hw_cfg_mem_params) 90*91f16700Schasinglulu bl_mem_params->ep_info.args.arg2 = 91*91f16700Schasinglulu hw_cfg_mem_params->image_info.image_base; 92*91f16700Schasinglulu else 93*91f16700Schasinglulu bl_mem_params->ep_info.args.arg2 = 0; 94*91f16700Schasinglulu bl_mem_params->ep_info.args.arg3 = 0; 95*91f16700Schasinglulu bl_mem_params->ep_info.spsr = imx7_get_spsr_for_bl32_entry(); 96*91f16700Schasinglulu break; 97*91f16700Schasinglulu 98*91f16700Schasinglulu case BL33_IMAGE_ID: 99*91f16700Schasinglulu /* AArch32 only core: OP-TEE expects NSec EP in register LR */ 100*91f16700Schasinglulu pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID); 101*91f16700Schasinglulu assert(pager_mem_params); 102*91f16700Schasinglulu pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; 103*91f16700Schasinglulu 104*91f16700Schasinglulu /* BL33 expects to receive the primary CPU MPID (through r0) */ 105*91f16700Schasinglulu bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); 106*91f16700Schasinglulu bl_mem_params->ep_info.spsr = imx7_get_spsr_for_bl33_entry(); 107*91f16700Schasinglulu break; 108*91f16700Schasinglulu 109*91f16700Schasinglulu default: 110*91f16700Schasinglulu /* Do nothing in default case */ 111*91f16700Schasinglulu break; 112*91f16700Schasinglulu } 113*91f16700Schasinglulu 114*91f16700Schasinglulu return err; 115*91f16700Schasinglulu } 116*91f16700Schasinglulu 117*91f16700Schasinglulu void bl2_el3_plat_arch_setup(void) 118*91f16700Schasinglulu { 119*91f16700Schasinglulu /* Setup the MMU here */ 120*91f16700Schasinglulu } 121*91f16700Schasinglulu 122*91f16700Schasinglulu static void imx7_setup_system_counter(void) 123*91f16700Schasinglulu { 124*91f16700Schasinglulu unsigned long freq = SYS_COUNTER_FREQ_IN_TICKS; 125*91f16700Schasinglulu 126*91f16700Schasinglulu /* Set the frequency table index to our target frequency */ 127*91f16700Schasinglulu write_cntfrq(freq); 128*91f16700Schasinglulu 129*91f16700Schasinglulu /* Enable system counter @ frequency table index 0, halt on debug */ 130*91f16700Schasinglulu mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, 131*91f16700Schasinglulu CNTCR_FCREQ(0) | CNTCR_HDBG | CNTCR_EN); 132*91f16700Schasinglulu } 133*91f16700Schasinglulu 134*91f16700Schasinglulu static void imx7_setup_wdog_clocks(void) 135*91f16700Schasinglulu { 136*91f16700Schasinglulu uint32_t wdog_en_bits = (uint32_t)WDOG_DEFAULT_CLK_SELECT; 137*91f16700Schasinglulu 138*91f16700Schasinglulu imx_clock_set_wdog_clk_root_bits(wdog_en_bits); 139*91f16700Schasinglulu imx_clock_enable_wdog(0); 140*91f16700Schasinglulu imx_clock_enable_wdog(1); 141*91f16700Schasinglulu imx_clock_enable_wdog(2); 142*91f16700Schasinglulu imx_clock_enable_wdog(3); 143*91f16700Schasinglulu } 144*91f16700Schasinglulu 145*91f16700Schasinglulu 146*91f16700Schasinglulu /* 147*91f16700Schasinglulu * bl2_el3_early_platform_setup() 148*91f16700Schasinglulu * MMU off 149*91f16700Schasinglulu */ 150*91f16700Schasinglulu void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, 151*91f16700Schasinglulu u_register_t arg3, u_register_t arg4) 152*91f16700Schasinglulu { 153*91f16700Schasinglulu static console_t console; 154*91f16700Schasinglulu int console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME; 155*91f16700Schasinglulu 156*91f16700Schasinglulu /* Initialize common components */ 157*91f16700Schasinglulu imx_aips_init(); 158*91f16700Schasinglulu imx_csu_init(); 159*91f16700Schasinglulu imx_snvs_init(); 160*91f16700Schasinglulu imx_gpt_ops_init(GPT1_BASE_ADDR); 161*91f16700Schasinglulu imx_clock_init(); 162*91f16700Schasinglulu imx7_setup_system_counter(); 163*91f16700Schasinglulu imx7_setup_wdog_clocks(); 164*91f16700Schasinglulu 165*91f16700Schasinglulu /* Platform specific setup */ 166*91f16700Schasinglulu imx7_platform_setup(arg1, arg2, arg3, arg4); 167*91f16700Schasinglulu 168*91f16700Schasinglulu /* Init UART, clock should be enabled in imx7_platform_setup() */ 169*91f16700Schasinglulu console_imx_uart_register(PLAT_IMX7_BOOT_UART_BASE, 170*91f16700Schasinglulu PLAT_IMX7_BOOT_UART_CLK_IN_HZ, 171*91f16700Schasinglulu PLAT_IMX7_CONSOLE_BAUDRATE, 172*91f16700Schasinglulu &console); 173*91f16700Schasinglulu console_set_scope(&console, console_scope); 174*91f16700Schasinglulu 175*91f16700Schasinglulu /* Open handles to persistent storage */ 176*91f16700Schasinglulu plat_imx_io_setup(); 177*91f16700Schasinglulu 178*91f16700Schasinglulu /* Setup higher-level functionality CAAM, RTC etc */ 179*91f16700Schasinglulu imx_caam_init(); 180*91f16700Schasinglulu imx_wdog_init(); 181*91f16700Schasinglulu 182*91f16700Schasinglulu /* Print out the expected memory map */ 183*91f16700Schasinglulu VERBOSE("\tOPTEE 0x%08x-0x%08x\n", IMX7_OPTEE_BASE, IMX7_OPTEE_LIMIT); 184*91f16700Schasinglulu VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT); 185*91f16700Schasinglulu VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT); 186*91f16700Schasinglulu VERBOSE("\tFIP 0x%08x-0x%08x\n", IMX_FIP_BASE, IMX_FIP_LIMIT); 187*91f16700Schasinglulu VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", IMX7_DTB_OVERLAY_BASE, IMX7_DTB_OVERLAY_LIMIT); 188*91f16700Schasinglulu VERBOSE("\tDTB 0x%08x-0x%08x\n", IMX7_DTB_BASE, IMX7_DTB_LIMIT); 189*91f16700Schasinglulu VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", IMX7_UBOOT_BASE, IMX7_UBOOT_LIMIT); 190*91f16700Schasinglulu } 191*91f16700Schasinglulu 192*91f16700Schasinglulu /* 193*91f16700Schasinglulu * bl2_platform_setup() 194*91f16700Schasinglulu * MMU on - enabled by bl2_el3_plat_arch_setup() 195*91f16700Schasinglulu */ 196*91f16700Schasinglulu void bl2_platform_setup(void) 197*91f16700Schasinglulu { 198*91f16700Schasinglulu } 199