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