1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. 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 <cortex_a72.h> 10*91f16700Schasinglulu#include <cpu_macros.S> 11*91f16700Schasinglulu#include <platform_def.h> 12*91f16700Schasinglulu 13*91f16700Schasinglulu#define K3_BOOT_REASON_COLD_RESET 0x1 14*91f16700Schasinglulu 15*91f16700Schasinglulu /* ------------------------------------------------------------------ 16*91f16700Schasinglulu * uintptr_t plat_get_my_entrypoint(void) 17*91f16700Schasinglulu * ------------------------------------------------------------------ 18*91f16700Schasinglulu * 19*91f16700Schasinglulu * This function is called with the called with the MMU and caches 20*91f16700Schasinglulu * disabled (SCTLR_EL3.M = 0 and SCTLR_EL3.C = 0). The function is 21*91f16700Schasinglulu * responsible for distinguishing between a warm and cold reset for the 22*91f16700Schasinglulu * current CPU using platform-specific means. If it's a warm reset, 23*91f16700Schasinglulu * then it returns the warm reset entrypoint point provided to 24*91f16700Schasinglulu * plat_setup_psci_ops() during BL31 initialization. If it's a cold 25*91f16700Schasinglulu * reset then this function must return zero. 26*91f16700Schasinglulu * 27*91f16700Schasinglulu * This function does not follow the Procedure Call Standard used by 28*91f16700Schasinglulu * the Application Binary Interface for the ARM 64-bit architecture. 29*91f16700Schasinglulu * The caller should not assume that callee saved registers are 30*91f16700Schasinglulu * preserved across a call to this function. 31*91f16700Schasinglulu */ 32*91f16700Schasinglulu .globl plat_get_my_entrypoint 33*91f16700Schasinglulufunc plat_get_my_entrypoint 34*91f16700Schasinglulu ldr x0, k3_boot_reason_data_store 35*91f16700Schasinglulu cmp x0, #K3_BOOT_REASON_COLD_RESET 36*91f16700Schasinglulu 37*91f16700Schasinglulu /* We ONLY support cold boot at this point */ 38*91f16700Schasinglulu bne plat_unsupported_boot 39*91f16700Schasinglulu mov x0, #0 40*91f16700Schasinglulu ret 41*91f16700Schasinglulu 42*91f16700Schasinglulu /* 43*91f16700Schasinglulu * We self manage our boot reason. 44*91f16700Schasinglulu * At load time, we have just a default reason - which is cold reset 45*91f16700Schasinglulu */ 46*91f16700Schasingluluk3_boot_reason_data_store: 47*91f16700Schasinglulu .word K3_BOOT_REASON_COLD_RESET 48*91f16700Schasinglulu 49*91f16700Schasingluluplat_unsupported_boot: 50*91f16700Schasinglulu b plat_unsupported_boot 51*91f16700Schasinglulu 52*91f16700Schasingluluendfunc plat_get_my_entrypoint 53*91f16700Schasinglulu 54*91f16700Schasinglulu /* ------------------------------------------------------------------ 55*91f16700Schasinglulu * unsigned int plat_my_core_pos(void) 56*91f16700Schasinglulu * ------------------------------------------------------------------ 57*91f16700Schasinglulu * 58*91f16700Schasinglulu * This function returns the index of the calling CPU which is used as a 59*91f16700Schasinglulu * CPU-specific linear index into blocks of memory (for example while 60*91f16700Schasinglulu * allocating per-CPU stacks). This function will be invoked very early 61*91f16700Schasinglulu * in the initialization sequence which mandates that this function 62*91f16700Schasinglulu * should be implemented in assembly and should not rely on the 63*91f16700Schasinglulu * avalability of a C runtime environment. This function can clobber x0 64*91f16700Schasinglulu * - x8 and must preserve x9 - x29. 65*91f16700Schasinglulu * 66*91f16700Schasinglulu * This function plays a crucial role in the power domain topology 67*91f16700Schasinglulu * framework in PSCI and details of this can be found in Power Domain 68*91f16700Schasinglulu * Topology Design. 69*91f16700Schasinglulu */ 70*91f16700Schasinglulu .globl plat_my_core_pos 71*91f16700Schasinglulufunc plat_my_core_pos 72*91f16700Schasinglulu mrs x0, MPIDR_EL1 73*91f16700Schasinglulu 74*91f16700Schasinglulu and x1, x0, #MPIDR_CLUSTER_MASK 75*91f16700Schasinglulu lsr x1, x1, #MPIDR_AFF1_SHIFT 76*91f16700Schasinglulu and x0, x0, #MPIDR_CPU_MASK 77*91f16700Schasinglulu 78*91f16700Schasinglulu cmp x1, 0 79*91f16700Schasinglulu b.eq out 80*91f16700Schasinglulu add x0, x0, #K3_CLUSTER0_CORE_COUNT 81*91f16700Schasinglulu 82*91f16700Schasinglulu cmp x1, 1 83*91f16700Schasinglulu b.eq out 84*91f16700Schasinglulu add x0, x0, #K3_CLUSTER1_CORE_COUNT 85*91f16700Schasinglulu 86*91f16700Schasinglulu cmp x1, 2 87*91f16700Schasinglulu b.eq out 88*91f16700Schasinglulu add x0, x0, #K3_CLUSTER2_CORE_COUNT 89*91f16700Schasinglulu 90*91f16700Schasingluluout: 91*91f16700Schasinglulu ret 92*91f16700Schasingluluendfunc plat_my_core_pos 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* -------------------------------------------------------------------- 95*91f16700Schasinglulu * This handler does the following: 96*91f16700Schasinglulu * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72 97*91f16700Schasinglulu * -------------------------------------------------------------------- 98*91f16700Schasinglulu */ 99*91f16700Schasinglulu .globl plat_reset_handler 100*91f16700Schasinglulufunc plat_reset_handler 101*91f16700Schasinglulu /* Only on Cortex-A72 */ 102*91f16700Schasinglulu jump_if_cpu_midr CORTEX_A72_MIDR, a72 103*91f16700Schasinglulu ret 104*91f16700Schasinglulu 105*91f16700Schasinglulu /* Cortex-A72 specific settings */ 106*91f16700Schasinglulua72: 107*91f16700Schasinglulu mrs x0, CORTEX_A72_L2CTLR_EL1 108*91f16700Schasinglulu#if K3_DATA_RAM_4_LATENCY 109*91f16700Schasinglulu /* Set L2 cache data RAM latency to 4 cycles */ 110*91f16700Schasinglulu orr x0, x0, #(CORTEX_A72_L2_DATA_RAM_LATENCY_4_CYCLES << \ 111*91f16700Schasinglulu CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) 112*91f16700Schasinglulu#else 113*91f16700Schasinglulu /* Set L2 cache data RAM latency to 3 cycles */ 114*91f16700Schasinglulu orr x0, x0, #(CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << \ 115*91f16700Schasinglulu CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) 116*91f16700Schasinglulu#endif 117*91f16700Schasinglulu /* Enable L2 ECC and parity with inline data */ 118*91f16700Schasinglulu orr x0, x0, #CORTEX_A72_L2CTLR_EL1_ECC_AND_PARITY_ENABLE 119*91f16700Schasinglulu orr x0, x0, #CORTEX_A72_L2CTLR_EL1_DATA_INLINE_ECC_ENABLE 120*91f16700Schasinglulu msr CORTEX_A72_L2CTLR_EL1, x0 121*91f16700Schasinglulu 122*91f16700Schasinglulu mrs x0, CORTEX_A72_L2ACTLR_EL1 123*91f16700Schasinglulu /* Enable L2 UniqueClean evictions with data */ 124*91f16700Schasinglulu orr x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN 125*91f16700Schasinglulu msr CORTEX_A72_L2ACTLR_EL1, x0 126*91f16700Schasinglulu 127*91f16700Schasinglulu#if K3_EXCLUSIVE_SNOOP_DELAY 128*91f16700Schasinglulu mrs x0, CORTEX_A72_CPUACTLR_EL1 129*91f16700Schasinglulu /* Set Snoop-delayed exclusive handling */ 130*91f16700Schasinglulu orr x0, x0, #CORTEX_A72_CPUACTLR_EL1_DELAY_EXCLUSIVE_SNOOP 131*91f16700Schasinglulu msr CORTEX_A72_CPUACTLR_EL1, x0 132*91f16700Schasinglulu#endif 133*91f16700Schasinglulu 134*91f16700Schasinglulu isb 135*91f16700Schasinglulu ret 136*91f16700Schasingluluendfunc plat_reset_handler 137*91f16700Schasinglulu 138*91f16700Schasinglulu /* --------------------------------------------- 139*91f16700Schasinglulu * int plat_crash_console_init(void) 140*91f16700Schasinglulu * Function to initialize the crash console 141*91f16700Schasinglulu * without a C Runtime to print crash report. 142*91f16700Schasinglulu * Clobber list : x0 - x4 143*91f16700Schasinglulu * --------------------------------------------- 144*91f16700Schasinglulu */ 145*91f16700Schasinglulu .globl plat_crash_console_init 146*91f16700Schasinglulufunc plat_crash_console_init 147*91f16700Schasinglulu mov_imm x0, CRASH_CONSOLE_BASE 148*91f16700Schasinglulu mov_imm x1, CRASH_CONSOLE_CLK 149*91f16700Schasinglulu mov_imm x2, CRASH_CONSOLE_BAUD_RATE 150*91f16700Schasinglulu mov w3, #0x0 151*91f16700Schasinglulu b console_16550_core_init 152*91f16700Schasingluluendfunc plat_crash_console_init 153*91f16700Schasinglulu 154*91f16700Schasinglulu /* --------------------------------------------- 155*91f16700Schasinglulu * int plat_crash_console_putc(void) 156*91f16700Schasinglulu * Function to print a character on the crash 157*91f16700Schasinglulu * console without a C Runtime. 158*91f16700Schasinglulu * Clobber list : x1, x2 159*91f16700Schasinglulu * --------------------------------------------- 160*91f16700Schasinglulu */ 161*91f16700Schasinglulu .globl plat_crash_console_putc 162*91f16700Schasinglulufunc plat_crash_console_putc 163*91f16700Schasinglulu mov_imm x1, CRASH_CONSOLE_BASE 164*91f16700Schasinglulu b console_16550_core_putc 165*91f16700Schasingluluendfunc plat_crash_console_putc 166*91f16700Schasinglulu 167*91f16700Schasinglulu /* --------------------------------------------- 168*91f16700Schasinglulu * void plat_crash_console_flush() 169*91f16700Schasinglulu * Function to force a write of all buffered 170*91f16700Schasinglulu * data that hasn't been output. 171*91f16700Schasinglulu * Out : void. 172*91f16700Schasinglulu * Clobber list : x0, x1 173*91f16700Schasinglulu * --------------------------------------------- 174*91f16700Schasinglulu */ 175*91f16700Schasinglulu .globl plat_crash_console_flush 176*91f16700Schasinglulufunc plat_crash_console_flush 177*91f16700Schasinglulu mov_imm x0, CRASH_CONSOLE_BASE 178*91f16700Schasinglulu b console_16550_core_flush 179*91f16700Schasingluluendfunc plat_crash_console_flush 180