blob: d9b3df68d7a0f27888bbc2618539126da09aa9a3 [file] [log] [blame]
Nariman Poushinc703f902018-03-07 10:29:57 +00001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <platform_def.h>
10#include <cortex_a75.h>
11#include <cortex_a55.h>
12
13 .globl plat_arm_calc_core_pos
14 .globl plat_reset_handler
15
16 /* ---------------------------------------------------------------------
17 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
18 *
19 * Function to calculate the core position on FVP.
20 *
21 * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) +
22 * (CPUId * MAX_PE_PER_CPU) +
23 * ThreadId
24 *
25 * which can be simplified as:
26 *
27 * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU)
28 * + ThreadId
29 * ---------------------------------------------------------------------
30 */
31func plat_arm_calc_core_pos
32 /*
33 * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
34 * look as if in a multi-threaded implementation.
35 */
36 tst x0, #MPIDR_MT_MASK
37 lsr x3, x0, #MPIDR_AFFINITY_BITS
38 csel x3, x3, x0, eq
39
40 /* Extract individual affinity fields from MPIDR */
41 ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
42 ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
43 ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
44
45 /* Compute linear position */
46 mov x4, #PLAT_MAX_CPUS_PER_CLUSTER
47 madd x1, x2, x4, x1
48 mov x5, #PLAT_MAX_PE_PER_CPU
49 madd x0, x1, x5, x0
50 ret
51endfunc plat_arm_calc_core_pos
52
53 /* ------------------------------------------------------
54 * Helper macro that reads the part number of the current
55 * CPU and jumps to the given label if it matches the CPU
56 * MIDR provided.
57 *
58 * Clobbers x0.
59 * -----------------------------------------------------
60 */
61 .macro jump_if_cpu_midr _cpu_midr, _label
62 mrs x0, midr_el1
63 ubfx x0, x0, MIDR_PN_SHIFT, #12
64 cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
65 b.eq \_label
66 .endm
67
68 /* -----------------------------------------------------
69 * void plat_reset_handler(void);
70 *
71 * Determine the CPU MIDR and disable power down bit for
72 * that CPU.
73 * -----------------------------------------------------
74 */
75func plat_reset_handler
76 jump_if_cpu_midr CORTEX_A75_MIDR, A75
77 jump_if_cpu_midr CORTEX_A55_MIDR, A55
78 ret
79
80 /* -----------------------------------------------------
81 * Disable CPU power down bit in power control register
82 * -----------------------------------------------------
83 */
84A75:
85 mrs x0, CORTEX_A75_CPUPWRCTLR_EL1
86 bic x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
87 msr CORTEX_A75_CPUPWRCTLR_EL1, x0
88 isb
89 ret
90A55:
91 mrs x0, CORTEX_A55_CPUPWRCTLR_EL1
92 bic x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
93 msr CORTEX_A55_CPUPWRCTLR_EL1, x0
94 isb
95 ret
96endfunc plat_reset_handler