1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2015-2020, Broadcom 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu#include <arch.h> 8*91f16700Schasinglulu#include <asm_macros.S> 9*91f16700Schasinglulu#include <assert_macros.S> 10*91f16700Schasinglulu#include <cpu_macros.S> 11*91f16700Schasinglulu#include <cortex_a72.h> 12*91f16700Schasinglulu#include <drivers/ti/uart/uart_16550.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu#include <platform_def.h> 15*91f16700Schasinglulu 16*91f16700Schasinglulu .globl plat_reset_handler 17*91f16700Schasinglulu .globl platform_get_entrypoint 18*91f16700Schasinglulu .globl plat_secondary_cold_boot_setup 19*91f16700Schasinglulu .globl platform_mem_init 20*91f16700Schasinglulu .globl platform_check_mpidr 21*91f16700Schasinglulu .globl plat_crash_console_init 22*91f16700Schasinglulu .globl plat_crash_console_putc 23*91f16700Schasinglulu .globl plat_crash_console_flush 24*91f16700Schasinglulu .globl plat_disable_acp 25*91f16700Schasinglulu .globl plat_is_my_cpu_primary 26*91f16700Schasinglulu .globl plat_my_core_pos 27*91f16700Schasinglulu .globl platform_is_primary_cpu 28*91f16700Schasinglulu .globl plat_brcm_calc_core_pos 29*91f16700Schasinglulu .globl plat_get_my_entrypoint 30*91f16700Schasinglulu 31*91f16700Schasinglulu 32*91f16700Schasinglulu /* ------------------------------------------------------------ 33*91f16700Schasinglulu * void plat_l2_init(void); 34*91f16700Schasinglulu * 35*91f16700Schasinglulu * BL1 and BL2 run with one core, one cluster 36*91f16700Schasinglulu * This is safe to disable cluster coherency 37*91f16700Schasinglulu * to make use of the data cache MMU WB attribute 38*91f16700Schasinglulu * for the SRAM. 39*91f16700Schasinglulu * 40*91f16700Schasinglulu * Set L2 Auxiliary Control Register 41*91f16700Schasinglulu * -------------------------------------------------------------------- 42*91f16700Schasinglulu */ 43*91f16700Schasinglulufunc plat_l2_init 44*91f16700Schasinglulu mrs x0, CORTEX_A72_L2ACTLR_EL1 45*91f16700Schasinglulu#if (IMAGE_BL1 || IMAGE_BL2) || defined(USE_SINGLE_CLUSTER) 46*91f16700Schasinglulu orr x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI 47*91f16700Schasinglulu#else 48*91f16700Schasinglulu bic x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI 49*91f16700Schasinglulu#endif 50*91f16700Schasinglulu msr CORTEX_A72_L2ACTLR_EL1, x0 51*91f16700Schasinglulu 52*91f16700Schasinglulu /* Set L2 Control Register */ 53*91f16700Schasinglulu mrs x0, CORTEX_A72_L2CTLR_EL1 54*91f16700Schasinglulu mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_MASK << \ 55*91f16700Schasinglulu CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 56*91f16700Schasinglulu (CORTEX_A72_L2_TAG_RAM_LATENCY_MASK << \ 57*91f16700Schasinglulu CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT) | \ 58*91f16700Schasinglulu (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \ 59*91f16700Schasinglulu (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT)) 60*91f16700Schasinglulu bic x0, x0, x1 61*91f16700Schasinglulu mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << \ 62*91f16700Schasinglulu CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 63*91f16700Schasinglulu (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \ 64*91f16700Schasinglulu (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT)) 65*91f16700Schasinglulu orr x0, x0, x1 66*91f16700Schasinglulu msr CORTEX_A72_L2CTLR_EL1, x0 67*91f16700Schasinglulu 68*91f16700Schasinglulu isb 69*91f16700Schasinglulu ret 70*91f16700Schasingluluendfunc plat_l2_init 71*91f16700Schasinglulu 72*91f16700Schasinglulu /* -------------------------------------------------------------------- 73*91f16700Schasinglulu * void plat_reset_handler(void); 74*91f16700Schasinglulu * 75*91f16700Schasinglulu * Before adding code in this function, refer to the guidelines in 76*91f16700Schasinglulu * docs/firmware-design.md. 77*91f16700Schasinglulu * 78*91f16700Schasinglulu * -------------------------------------------------------------------- 79*91f16700Schasinglulu */ 80*91f16700Schasinglulufunc plat_reset_handler 81*91f16700Schasinglulu mov x9, x30 82*91f16700Schasinglulu bl plat_l2_init 83*91f16700Schasinglulu mov x30, x9 84*91f16700Schasinglulu ret 85*91f16700Schasingluluendfunc plat_reset_handler 86*91f16700Schasinglulu 87*91f16700Schasinglulu /* ----------------------------------------------------- 88*91f16700Schasinglulu * void platform_get_entrypoint (unsigned int mpid); 89*91f16700Schasinglulu * 90*91f16700Schasinglulu * Main job of this routine is to distinguish between 91*91f16700Schasinglulu * a cold and warm boot. 92*91f16700Schasinglulu * On a cold boot the secondaries first wait for the 93*91f16700Schasinglulu * platform to be initialized after which they are 94*91f16700Schasinglulu * hotplugged in. The primary proceeds to perform the 95*91f16700Schasinglulu * platform initialization. 96*91f16700Schasinglulu * ----------------------------------------------------- 97*91f16700Schasinglulu */ 98*91f16700Schasinglulufunc platform_get_entrypoint 99*91f16700Schasinglulu /*TBD-STINGRAY*/ 100*91f16700Schasinglulu mov x0, #0 101*91f16700Schasinglulu ret 102*91f16700Schasingluluendfunc platform_get_entrypoint 103*91f16700Schasinglulu 104*91f16700Schasinglulu /* ----------------------------------------------------- 105*91f16700Schasinglulu * void plat_secondary_cold_boot_setup (void); 106*91f16700Schasinglulu * 107*91f16700Schasinglulu * This function performs any platform specific actions 108*91f16700Schasinglulu * needed for a secondary cpu after a cold reset e.g 109*91f16700Schasinglulu * mark the cpu's presence, mechanism to place it in a 110*91f16700Schasinglulu * holding pen etc. 111*91f16700Schasinglulu * ----------------------------------------------------- 112*91f16700Schasinglulu */ 113*91f16700Schasinglulufunc plat_secondary_cold_boot_setup 114*91f16700Schasinglulu bl plat_my_core_pos 115*91f16700Schasinglulu mov_imm x1, SECONDARY_CPU_SPIN_BASE_ADDR 116*91f16700Schasinglulu add x0, x1, x0, LSL #3 117*91f16700Schasinglulu mov x1, #0 118*91f16700Schasinglulu str x1, [x0] 119*91f16700Schasinglulu 120*91f16700Schasinglulu /* Wait until the entrypoint gets populated */ 121*91f16700Schasinglulupoll_mailbox: 122*91f16700Schasinglulu ldr x1, [x0] 123*91f16700Schasinglulu cbz x1, 1f 124*91f16700Schasinglulu br x1 125*91f16700Schasinglulu1: 126*91f16700Schasinglulu wfe 127*91f16700Schasinglulu b poll_mailbox 128*91f16700Schasingluluendfunc plat_secondary_cold_boot_setup 129*91f16700Schasinglulu 130*91f16700Schasinglulu 131*91f16700Schasinglulu /* ----------------------------------------------------- 132*91f16700Schasinglulu * void platform_mem_init(void); 133*91f16700Schasinglulu * 134*91f16700Schasinglulu * We don't need to carry out any memory initialization 135*91f16700Schasinglulu * on CSS platforms. The Secure RAM is accessible straight away. 136*91f16700Schasinglulu * ----------------------------------------------------- 137*91f16700Schasinglulu */ 138*91f16700Schasinglulufunc platform_mem_init 139*91f16700Schasinglulu /*TBD-STINGRAY*/ 140*91f16700Schasinglulu ret 141*91f16700Schasingluluendfunc platform_mem_init 142*91f16700Schasinglulu 143*91f16700Schasinglulu /* ----------------------------------------------------- 144*91f16700Schasinglulu * Placeholder function which should be redefined by 145*91f16700Schasinglulu * each platform. 146*91f16700Schasinglulu * ----------------------------------------------------- 147*91f16700Schasinglulu */ 148*91f16700Schasinglulufunc platform_check_mpidr 149*91f16700Schasinglulu /*TBD-STINGRAY*/ 150*91f16700Schasinglulu mov x0, xzr 151*91f16700Schasinglulu ret 152*91f16700Schasingluluendfunc platform_check_mpidr 153*91f16700Schasinglulu 154*91f16700Schasinglulu /* --------------------------------------------- 155*91f16700Schasinglulu * int plat_crash_console_init(void) 156*91f16700Schasinglulu * Function to initialize the crash console 157*91f16700Schasinglulu * without a C Runtime to print crash report. 158*91f16700Schasinglulu * Clobber list : x0, x1, x2 159*91f16700Schasinglulu * --------------------------------------------- 160*91f16700Schasinglulu */ 161*91f16700Schasinglulu 162*91f16700Schasinglulufunc plat_crash_console_init 163*91f16700Schasinglulu mov_imm x0, BRCM_CRASH_CONSOLE_BASE 164*91f16700Schasinglulu mov_imm x1, BRCM_CRASH_CONSOLE_REFCLK 165*91f16700Schasinglulu mov_imm x2, BRCM_CRASH_CONSOLE_BAUDRATE 166*91f16700Schasinglulu b console_16550_core_init 167*91f16700Schasinglulu ret 168*91f16700Schasingluluendfunc plat_crash_console_init 169*91f16700Schasinglulu 170*91f16700Schasinglulu /* --------------------------------------------- 171*91f16700Schasinglulu * int plat_crash_console_putc(void) 172*91f16700Schasinglulu * Function to print a character on the crash 173*91f16700Schasinglulu * console without a C Runtime. 174*91f16700Schasinglulu * Clobber list : x1, x2, x3 175*91f16700Schasinglulu * --------------------------------------------- 176*91f16700Schasinglulu */ 177*91f16700Schasinglulu 178*91f16700Schasinglulufunc plat_crash_console_putc 179*91f16700Schasinglulu mov_imm x1, BRCM_CRASH_CONSOLE_BASE 180*91f16700Schasinglulu b console_16550_core_putc 181*91f16700Schasinglulu ret 182*91f16700Schasingluluendfunc plat_crash_console_putc 183*91f16700Schasinglulu 184*91f16700Schasinglulu /* --------------------------------------------- 185*91f16700Schasinglulu * void plat_crash_console_flush(void) 186*91f16700Schasinglulu * Function to flush crash console 187*91f16700Schasinglulu * Clobber list : x0, x1 188*91f16700Schasinglulu * --------------------------------------------- 189*91f16700Schasinglulu */ 190*91f16700Schasinglulufunc plat_crash_console_flush 191*91f16700Schasinglulu mov_imm x0, BRCM_CRASH_CONSOLE_BASE 192*91f16700Schasinglulu b console_16550_core_flush 193*91f16700Schasinglulu ret 194*91f16700Schasingluluendfunc plat_crash_console_flush 195*91f16700Schasinglulu 196*91f16700Schasinglulu /* ----------------------------------------------------- 197*91f16700Schasinglulu * Placeholder function which should be redefined by 198*91f16700Schasinglulu * each platform. This function is allowed to use 199*91f16700Schasinglulu * registers x0 - x17. 200*91f16700Schasinglulu * ----------------------------------------------------- 201*91f16700Schasinglulu */ 202*91f16700Schasinglulu 203*91f16700Schasinglulufunc plat_disable_acp 204*91f16700Schasinglulu /*TBD-STINGRAY*/ 205*91f16700Schasinglulu ret 206*91f16700Schasingluluendfunc plat_disable_acp 207*91f16700Schasinglulu 208*91f16700Schasinglulu /* ----------------------------------------------------- 209*91f16700Schasinglulu * unsigned int plat_is_my_cpu_primary (void); 210*91f16700Schasinglulu * 211*91f16700Schasinglulu * Find out whether the current cpu is the primary 212*91f16700Schasinglulu * cpu (applicable only after a cold boot) 213*91f16700Schasinglulu * ----------------------------------------------------- 214*91f16700Schasinglulu */ 215*91f16700Schasinglulufunc plat_is_my_cpu_primary 216*91f16700Schasinglulu mrs x0, mpidr_el1 217*91f16700Schasinglulu b platform_is_primary_cpu 218*91f16700Schasingluluendfunc plat_is_my_cpu_primary 219*91f16700Schasinglulu 220*91f16700Schasinglulu /* ----------------------------------------------------- 221*91f16700Schasinglulu * unsigned int plat_my_core_pos(void) 222*91f16700Schasinglulu * This function uses the plat_brcm_calc_core_pos() 223*91f16700Schasinglulu * definition to get the index of the calling CPU. 224*91f16700Schasinglulu * ----------------------------------------------------- 225*91f16700Schasinglulu */ 226*91f16700Schasinglulufunc plat_my_core_pos 227*91f16700Schasinglulu mrs x0, mpidr_el1 228*91f16700Schasinglulu b plat_brcm_calc_core_pos 229*91f16700Schasingluluendfunc plat_my_core_pos 230*91f16700Schasinglulu 231*91f16700Schasinglulu /* ----------------------------------------------------- 232*91f16700Schasinglulu * unsigned int platform_is_primary_cpu (void); 233*91f16700Schasinglulu * 234*91f16700Schasinglulu * Find out whether the current cpu is the primary 235*91f16700Schasinglulu * cpu (applicable only after a cold boot) 236*91f16700Schasinglulu * ----------------------------------------------------- 237*91f16700Schasinglulu */ 238*91f16700Schasinglulufunc platform_is_primary_cpu 239*91f16700Schasinglulu mov x9, x30 240*91f16700Schasinglulu bl plat_my_core_pos 241*91f16700Schasinglulu cmp x0, #PRIMARY_CPU 242*91f16700Schasinglulu cset x0, eq 243*91f16700Schasinglulu ret x9 244*91f16700Schasingluluendfunc platform_is_primary_cpu 245*91f16700Schasinglulu 246*91f16700Schasinglulu /* ----------------------------------------------------- 247*91f16700Schasinglulu * unsigned int plat_brcm_calc_core_pos(uint64_t mpidr) 248*91f16700Schasinglulu * Helper function to calculate the core position. 249*91f16700Schasinglulu * With this function: CorePos = (ClusterId * 4) + 250*91f16700Schasinglulu * CoreId 251*91f16700Schasinglulu * ----------------------------------------------------- 252*91f16700Schasinglulu */ 253*91f16700Schasinglulufunc plat_brcm_calc_core_pos 254*91f16700Schasinglulu and x1, x0, #MPIDR_CPU_MASK 255*91f16700Schasinglulu and x0, x0, #MPIDR_CLUSTER_MASK 256*91f16700Schasinglulu add x0, x1, x0, LSR #7 257*91f16700Schasinglulu ret 258*91f16700Schasingluluendfunc plat_brcm_calc_core_pos 259*91f16700Schasinglulu 260*91f16700Schasinglulufunc plat_get_my_entrypoint 261*91f16700Schasinglulu mrs x0, mpidr_el1 262*91f16700Schasinglulu b platform_get_entrypoint 263*91f16700Schasingluluendfunc plat_get_my_entrypoint 264