aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/l2cr_6xx.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/l2cr_6xx.S')
-rw-r--r--arch/powerpc/kernel/l2cr_6xx.S471
1 files changed, 471 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S
new file mode 100644
index 000000000000..d7f4e982b539
--- /dev/null
+++ b/arch/powerpc/kernel/l2cr_6xx.S
@@ -0,0 +1,471 @@
1/*
2 L2CR functions
3 Copyright © 1997-1998 by PowerLogix R & D, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19/*
20 Thur, Dec. 12, 1998.
21 - First public release, contributed by PowerLogix.
22 ***********
23 Sat, Aug. 7, 1999.
24 - Terry: Made sure code disabled interrupts before running. (Previously
25 it was assumed interrupts were already disabled).
26 - Terry: Updated for tentative G4 support. 4MB of memory is now flushed
27 instead of 2MB. (Prob. only 3 is necessary).
28 - Terry: Updated for workaround to HID0[DPM] processor bug
29 during global invalidates.
30 ***********
31 Thu, July 13, 2000.
32 - Terry: Added isync to correct for an errata.
33
34 22 August 2001.
35 - DanM: Finally added the 7450 patch I've had for the past
36 several months. The L2CR is similar, but I'm going
37 to assume the user of this functions knows what they
38 are doing.
39
40 Author: Terry Greeniaus (tgree@phys.ualberta.ca)
41 Please e-mail updates to this file to me, thanks!
42*/
43#include <linux/config.h>
44#include <asm/processor.h>
45#include <asm/cputable.h>
46#include <asm/ppc_asm.h>
47#include <asm/cache.h>
48#include <asm/page.h>
49
50/* Usage:
51
52 When setting the L2CR register, you must do a few special
53 things. If you are enabling the cache, you must perform a
54 global invalidate. If you are disabling the cache, you must
55 flush the cache contents first. This routine takes care of
56 doing these things. When first enabling the cache, make sure
57 you pass in the L2CR you want, as well as passing in the
58 global invalidate bit set. A global invalidate will only be
59 performed if the L2I bit is set in applyThis. When enabling
60 the cache, you should also set the L2E bit in applyThis. If
61 you want to modify the L2CR contents after the cache has been
62 enabled, the recommended procedure is to first call
63 __setL2CR(0) to disable the cache and then call it again with
64 the new values for L2CR. Examples:
65
66 _setL2CR(0) - disables the cache
67 _setL2CR(0xB3A04000) - enables my G3 upgrade card:
68 - L2E set to turn on the cache
69 - L2SIZ set to 1MB
70 - L2CLK set to 1:1
71 - L2RAM set to pipelined synchronous late-write
72 - L2I set to perform a global invalidation
73 - L2OH set to 0.5 nS
74 - L2DF set because this upgrade card
75 requires it
76
77 A similar call should work for your card. You need to know
78 the correct setting for your card and then place them in the
79 fields I have outlined above. Other fields support optional
80 features, such as L2DO which caches only data, or L2TS which
81 causes cache pushes from the L1 cache to go to the L2 cache
82 instead of to main memory.
83
84IMPORTANT:
85 Starting with the 7450, the bits in this register have moved
86 or behave differently. The Enable, Parity Enable, Size,
87 and L2 Invalidate are the only bits that have not moved.
88 The size is read-only for these processors with internal L2
89 cache, and the invalidate is a control as well as status.
90 -- Dan
91
92*/
93/*
94 * Summary: this procedure ignores the L2I bit in the value passed in,
95 * flushes the cache if it was already enabled, always invalidates the
96 * cache, then enables the cache if the L2E bit is set in the value
97 * passed in.
98 * -- paulus.
99 */
100_GLOBAL(_set_L2CR)
101 /* Make sure this is a 750 or 7400 chip */
102BEGIN_FTR_SECTION
103 li r3,-1
104 blr
105END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
106
107 mflr r9
108
109 /* Stop DST streams */
110BEGIN_FTR_SECTION
111 DSSALL
112 sync
113END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
114
115 /* Turn off interrupts and data relocation. */
116 mfmsr r7 /* Save MSR in r7 */
117 rlwinm r4,r7,0,17,15
118 rlwinm r4,r4,0,28,26 /* Turn off DR bit */
119 sync
120 mtmsr r4
121 isync
122
123 /* Before we perform the global invalidation, we must disable dynamic
124 * power management via HID0[DPM] to work around a processor bug where
125 * DPM can possibly interfere with the state machine in the processor
126 * that invalidates the L2 cache tags.
127 */
128 mfspr r8,SPRN_HID0 /* Save HID0 in r8 */
129 rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
130 sync
131 mtspr SPRN_HID0,r4 /* Disable DPM */
132 sync
133
134 /* Get the current enable bit of the L2CR into r4 */
135 mfspr r4,SPRN_L2CR
136
137 /* Tweak some bits */
138 rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
139 rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */
140 rlwinm r3,r3,0,1,31 /* Turn off the enable bit */
141
142 /* Check to see if we need to flush */
143 rlwinm. r4,r4,0,0,0
144 beq 2f
145
146 /* Flush the cache. First, read the first 4MB of memory (physical) to
147 * put new data in the cache. (Actually we only need
148 * the size of the L2 cache plus the size of the L1 cache, but 4MB will
149 * cover everything just to be safe).
150 */
151
152 /**** Might be a good idea to set L2DO here - to prevent instructions
153 from getting into the cache. But since we invalidate
154 the next time we enable the cache it doesn't really matter.
155 Don't do this unless you accomodate all processor variations.
156 The bit moved on the 7450.....
157 ****/
158
159BEGIN_FTR_SECTION
160 /* Disable L2 prefetch on some 745x and try to ensure
161 * L2 prefetch engines are idle. As explained by errata
162 * text, we can't be sure they are, we just hope very hard
163 * that well be enough (sic !). At least I noticed Apple
164 * doesn't even bother doing the dcbf's here...
165 */
166 mfspr r4,SPRN_MSSCR0
167 rlwinm r4,r4,0,0,29
168 sync
169 mtspr SPRN_MSSCR0,r4
170 sync
171 isync
172 lis r4,KERNELBASE@h
173 dcbf 0,r4
174 dcbf 0,r4
175 dcbf 0,r4
176 dcbf 0,r4
177END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
178
179 /* TODO: use HW flush assist when available */
180
181 lis r4,0x0002
182 mtctr r4
183 li r4,0
1841:
185 lwzx r0,r0,r4
186 addi r4,r4,32 /* Go to start of next cache line */
187 bdnz 1b
188 isync
189
190 /* Now, flush the first 4MB of memory */
191 lis r4,0x0002
192 mtctr r4
193 li r4,0
194 sync
1951:
196 dcbf 0,r4
197 addi r4,r4,32 /* Go to start of next cache line */
198 bdnz 1b
199
2002:
201 /* Set up the L2CR configuration bits (and switch L2 off) */
202 /* CPU errata: Make sure the mtspr below is already in the
203 * L1 icache
204 */
205 b 20f
206 .balign L1_CACHE_BYTES
20722:
208 sync
209 mtspr SPRN_L2CR,r3
210 sync
211 b 23f
21220:
213 b 21f
21421: sync
215 isync
216 b 22b
217
21823:
219 /* Perform a global invalidation */
220 oris r3,r3,0x0020
221 sync
222 mtspr SPRN_L2CR,r3
223 sync
224 isync /* For errata */
225
226BEGIN_FTR_SECTION
227 /* On the 7450, we wait for the L2I bit to clear......
228 */
22910: mfspr r3,SPRN_L2CR
230 andis. r4,r3,0x0020
231 bne 10b
232 b 11f
233END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
234
235 /* Wait for the invalidation to complete */
2363: mfspr r3,SPRN_L2CR
237 rlwinm. r4,r3,0,31,31
238 bne 3b
239
24011: rlwinm r3,r3,0,11,9 /* Turn off the L2I bit */
241 sync
242 mtspr SPRN_L2CR,r3
243 sync
244
245 /* See if we need to enable the cache */
246 cmplwi r5,0
247 beq 4f
248
249 /* Enable the cache */
250 oris r3,r3,0x8000
251 mtspr SPRN_L2CR,r3
252 sync
253
254 /* Enable L2 HW prefetch on 744x/745x */
255BEGIN_FTR_SECTION
256 mfspr r3,SPRN_MSSCR0
257 ori r3,r3,3
258 sync
259 mtspr SPRN_MSSCR0,r3
260 sync
261 isync
262END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
2634:
264
265 /* Restore HID0[DPM] to whatever it was before */
266 sync
267 mtspr 1008,r8
268 sync
269
270 /* Restore MSR (restores EE and DR bits to original state) */
271 SYNC
272 mtmsr r7
273 isync
274
275 mtlr r9
276 blr
277
278_GLOBAL(_get_L2CR)
279 /* Return the L2CR contents */
280 li r3,0
281BEGIN_FTR_SECTION
282 mfspr r3,SPRN_L2CR
283END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
284 blr
285
286
287/*
288 * Here is a similar routine for dealing with the L3 cache
289 * on the 745x family of chips
290 */
291
292_GLOBAL(_set_L3CR)
293 /* Make sure this is a 745x chip */
294BEGIN_FTR_SECTION
295 li r3,-1
296 blr
297END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
298
299 /* Turn off interrupts and data relocation. */
300 mfmsr r7 /* Save MSR in r7 */
301 rlwinm r4,r7,0,17,15
302 rlwinm r4,r4,0,28,26 /* Turn off DR bit */
303 sync
304 mtmsr r4
305 isync
306
307 /* Stop DST streams */
308 DSSALL
309 sync
310
311 /* Get the current enable bit of the L3CR into r4 */
312 mfspr r4,SPRN_L3CR
313
314 /* Tweak some bits */
315 rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
316 rlwinm r3,r3,0,22,20 /* Turn off the invalidate bit */
317 rlwinm r3,r3,0,2,31 /* Turn off the enable & PE bits */
318 rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
319 /* Check to see if we need to flush */
320 rlwinm. r4,r4,0,0,0
321 beq 2f
322
323 /* Flush the cache.
324 */
325
326 /* TODO: use HW flush assist */
327
328 lis r4,0x0008
329 mtctr r4
330 li r4,0
3311:
332 lwzx r0,r0,r4
333 dcbf 0,r4
334 addi r4,r4,32 /* Go to start of next cache line */
335 bdnz 1b
336
3372:
338 /* Set up the L3CR configuration bits (and switch L3 off) */
339 sync
340 mtspr SPRN_L3CR,r3
341 sync
342
343 oris r3,r3,L3CR_L3RES@h /* Set reserved bit 5 */
344 mtspr SPRN_L3CR,r3
345 sync
346 oris r3,r3,L3CR_L3CLKEN@h /* Set clken */
347 mtspr SPRN_L3CR,r3
348 sync
349
350 /* Wait for stabilize */
351 li r0,256
352 mtctr r0
3531: bdnz 1b
354
355 /* Perform a global invalidation */
356 ori r3,r3,0x0400
357 sync
358 mtspr SPRN_L3CR,r3
359 sync
360 isync
361
362 /* We wait for the L3I bit to clear...... */
36310: mfspr r3,SPRN_L3CR
364 andi. r4,r3,0x0400
365 bne 10b
366
367 /* Clear CLKEN */
368 rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
369 mtspr SPRN_L3CR,r3
370 sync
371
372 /* Wait for stabilize */
373 li r0,256
374 mtctr r0
3751: bdnz 1b
376
377 /* See if we need to enable the cache */
378 cmplwi r5,0
379 beq 4f
380
381 /* Enable the cache */
382 oris r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
383 mtspr SPRN_L3CR,r3
384 sync
385
386 /* Wait for stabilize */
387 li r0,256
388 mtctr r0
3891: bdnz 1b
390
391 /* Restore MSR (restores EE and DR bits to original state) */
3924: SYNC
393 mtmsr r7
394 isync
395 blr
396
397_GLOBAL(_get_L3CR)
398 /* Return the L3CR contents */
399 li r3,0
400BEGIN_FTR_SECTION
401 mfspr r3,SPRN_L3CR
402END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
403 blr
404
405/* --- End of PowerLogix code ---
406 */
407
408
409/* flush_disable_L1() - Flush and disable L1 cache
410 *
411 * clobbers r0, r3, ctr, cr0
412 * Must be called with interrupts disabled and MMU enabled.
413 */
414_GLOBAL(__flush_disable_L1)
415 /* Stop pending alitvec streams and memory accesses */
416BEGIN_FTR_SECTION
417 DSSALL
418END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
419 sync
420
421 /* Load counter to 0x4000 cache lines (512k) and
422 * load cache with datas
423 */
424 li r3,0x4000 /* 512kB / 32B */
425 mtctr r3
426 lis r3,KERNELBASE@h
4271:
428 lwz r0,0(r3)
429 addi r3,r3,0x0020 /* Go to start of next cache line */
430 bdnz 1b
431 isync
432 sync
433
434 /* Now flush those cache lines */
435 li r3,0x4000 /* 512kB / 32B */
436 mtctr r3
437 lis r3,KERNELBASE@h
4381:
439 dcbf 0,r3
440 addi r3,r3,0x0020 /* Go to start of next cache line */
441 bdnz 1b
442 sync
443
444 /* We can now disable the L1 cache (HID0:DCE, HID0:ICE) */
445 mfspr r3,SPRN_HID0
446 rlwinm r3,r3,0,18,15
447 mtspr SPRN_HID0,r3
448 sync
449 isync
450 blr
451
452/* inval_enable_L1 - Invalidate and enable L1 cache
453 *
454 * Assumes L1 is already disabled and MSR:EE is off
455 *
456 * clobbers r3
457 */
458_GLOBAL(__inval_enable_L1)
459 /* Enable and then Flash inval the instruction & data cache */
460 mfspr r3,SPRN_HID0
461 ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
462 sync
463 isync
464 mtspr SPRN_HID0,r3
465 xori r3,r3, HID0_ICFI|HID0_DCI
466 mtspr SPRN_HID0,r3
467 sync
468
469 blr
470
471