blob: 64d21b49c863c61500353cdb52e38c5652c5852e [file] [log] [blame]
Varun Wadekar08438e22015-05-19 16:48:04 +05301/*
Ambroise Vincent544c0922019-05-29 14:04:16 +01002 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
Varun Wadekarb1481cf2018-06-07 11:21:02 -07003 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
Varun Wadekar08438e22015-05-19 16:48:04 +05304 *
dp-arm82cb2c12017-05-03 09:38:09 +01005 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekar08438e22015-05-19 16:48:04 +05306 */
Varun Wadekara69a1112019-11-18 11:55:02 -08007
Varun Wadekar08438e22015-05-19 16:48:04 +05308#include <arch.h>
9#include <asm_macros.S>
10#include <assert_macros.S>
Isla Mitchellee1ebbd2017-07-14 10:46:32 +010011#include <cortex_a57.h>
Varun Wadekara69a1112019-11-18 11:55:02 -080012#include <cpu_macros.S>
13
Varun Wadekar11bd24b2016-04-26 11:38:38 -070014#include <platform_def.h>
Varun Wadekar08438e22015-05-19 16:48:04 +053015#include <tegra_def.h>
Harvey Hsiehc195fec2017-04-24 19:35:51 +080016#include <tegra_platform.h>
Varun Wadekar08438e22015-05-19 16:48:04 +053017
Varun Wadekar0cd61382015-09-22 13:33:56 +053018#define MIDR_PN_CORTEX_A57 0xD07
19
20/*******************************************************************************
21 * Implementation defined ACTLR_EL3 bit definitions
22 ******************************************************************************/
Varun Wadekarb1481cf2018-06-07 11:21:02 -070023#define ACTLR_ELx_L2ACTLR_BIT (U(1) << 6)
24#define ACTLR_ELx_L2ECTLR_BIT (U(1) << 5)
25#define ACTLR_ELx_L2CTLR_BIT (U(1) << 4)
26#define ACTLR_ELx_CPUECTLR_BIT (U(1) << 1)
27#define ACTLR_ELx_CPUACTLR_BIT (U(1) << 0)
28#define ACTLR_ELx_ENABLE_ALL_ACCESS (ACTLR_ELx_L2ACTLR_BIT | \
29 ACTLR_ELx_L2ECTLR_BIT | \
30 ACTLR_ELx_L2CTLR_BIT | \
31 ACTLR_ELx_CPUECTLR_BIT | \
32 ACTLR_ELx_CPUACTLR_BIT)
Varun Wadekar0cd61382015-09-22 13:33:56 +053033
Varun Wadekar08438e22015-05-19 16:48:04 +053034 /* Global functions */
Varun Wadekar71cb26e2015-08-07 10:03:00 +053035 .globl plat_is_my_cpu_primary
36 .globl plat_my_core_pos
37 .globl plat_get_my_entrypoint
Varun Wadekar08438e22015-05-19 16:48:04 +053038 .globl plat_secondary_cold_boot_setup
39 .globl platform_mem_init
40 .globl plat_crash_console_init
41 .globl plat_crash_console_putc
Antonio Nino Diaz9c675b32018-10-17 15:29:34 +010042 .globl plat_crash_console_flush
Varun Wadekar0ac1bf72018-11-27 15:47:26 -080043 .weak plat_core_pos_by_mpidr
Varun Wadekar08438e22015-05-19 16:48:04 +053044 .globl tegra_secure_entrypoint
45 .globl plat_reset_handler
46
47 /* Global variables */
Varun Wadekar71cb26e2015-08-07 10:03:00 +053048 .globl tegra_sec_entry_point
Varun Wadekar08438e22015-05-19 16:48:04 +053049 .globl ns_image_entrypoint
50 .globl tegra_bl31_phys_base
Varun Wadekare1084212015-10-29 10:37:28 +053051 .globl tegra_console_base
Varun Wadekar08438e22015-05-19 16:48:04 +053052
53 /* ---------------------
54 * Common CPU init code
55 * ---------------------
56 */
57.macro cpu_init_common
58
Varun Wadekar0cd61382015-09-22 13:33:56 +053059 /* ------------------------------------------------
Varun Wadekar018b8482016-05-12 13:43:33 -070060 * We enable procesor retention, L2/CPUECTLR NS
61 * access and ECC/Parity protection for A57 CPUs
Varun Wadekar0cd61382015-09-22 13:33:56 +053062 * ------------------------------------------------
63 */
64 mrs x0, midr_el1
65 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT)
66 and x0, x0, x1
67 lsr x0, x0, #MIDR_PN_SHIFT
68 cmp x0, #MIDR_PN_CORTEX_A57
69 b.ne 1f
70
Varun Wadekarb42192b2015-08-21 15:56:02 +053071 /* ---------------------------
72 * Enable processor retention
73 * ---------------------------
Varun Wadekar018b8482016-05-12 13:43:33 -070074 */
Varun Wadekarfb7d32e2017-06-05 14:54:46 -070075 mrs x0, CORTEX_A57_L2ECTLR_EL1
76 mov x1, #RETENTION_ENTRY_TICKS_512
77 bic x0, x0, #CORTEX_A57_L2ECTLR_RET_CTRL_MASK
Varun Wadekarb42192b2015-08-21 15:56:02 +053078 orr x0, x0, x1
Varun Wadekarfb7d32e2017-06-05 14:54:46 -070079 msr CORTEX_A57_L2ECTLR_EL1, x0
Varun Wadekarb42192b2015-08-21 15:56:02 +053080 isb
Varun Wadekarb42192b2015-08-21 15:56:02 +053081
Varun Wadekarfb7d32e2017-06-05 14:54:46 -070082 mrs x0, CORTEX_A57_ECTLR_EL1
83 mov x1, #RETENTION_ENTRY_TICKS_512
84 bic x0, x0, #CORTEX_A57_ECTLR_CPU_RET_CTRL_MASK
Varun Wadekarb42192b2015-08-21 15:56:02 +053085 orr x0, x0, x1
Varun Wadekarfb7d32e2017-06-05 14:54:46 -070086 msr CORTEX_A57_ECTLR_EL1, x0
Varun Wadekarb42192b2015-08-21 15:56:02 +053087 isb
Varun Wadekarb42192b2015-08-21 15:56:02 +053088
Varun Wadekar08438e22015-05-19 16:48:04 +053089 /* -------------------------------------------------------
90 * Enable L2 and CPU ECTLR RW access from non-secure world
91 * -------------------------------------------------------
Varun Wadekar018b8482016-05-12 13:43:33 -070092 */
Steven Kao75516c32017-06-14 14:02:23 +080093 mrs x0, actlr_el3
Varun Wadekarb1481cf2018-06-07 11:21:02 -070094 mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
Steven Kao75516c32017-06-14 14:02:23 +080095 orr x0, x0, x1
Varun Wadekar08438e22015-05-19 16:48:04 +053096 msr actlr_el3, x0
Steven Kao75516c32017-06-14 14:02:23 +080097 mrs x0, actlr_el2
Varun Wadekarb1481cf2018-06-07 11:21:02 -070098 mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
Steven Kao75516c32017-06-14 14:02:23 +080099 orr x0, x0, x1
Varun Wadekar08438e22015-05-19 16:48:04 +0530100 msr actlr_el2, x0
101 isb
Varun Wadekar08438e22015-05-19 16:48:04 +0530102
103 /* --------------------------------
104 * Enable the cycle count register
105 * --------------------------------
106 */
Varun Wadekar0cd61382015-09-22 13:33:56 +05301071: mrs x0, pmcr_el0
Varun Wadekar08438e22015-05-19 16:48:04 +0530108 ubfx x0, x0, #11, #5 // read PMCR.N field
109 mov x1, #1
110 lsl x0, x1, x0
111 sub x0, x0, #1 // mask of event counters
112 orr x0, x0, #0x80000000 // disable overflow intrs
113 msr pmintenclr_el1, x0
114 msr pmuserenr_el0, x1 // enable user mode access
115
116 /* ----------------------------------------------------------------
117 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
118 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
119 * registers from EL0.
120 * ----------------------------------------------------------------
121 */
122 mrs x0, cntkctl_el1
123 orr x0, x0, #EL0VCTEN_BIT
124 msr cntkctl_el1, x0
125.endm
126
127 /* -----------------------------------------------------
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530128 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekar08438e22015-05-19 16:48:04 +0530129 *
130 * This function checks if this is the Primary CPU
131 * -----------------------------------------------------
132 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530133func plat_is_my_cpu_primary
134 mrs x0, mpidr_el1
Varun Wadekar08438e22015-05-19 16:48:04 +0530135 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
136 cmp x0, #TEGRA_PRIMARY_CPU
137 cset x0, eq
138 ret
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530139endfunc plat_is_my_cpu_primary
Varun Wadekar08438e22015-05-19 16:48:04 +0530140
Varun Wadekarb627d082017-08-23 16:02:06 -0700141 /* ----------------------------------------------------------
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530142 * unsigned int plat_my_core_pos(void);
Varun Wadekar08438e22015-05-19 16:48:04 +0530143 *
Varun Wadekarb627d082017-08-23 16:02:06 -0700144 * result: CorePos = CoreId + (ClusterId * cpus per cluster)
Kalyani Chidambaram3bab03e2018-10-03 17:00:17 -0700145 * Registers clobbered: x0, x8
Varun Wadekarb627d082017-08-23 16:02:06 -0700146 * ----------------------------------------------------------
Varun Wadekar08438e22015-05-19 16:48:04 +0530147 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530148func plat_my_core_pos
Kalyani Chidambaram3bab03e2018-10-03 17:00:17 -0700149 mov x8, x30
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530150 mrs x0, mpidr_el1
Kalyani Chidambaram3bab03e2018-10-03 17:00:17 -0700151 bl plat_core_pos_by_mpidr
152 ret x8
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530153endfunc plat_my_core_pos
154
155 /* -----------------------------------------------------
156 * unsigned long plat_get_my_entrypoint (void);
157 *
158 * Main job of this routine is to distinguish between
159 * a cold and warm boot. If the tegra_sec_entry_point for
160 * this CPU is present, then it's a warm boot.
161 *
162 * -----------------------------------------------------
163 */
164func plat_get_my_entrypoint
165 adr x1, tegra_sec_entry_point
166 ldr x0, [x1]
167 ret
168endfunc plat_get_my_entrypoint
Varun Wadekar08438e22015-05-19 16:48:04 +0530169
170 /* -----------------------------------------------------
171 * void plat_secondary_cold_boot_setup (void);
172 *
173 * This function performs any platform specific actions
174 * needed for a secondary cpu after a cold reset. Right
175 * now this is a stub function.
176 * -----------------------------------------------------
177 */
178func plat_secondary_cold_boot_setup
179 mov x0, #0
180 ret
181endfunc plat_secondary_cold_boot_setup
182
Varun Wadekar08438e22015-05-19 16:48:04 +0530183 /* --------------------------------------------------------
184 * void platform_mem_init (void);
185 *
186 * Any memory init, relocation to be done before the
187 * platform boots. Called very early in the boot process.
188 * --------------------------------------------------------
189 */
190func platform_mem_init
191 mov x0, #0
192 ret
193endfunc platform_mem_init
194
Varun Wadekar08438e22015-05-19 16:48:04 +0530195 /* ---------------------------------------------------
196 * Function to handle a platform reset and store
197 * input parameters passed by BL2.
198 * ---------------------------------------------------
199 */
200func plat_reset_handler
201
Varun Wadekar939dcf22016-03-24 15:34:24 -0700202 /* ----------------------------------------------------
203 * Verify if we are running from BL31_BASE address
204 * ----------------------------------------------------
205 */
206 adr x18, bl31_entrypoint
207 mov x17, #BL31_BASE
208 cmp x18, x17
209 b.eq 1f
210
211 /* ----------------------------------------------------
212 * Copy the entire BL31 code to BL31_BASE if we are not
213 * running from it already
214 * ----------------------------------------------------
215 */
216 mov x0, x17
217 mov x1, x18
218 mov x2, #BL31_SIZE
219_loop16:
220 cmp x2, #16
Douglas Raillard768baf62017-03-20 10:38:29 +0000221 b.lo _loop1
Varun Wadekar939dcf22016-03-24 15:34:24 -0700222 ldp x3, x4, [x1], #16
223 stp x3, x4, [x0], #16
224 sub x2, x2, #16
225 b _loop16
226 /* copy byte per byte */
227_loop1:
228 cbz x2, _end
229 ldrb w3, [x1], #1
230 strb w3, [x0], #1
231 subs x2, x2, #1
232 b.ne _loop1
233
234 /* ----------------------------------------------------
235 * Jump to BL31_BASE and start execution again
236 * ----------------------------------------------------
237 */
238_end: mov x0, x20
239 mov x1, x21
240 br x17
2411:
242
Varun Wadekar08438e22015-05-19 16:48:04 +0530243 /* -----------------------------------
244 * derive and save the phys_base addr
245 * -----------------------------------
246 */
247 adr x17, tegra_bl31_phys_base
248 ldr x18, [x17]
249 cbnz x18, 1f
250 adr x18, bl31_entrypoint
251 str x18, [x17]
252
2531: cpu_init_common
254
255 ret
256endfunc plat_reset_handler
257
Varun Wadekar0ac1bf72018-11-27 15:47:26 -0800258 /* ------------------------------------------------------
259 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
260 *
261 * This function implements a part of the critical
262 * interface between the psci generic layer and the
263 * platform that allows the former to query the platform
264 * to convert an MPIDR to a unique linear index. An error
265 * code (-1) is returned in case the MPIDR is invalid.
266 *
267 * Clobbers: x0-x3
268 * ------------------------------------------------------
269 */
270func plat_core_pos_by_mpidr
271 lsr x1, x0, #MPIDR_AFF0_SHIFT
272 and x1, x1, #MPIDR_AFFLVL_MASK /* core id */
273 lsr x2, x0, #MPIDR_AFF1_SHIFT
274 and x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */
275
276 /* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */
277 mov x0, #-1
278 cmp x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1)
279 b.gt 1f
280
281 /* cluster_id >= PLATFORM_CLUSTER_COUNT */
282 cmp x2, #(PLATFORM_CLUSTER_COUNT - 1)
283 b.gt 1f
284
285 /* CorePos = CoreId + (ClusterId * cpus per cluster) */
286 mov x3, #PLATFORM_MAX_CPUS_PER_CLUSTER
287 mul x3, x3, x2
288 add x0, x1, x3
289
2901:
291 ret
292endfunc plat_core_pos_by_mpidr
293
Varun Wadekar08438e22015-05-19 16:48:04 +0530294 /* ----------------------------------------
295 * Secure entrypoint function for CPU boot
296 * ----------------------------------------
297 */
Julius Werner64726e62017-08-01 15:16:36 -0700298func tegra_secure_entrypoint _align=6
Varun Wadekar08438e22015-05-19 16:48:04 +0530299
300#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
301
Harvey Hsiehc195fec2017-04-24 19:35:51 +0800302 /* --------------------------------------------------------
303 * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
304 * --------------------------------------------------------
305 */
306 mov x0, #TEGRA_MISC_BASE
307 add x0, x0, #HARDWARE_REVISION_OFFSET
308 ldr w1, [x0]
309 lsr w1, w1, #CHIP_ID_SHIFT
310 and w1, w1, #CHIP_ID_MASK
311 cmp w1, #TEGRA_CHIPID_TEGRA21 /* T210? */
312 b.ne 2f
313 ldr w1, [x0]
314 lsr w1, w1, #MAJOR_VERSION_SHIFT
315 and w1, w1, #MAJOR_VERSION_MASK
316 cmp w1, #0x02 /* T210 B01? */
317 b.eq 2f
318
Varun Wadekar08438e22015-05-19 16:48:04 +0530319 /* -------------------------------------------------------
320 * Invalidate BTB along with I$ to remove any stale
321 * entries from the branch predictor array.
322 * -------------------------------------------------------
323 */
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100324 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekar08438e22015-05-19 16:48:04 +0530325 orr x0, x0, #1
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100326 msr CORTEX_A57_CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
Varun Wadekar08438e22015-05-19 16:48:04 +0530327 dsb sy
328 isb
329 ic iallu /* actual invalidate */
330 dsb sy
331 isb
332
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100333 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekar08438e22015-05-19 16:48:04 +0530334 bic x0, x0, #1
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100335 msr CORTEX_A57_CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
Varun Wadekar08438e22015-05-19 16:48:04 +0530336 dsb sy
337 isb
338
339 .rept 7
340 nop /* wait */
341 .endr
342
343 /* -----------------------------------------------
344 * Extract OSLK bit and check if it is '1'. This
345 * bit remains '0' for A53 on warm-resets. If '1',
346 * turn off regional clock gating and request warm
347 * reset.
348 * -----------------------------------------------
349 */
350 mrs x0, oslsr_el1
351 and x0, x0, #2
352 mrs x1, mpidr_el1
353 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
354 b.eq restore_oslock
355 mov x0, xzr
356 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
357 mov x3, #3
358 movz x4, #0x8000, lsl #48
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100359 msr CORTEX_A57_CPUACTLR_EL1, x4 /* turn off RCG */
Varun Wadekar08438e22015-05-19 16:48:04 +0530360 isb
361 msr rmr_el3, x3 /* request warm reset */
362 isb
363 dsb sy
3641: wfi
365 b 1b
366
367 /* --------------------------------------------------
368 * These nops are here so that speculative execution
369 * won't harm us before we are done with warm reset.
370 * --------------------------------------------------
371 */
372 .rept 65
373 nop
374 .endr
Harvey Hsiehc195fec2017-04-24 19:35:51 +08003752:
Varun Wadekar08438e22015-05-19 16:48:04 +0530376 /* --------------------------------------------------
377 * Do not insert instructions here
378 * --------------------------------------------------
379 */
380#endif
381
382 /* --------------------------------------------------
383 * Restore OS Lock bit
384 * --------------------------------------------------
385 */
386restore_oslock:
387 mov x0, #1
388 msr oslar_el1, x0
389
Varun Wadekar08438e22015-05-19 16:48:04 +0530390 /* --------------------------------------------------
391 * Get secure world's entry point and jump to it
392 * --------------------------------------------------
393 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530394 bl plat_get_my_entrypoint
Varun Wadekar08438e22015-05-19 16:48:04 +0530395 br x0
396endfunc tegra_secure_entrypoint
397
398 .data
399 .align 3
400
401 /* --------------------------------------------------
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530402 * CPU Secure entry point - resume from suspend
Varun Wadekar08438e22015-05-19 16:48:04 +0530403 * --------------------------------------------------
404 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530405tegra_sec_entry_point:
Varun Wadekar08438e22015-05-19 16:48:04 +0530406 .quad 0
Varun Wadekar08438e22015-05-19 16:48:04 +0530407
408 /* --------------------------------------------------
409 * NS world's cold boot entry point
410 * --------------------------------------------------
411 */
412ns_image_entrypoint:
413 .quad 0
414
415 /* --------------------------------------------------
416 * BL31's physical base address
417 * --------------------------------------------------
418 */
419tegra_bl31_phys_base:
420 .quad 0
Varun Wadekare1084212015-10-29 10:37:28 +0530421
422 /* --------------------------------------------------
423 * UART controller base for console init
424 * --------------------------------------------------
425 */
426tegra_console_base:
427 .quad 0