blob: d6f63ede9112c10d5840ba6b661b1cf920f4a235 [file] [log] [blame]
Nariman Poushin0ece80f2018-02-26 06:52:04 +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>
Chandni Cherukuri82718852018-08-02 12:29:07 +053010#include <cortex_a75.h>
Nariman Poushin0ece80f2018-02-26 06:52:04 +000011
12 .globl plat_is_my_cpu_primary
13 .globl plat_arm_calc_core_pos
Chandni Cherukuri82718852018-08-02 12:29:07 +053014 .globl plat_reset_handler
Nariman Poushin0ece80f2018-02-26 06:52:04 +000015
16 /* -----------------------------------------------------
17 * unsigned int plat_is_my_cpu_primary (void);
18 *
19 * Find out whether the current cpu is the primary
20 * cpu (applicable only after a cold boot)
21 * -----------------------------------------------------
22 */
23func plat_is_my_cpu_primary
24 mov x9, x30
25 bl plat_my_core_pos
26 ldr x1, =SGI_BOOT_CFG_ADDR
27 ldr x1, [x1]
28 ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \
29 #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
30 cmp x0, x1
31 cset w0, eq
32 ret x9
33endfunc plat_is_my_cpu_primary
34
35 /* -----------------------------------------------------
Vishwanatha HG64f0b6f2018-05-08 17:15:37 +053036 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
37 *
38 * Helper function to calculate the core position.
39 * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
40 * (CPUId * CSS_SGI_MAX_PE_PER_CPU) +
41 * ThreadId
42 *
43 * which can be simplified as:
44 *
45 * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) *
46 * CSS_SGI_MAX_PE_PER_CPU) + ThreadId
47 * ------------------------------------------------------
48 */
49
Nariman Poushin0ece80f2018-02-26 06:52:04 +000050func plat_arm_calc_core_pos
Vishwanatha HG64f0b6f2018-05-08 17:15:37 +053051 mov x3, x0
52
53 /*
54 * The MT bit in MPIDR is always set for SGI platforms
55 * and the affinity level 0 corresponds to thread affinity level.
56 */
57
58 /* Extract individual affinity fields from MPIDR */
59 ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
60 ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
61 ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
62
63 /* Compute linear position */
64 mov x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER
65 madd x1, x2, x4, x1
66 mov x5, #CSS_SGI_MAX_PE_PER_CPU
67 madd x0, x1, x5, x0
Nariman Poushin0ece80f2018-02-26 06:52:04 +000068 ret
69endfunc plat_arm_calc_core_pos
Chandni Cherukuri82718852018-08-02 12:29:07 +053070
71 /* ------------------------------------------------------
72 * Helper macro that reads the part number of the current
73 * CPU and jumps to the given label if it matches the CPU
74 * MIDR provided.
75 *
76 * Clobbers x0.
77 * -----------------------------------------------------
78 */
79 .macro jump_if_cpu_midr _cpu_midr, _label
80 mrs x0, midr_el1
81 ubfx x0, x0, MIDR_PN_SHIFT, #12
82 cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
83 b.eq \_label
84 .endm
85
86 /* -----------------------------------------------------
87 * void plat_reset_handler(void);
88 *
89 * Determine the CPU MIDR and disable power down bit for
90 * that CPU.
91 * -----------------------------------------------------
92 */
93func plat_reset_handler
94 jump_if_cpu_midr CORTEX_A75_MIDR, A75
95 ret
96
97 /* -----------------------------------------------------
98 * Disable CPU power down bit in power control register
99 * -----------------------------------------------------
100 */
101A75:
102 mrs x0, CORTEX_A75_CPUPWRCTLR_EL1
103 bic x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
104 msr CORTEX_A75_CPUPWRCTLR_EL1, x0
105 isb
106 ret
107endfunc plat_reset_handler