xref: /arm-trusted-firmware/plat/ti/k3/common/k3_helpers.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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