1dddba19aSStephan Gerhold /* 2dddba19aSStephan Gerhold * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net> 3dddba19aSStephan Gerhold * 4dddba19aSStephan Gerhold * SPDX-License-Identifier: BSD-3-Clause 5dddba19aSStephan Gerhold */ 6dddba19aSStephan Gerhold 7dddba19aSStephan Gerhold #include <assert.h> 8dddba19aSStephan Gerhold 9dddba19aSStephan Gerhold #include <arch.h> 10dddba19aSStephan Gerhold #include <common/debug.h> 11dddba19aSStephan Gerhold #include <drivers/console.h> 12dddba19aSStephan Gerhold #include <drivers/generic_delay_timer.h> 13dddba19aSStephan Gerhold #include <lib/mmio.h> 14dddba19aSStephan Gerhold #include <lib/xlat_tables/xlat_mmu_helpers.h> 15dddba19aSStephan Gerhold #include <lib/xlat_tables/xlat_tables_v2.h> 16dddba19aSStephan Gerhold #include <plat/common/platform.h> 17dddba19aSStephan Gerhold 18*af644731SStephan Gerhold #include "msm8916_gicv2.h" 19dddba19aSStephan Gerhold #include <msm8916_mmap.h> 20dddba19aSStephan Gerhold #include <platform_def.h> 21dddba19aSStephan Gerhold #include <uartdm_console.h> 22dddba19aSStephan Gerhold 23dddba19aSStephan Gerhold static const mmap_region_t msm8916_mmap[] = { 24dddba19aSStephan Gerhold MAP_REGION_FLAT(PCNOC_BASE, PCNOC_SIZE, 25dddba19aSStephan Gerhold MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), 26dddba19aSStephan Gerhold MAP_REGION_FLAT(APCS_BASE, APCS_SIZE, 27dddba19aSStephan Gerhold MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), 28dddba19aSStephan Gerhold {}, 29dddba19aSStephan Gerhold }; 30dddba19aSStephan Gerhold 31dddba19aSStephan Gerhold static struct { 32dddba19aSStephan Gerhold entry_point_info_t bl32; 33dddba19aSStephan Gerhold entry_point_info_t bl33; 34dddba19aSStephan Gerhold } image_ep_info = { 35dddba19aSStephan Gerhold /* BL32 entry point */ 36dddba19aSStephan Gerhold SET_STATIC_PARAM_HEAD(bl32, PARAM_EP, VERSION_1, 37dddba19aSStephan Gerhold entry_point_info_t, SECURE), 38dddba19aSStephan Gerhold .bl32.pc = BL32_BASE, 39dddba19aSStephan Gerhold 40dddba19aSStephan Gerhold /* BL33 entry point */ 41dddba19aSStephan Gerhold SET_STATIC_PARAM_HEAD(bl33, PARAM_EP, VERSION_1, 42dddba19aSStephan Gerhold entry_point_info_t, NON_SECURE), 43dddba19aSStephan Gerhold .bl33.pc = PRELOADED_BL33_BASE, 44dddba19aSStephan Gerhold .bl33.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), 45dddba19aSStephan Gerhold }; 46dddba19aSStephan Gerhold 47dddba19aSStephan Gerhold static console_t console; 48dddba19aSStephan Gerhold 49dddba19aSStephan Gerhold unsigned int plat_get_syscnt_freq2(void) 50dddba19aSStephan Gerhold { 51dddba19aSStephan Gerhold return PLAT_SYSCNT_FREQ; 52dddba19aSStephan Gerhold } 53dddba19aSStephan Gerhold 54dddba19aSStephan Gerhold #define CLK_ENABLE BIT_32(0) 55dddba19aSStephan Gerhold #define CLK_OFF BIT_32(31) 56dddba19aSStephan Gerhold 57dddba19aSStephan Gerhold #define GPIO_BLSP_UART2_TX 4 58dddba19aSStephan Gerhold #define GPIO_BLSP_UART2_RX 5 59dddba19aSStephan Gerhold #define GPIO_CFG_FUNC_BLSP_UART2 (U(0x2) << 2) 60dddba19aSStephan Gerhold #define GPIO_CFG_DRV_STRENGTH_16MA (U(0x7) << 6) 61dddba19aSStephan Gerhold 62dddba19aSStephan Gerhold #define GCC_BLSP1_AHB_CBCR (GCC_BASE + 0x01008) 63dddba19aSStephan Gerhold #define GCC_BLSP1_UART2_APPS_CBCR (GCC_BASE + 0x0302c) 64dddba19aSStephan Gerhold #define GCC_APCS_CLOCK_BRANCH_ENA_VOTE (GCC_BASE + 0x45004) 65dddba19aSStephan Gerhold #define BLSP1_AHB_CLK_ENA BIT_32(10) 66dddba19aSStephan Gerhold 67dddba19aSStephan Gerhold /* 68dddba19aSStephan Gerhold * The previous boot stage seems to disable most of the UART setup before exit 69dddba19aSStephan Gerhold * so it must be enabled here again before the UART console can be used. 70dddba19aSStephan Gerhold */ 71dddba19aSStephan Gerhold static void msm8916_enable_blsp_uart2(void) 72dddba19aSStephan Gerhold { 73dddba19aSStephan Gerhold /* Route GPIOs to BLSP UART2 */ 74dddba19aSStephan Gerhold mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_TX), 75dddba19aSStephan Gerhold GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA); 76dddba19aSStephan Gerhold mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_RX), 77dddba19aSStephan Gerhold GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA); 78dddba19aSStephan Gerhold 79dddba19aSStephan Gerhold /* Enable AHB clock */ 80dddba19aSStephan Gerhold mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA); 81dddba19aSStephan Gerhold while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF) 82dddba19aSStephan Gerhold ; 83dddba19aSStephan Gerhold 84dddba19aSStephan Gerhold /* Enable BLSP UART2 clock */ 85dddba19aSStephan Gerhold mmio_setbits_32(GCC_BLSP1_UART2_APPS_CBCR, CLK_ENABLE); 86dddba19aSStephan Gerhold while (mmio_read_32(GCC_BLSP1_UART2_APPS_CBCR) & CLK_OFF) 87dddba19aSStephan Gerhold ; 88dddba19aSStephan Gerhold } 89dddba19aSStephan Gerhold 90dddba19aSStephan Gerhold void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 91dddba19aSStephan Gerhold u_register_t arg2, u_register_t arg3) 92dddba19aSStephan Gerhold { 93dddba19aSStephan Gerhold /* Initialize the debug console as early as possible */ 94dddba19aSStephan Gerhold msm8916_enable_blsp_uart2(); 95dddba19aSStephan Gerhold console_uartdm_register(&console, BLSP_UART2_BASE); 96dddba19aSStephan Gerhold } 97dddba19aSStephan Gerhold 98dddba19aSStephan Gerhold void bl31_plat_arch_setup(void) 99dddba19aSStephan Gerhold { 100dddba19aSStephan Gerhold mmap_add_region(BL31_BASE, BL31_BASE, BL31_END - BL31_BASE, 101dddba19aSStephan Gerhold MT_RW_DATA | MT_SECURE); 102dddba19aSStephan Gerhold mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, 103dddba19aSStephan Gerhold BL_CODE_END - BL_CODE_BASE, 104dddba19aSStephan Gerhold MT_CODE | MT_SECURE); 105dddba19aSStephan Gerhold mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE, 106dddba19aSStephan Gerhold BL_RO_DATA_END - BL_RO_DATA_BASE, 107dddba19aSStephan Gerhold MT_RO_DATA | MT_SECURE); 108dddba19aSStephan Gerhold mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, 109dddba19aSStephan Gerhold BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, 110dddba19aSStephan Gerhold MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER); 111dddba19aSStephan Gerhold 112dddba19aSStephan Gerhold mmap_add(msm8916_mmap); 113dddba19aSStephan Gerhold init_xlat_tables(); 114dddba19aSStephan Gerhold enable_mmu_el3(0); 115dddba19aSStephan Gerhold } 116dddba19aSStephan Gerhold 117*af644731SStephan Gerhold static void msm8916_configure_timer(void) 118*af644731SStephan Gerhold { 119*af644731SStephan Gerhold /* Set timer frequency */ 120*af644731SStephan Gerhold mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, plat_get_syscnt_freq2()); 121*af644731SStephan Gerhold 122*af644731SStephan Gerhold /* Make frame 0 available to non-secure world */ 123*af644731SStephan Gerhold mmio_write_32(APCS_QTMR + CNTNSAR, BIT_32(CNTNSAR_NS_SHIFT(0))); 124*af644731SStephan Gerhold mmio_write_32(APCS_QTMR + CNTACR_BASE(0), 125*af644731SStephan Gerhold BIT_32(CNTACR_RPCT_SHIFT) | BIT_32(CNTACR_RVCT_SHIFT) | 126*af644731SStephan Gerhold BIT_32(CNTACR_RFRQ_SHIFT) | BIT_32(CNTACR_RVOFF_SHIFT) | 127*af644731SStephan Gerhold BIT_32(CNTACR_RWVT_SHIFT) | BIT_32(CNTACR_RWPT_SHIFT)); 128*af644731SStephan Gerhold } 129*af644731SStephan Gerhold 130*af644731SStephan Gerhold /* 131*af644731SStephan Gerhold * The APCS register regions always start with a SECURE register that should 132*af644731SStephan Gerhold * be cleared to 0 to only allow secure access. Since BL31 handles most of 133*af644731SStephan Gerhold * the CPU power management, most of them can be cleared to secure access only. 134*af644731SStephan Gerhold */ 135*af644731SStephan Gerhold #define APCS_GLB_SECURE_STS_NS BIT_32(0) 136*af644731SStephan Gerhold #define APCS_GLB_SECURE_PWR_NS BIT_32(1) 137*af644731SStephan Gerhold 138*af644731SStephan Gerhold static void msm8916_configure_cpu_pm(void) 139*af644731SStephan Gerhold { 140*af644731SStephan Gerhold unsigned int cpu; 141*af644731SStephan Gerhold 142*af644731SStephan Gerhold /* Disallow non-secure access to boot remapper / TCM registers */ 143*af644731SStephan Gerhold mmio_write_32(APCS_CFG, 0); 144*af644731SStephan Gerhold 145*af644731SStephan Gerhold /* 146*af644731SStephan Gerhold * Disallow non-secure access to power management registers. 147*af644731SStephan Gerhold * However, allow STS and PWR since those also seem to control access 148*af644731SStephan Gerhold * to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these 149*af644731SStephan Gerhold * bits are not set, CPU frequency control fails in the non-secure world. 150*af644731SStephan Gerhold */ 151*af644731SStephan Gerhold mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS); 152*af644731SStephan Gerhold 153*af644731SStephan Gerhold /* Disallow non-secure access to L2 SAW2 */ 154*af644731SStephan Gerhold mmio_write_32(APCS_L2_SAW2, 0); 155*af644731SStephan Gerhold 156*af644731SStephan Gerhold /* Disallow non-secure access to CPU ACS and SAW2 */ 157*af644731SStephan Gerhold for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) { 158*af644731SStephan Gerhold mmio_write_32(APCS_ALIAS_ACS(cpu), 0); 159*af644731SStephan Gerhold mmio_write_32(APCS_ALIAS_SAW2(cpu), 0); 160*af644731SStephan Gerhold } 161*af644731SStephan Gerhold } 162*af644731SStephan Gerhold 163*af644731SStephan Gerhold /* 164*af644731SStephan Gerhold * MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU, 165*af644731SStephan Gerhold * which allows routing context bank interrupts to one of 3 interrupt numbers 166*af644731SStephan Gerhold * ("TZ/HYP/NS"). Route all interrupts to the non-secure interrupt number 167*af644731SStephan Gerhold * by default to avoid special setup on the non-secure side. 168*af644731SStephan Gerhold */ 169*af644731SStephan Gerhold #define GCC_SMMU_CFG_CBCR (GCC_BASE + 0x12038) 170*af644731SStephan Gerhold #define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE (GCC_BASE + 0x4500c) 171*af644731SStephan Gerhold #define SMMU_CFG_CLK_ENA BIT_32(12) 172*af644731SStephan Gerhold #define APPS_SMMU_INTR_SEL_NS (APPS_SMMU_QCOM + 0x2000) 173*af644731SStephan Gerhold #define APPS_SMMU_INTR_SEL_NS_EN_ALL U(0xffffffff) 174*af644731SStephan Gerhold 175*af644731SStephan Gerhold static void msm8916_configure_smmu(void) 176*af644731SStephan Gerhold { 177*af644731SStephan Gerhold /* Enable SMMU configuration clock to enable register access */ 178*af644731SStephan Gerhold mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA); 179*af644731SStephan Gerhold while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF) 180*af644731SStephan Gerhold ; 181*af644731SStephan Gerhold 182*af644731SStephan Gerhold /* Route all context bank interrupts to non-secure interrupt */ 183*af644731SStephan Gerhold mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL); 184*af644731SStephan Gerhold 185*af644731SStephan Gerhold /* Disable configuration clock again */ 186*af644731SStephan Gerhold mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA); 187*af644731SStephan Gerhold } 188*af644731SStephan Gerhold 189dddba19aSStephan Gerhold void bl31_platform_setup(void) 190dddba19aSStephan Gerhold { 191*af644731SStephan Gerhold INFO("BL31: Platform setup start\n"); 192dddba19aSStephan Gerhold generic_delay_timer_init(); 193*af644731SStephan Gerhold msm8916_configure_timer(); 194*af644731SStephan Gerhold msm8916_gicv2_init(); 195*af644731SStephan Gerhold msm8916_configure_cpu_pm(); 196*af644731SStephan Gerhold msm8916_configure_smmu(); 197*af644731SStephan Gerhold INFO("BL31: Platform setup done\n"); 198dddba19aSStephan Gerhold } 199dddba19aSStephan Gerhold 200dddba19aSStephan Gerhold entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 201dddba19aSStephan Gerhold { 202dddba19aSStephan Gerhold switch (type) { 203dddba19aSStephan Gerhold case SECURE: 204dddba19aSStephan Gerhold return &image_ep_info.bl32; 205dddba19aSStephan Gerhold case NON_SECURE: 206dddba19aSStephan Gerhold return &image_ep_info.bl33; 207dddba19aSStephan Gerhold default: 208dddba19aSStephan Gerhold assert(sec_state_is_valid(type)); 209dddba19aSStephan Gerhold return NULL; 210dddba19aSStephan Gerhold } 211dddba19aSStephan Gerhold } 212