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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
/*
* This file contains low level CPU setup functions.
* Kumar Gala <galak@kernel.crashing.org>
* Copyright 2009 Freescale Semiconductor, Inc.
*
* Based on cpu_setup_6xx code by
* Benjamin Herrenschmidt <benh@kernel.crashing.org>
*
* 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; either version
* 2 of the License, or (at your option) any later version.
*
*/
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
#include <asm/mmu-book3e.h>
#include <asm/asm-offsets.h>
_GLOBAL(__e500_icache_setup)
mfspr r0, SPRN_L1CSR1
andi. r3, r0, L1CSR1_ICE
bnelr /* Already enabled */
oris r0, r0, L1CSR1_CPE@h
ori r0, r0, (L1CSR1_ICFI | L1CSR1_ICLFR | L1CSR1_ICE)
mtspr SPRN_L1CSR1, r0 /* Enable I-Cache */
isync
blr
_GLOBAL(__e500_dcache_setup)
mfspr r0, SPRN_L1CSR0
andi. r3, r0, L1CSR0_DCE
bnelr /* Already enabled */
msync
isync
li r0, 0
mtspr SPRN_L1CSR0, r0 /* Disable */
msync
isync
li r0, (L1CSR0_DCFI | L1CSR0_CLFC)
mtspr SPRN_L1CSR0, r0 /* Invalidate */
isync
1: mfspr r0, SPRN_L1CSR0
andi. r3, r0, L1CSR0_CLFC
bne+ 1b /* Wait for lock bits reset */
oris r0, r0, L1CSR0_CPE@h
ori r0, r0, L1CSR0_DCE
msync
isync
mtspr SPRN_L1CSR0, r0 /* Enable */
isync
blr
/*
* FIXME - we haven't yet done testing to determine a reasonable default
* value for PW20_WAIT_IDLE_BIT.
*/
#define PW20_WAIT_IDLE_BIT 50 /* 1ms, TB frequency is 41.66MHZ */
_GLOBAL(setup_pw20_idle)
mfspr r3, SPRN_PWRMGTCR0
/* Set PW20_WAIT bit, enable pw20 state*/
ori r3, r3, PWRMGTCR0_PW20_WAIT
li r11, PW20_WAIT_IDLE_BIT
/* Set Automatic PW20 Core Idle Count */
rlwimi r3, r11, PWRMGTCR0_PW20_ENT_SHIFT, PWRMGTCR0_PW20_ENT
mtspr SPRN_PWRMGTCR0, r3
blr
/*
* FIXME - we haven't yet done testing to determine a reasonable default
* value for AV_WAIT_IDLE_BIT.
*/
#define AV_WAIT_IDLE_BIT 50 /* 1ms, TB frequency is 41.66MHZ */
_GLOBAL(setup_altivec_idle)
mfspr r3, SPRN_PWRMGTCR0
/* Enable Altivec Idle */
oris r3, r3, PWRMGTCR0_AV_IDLE_PD_EN@h
li r11, AV_WAIT_IDLE_BIT
/* Set Automatic AltiVec Idle Count */
rlwimi r3, r11, PWRMGTCR0_AV_IDLE_CNT_SHIFT, PWRMGTCR0_AV_IDLE_CNT
mtspr SPRN_PWRMGTCR0, r3
blr
_GLOBAL(__setup_cpu_e6500)
mflr r6
#ifdef CONFIG_PPC64
bl .setup_altivec_ivors
/* Touch IVOR42 only if the CPU supports E.HV category */
mfspr r10,SPRN_MMUCFG
rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
beq 1f
bl .setup_lrat_ivor
1:
#endif
bl setup_pw20_idle
bl setup_altivec_idle
bl __setup_cpu_e5500
mtlr r6
blr
#ifdef CONFIG_PPC32
_GLOBAL(__setup_cpu_e200)
/* enable dedicated debug exception handling resources (Debug APU) */
mfspr r3,SPRN_HID0
ori r3,r3,HID0_DAPUEN@l
mtspr SPRN_HID0,r3
b __setup_e200_ivors
_GLOBAL(__setup_cpu_e500v1)
_GLOBAL(__setup_cpu_e500v2)
mflr r4
bl __e500_icache_setup
bl __e500_dcache_setup
bl __setup_e500_ivors
#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)
/* Ensure that RFXE is set */
mfspr r3,SPRN_HID1
oris r3,r3,HID1_RFXE@h
mtspr SPRN_HID1,r3
#endif
mtlr r4
blr
_GLOBAL(__setup_cpu_e500mc)
_GLOBAL(__setup_cpu_e5500)
mflr r5
bl __e500_icache_setup
bl __e500_dcache_setup
bl __setup_e500mc_ivors
/*
* We only want to touch IVOR38-41 if we're running on hardware
* that supports category E.HV. The architectural way to determine
* this is MMUCFG[LPIDSIZE].
*/
mfspr r3, SPRN_MMUCFG
rlwinm. r3, r3, 0, MMUCFG_LPIDSIZE
beq 1f
bl __setup_ehv_ivors
b 2f
1:
lwz r3, CPU_SPEC_FEATURES(r4)
/* We need this check as cpu_setup is also called for
* the secondary cores. So, if we have already cleared
* the feature on the primary core, avoid doing it on the
* secondary core.
*/
andis. r6, r3, CPU_FTR_EMB_HV@h
beq 2f
rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV
stw r3, CPU_SPEC_FEATURES(r4)
2:
mtlr r5
blr
#endif
#ifdef CONFIG_PPC_BOOK3E_64
_GLOBAL(__restore_cpu_e6500)
mflr r5
bl .setup_altivec_ivors
/* Touch IVOR42 only if the CPU supports E.HV category */
mfspr r10,SPRN_MMUCFG
rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
beq 1f
bl .setup_lrat_ivor
1:
bl .setup_pw20_idle
bl .setup_altivec_idle
bl __restore_cpu_e5500
mtlr r5
blr
_GLOBAL(__restore_cpu_e5500)
mflr r4
bl __e500_icache_setup
bl __e500_dcache_setup
bl .__setup_base_ivors
bl .setup_perfmon_ivor
bl .setup_doorbell_ivors
/*
* We only want to touch IVOR38-41 if we're running on hardware
* that supports category E.HV. The architectural way to determine
* this is MMUCFG[LPIDSIZE].
*/
mfspr r10,SPRN_MMUCFG
rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
beq 1f
bl .setup_ehv_ivors
1:
mtlr r4
blr
_GLOBAL(__setup_cpu_e5500)
mflr r5
bl __e500_icache_setup
bl __e500_dcache_setup
bl .__setup_base_ivors
bl .setup_perfmon_ivor
bl .setup_doorbell_ivors
/*
* We only want to touch IVOR38-41 if we're running on hardware
* that supports category E.HV. The architectural way to determine
* this is MMUCFG[LPIDSIZE].
*/
mfspr r10,SPRN_MMUCFG
rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
beq 1f
bl .setup_ehv_ivors
b 2f
1:
ld r10,CPU_SPEC_FEATURES(r4)
LOAD_REG_IMMEDIATE(r9,CPU_FTR_EMB_HV)
andc r10,r10,r9
std r10,CPU_SPEC_FEATURES(r4)
2:
mtlr r5
blr
#endif
|