1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/*
* This file is part of the coreboot project.
*
* Copyright 2015 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.
*/
#include <arch/asm.h>
#include <arch/cache_helpers.h>
#include <cpu/cortex_a57.h>
ENTRY(arm64_cpu_early_setup)
mrs x0, CPUECTLR_EL1
orr x0, x0, #(1 << SMPEN_SHIFT)
msr CPUECTLR_EL1, x0
isb
ret
ENDPROC(arm64_cpu_early_setup)
/*
* CPU power down sequence as per A57/A53/A72 TRM
*
* x0 - L2 flush by HW(0) or SW(1), if system/HW driven L2 flush is supported
*
*/
#if IS_ENABLED(CONFIG_ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT)
ENTRY(cortex_a57_cpu_power_down)
/* Store L2 cache flush request */
mov x13, x0
/* 1. Stop allocations to our data cache */
mrs x0, sctlr_el1
bic x0, x0, #1 << 2 // clear SCTLR.C
msr sctlr_el1, x0
isb
mrs x0, sctlr_el3
bic x0, x0, #1 << 2 // clear SCTLR.C
msr sctlr_el3, x0
isb
mrs x0, midr_el1
ubfx x0, x0, #4, #12
cmp x0, #CORTEX_A53_PN
b.eq a53
/* 2. Disable L2 prefetch */
mrs x0, CPUECTLR_EL1 // CPUECTLR_EL1
/* CPUECTLR[38], disable table walk descriptor access L2 prefetch */
orr x0, x0, #1 << 38
/*
* CPUECTLR[36:35] L2 instruction fetch prefetch distance
* 0 => disable instruction prefetch
*/
bic x0, x0, #3 << 35
/*
* CPUECTLR[33:32] L2 load/store prefetch distance
* 0 => disable instruction prefetch
*/
bic x0, x0, #3 << 32
msr CPUECTLR_EL1, x0
/* 3. ISB to ensure ectlr write is complete */
isb
/* 4. DSB to ensure prior prefetches are complete */
dsb sy
a53:
/* 5. Clean and invalidate L1 and L2 if X13 == 1 */
mov x0, #DCCISW
cmp x13, #1
bne 1f
bl flush_dcache_all
b 2f
1:
bl flush_dcache_louis
2:
/* 6. Leave coherency, clear SMPEN */
mrs x0, CPUECTLR_EL1
bic x0, x0, #(1 << SMPEN_SHIFT)
msr CPUECTLR_EL1, x0
/* 7. Set the DBGOSDLR.DLK, Double lock control bit */
mrs x0, osdlr_el1
orr x0, x0, #OSDLR_DBL_LOCK_BIT
msr osdlr_el1, x0
/*
* 9. Execute an ISB instruction to ensure that all of the
* System register changes from the previous steps have
* been committed.
*/
isb
/*
* 10. Execute a DSB instruction to ensure that all
* instruction cache, TLB, and branch predictor
* maintenance operations issued by any processor in the
* multiprocessor before the SMPEN bit was cleared have
* completed.
*/
dsb sy
/* 11. wfi */
3: wfi
/* we never return here */
b 3b
ENDPROC(cortex_a57_cpu_power_down)
#endif
|