GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / powerpc / platforms / powermac / cache.S
blobcb6a6f85e564d37ec4bce7f0046120bd05333cef
1 /*
2  * This file contains low-level cache management functions
3  * used for sleep and CPU speed changes on Apple machines.
4  * (In fact the only thing that is Apple-specific is that we assume
5  * that we can read from ROM at physical address 0xfff00000.)
6  *
7  *    Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
8  *                       Benjamin Herrenschmidt (benh@kernel.crashing.org)
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version
13  * 2 of the License, or (at your option) any later version.
14  *
15  */
17 #include <asm/processor.h>
18 #include <asm/ppc_asm.h>
19 #include <asm/cputable.h>
22  * Flush and disable all data caches (dL1, L2, L3). This is used
23  * when going to sleep, when doing a PMU based cpufreq transition,
24  * or when "offlining" a CPU on SMP machines. This code is over
25  * paranoid, but I've had enough issues with various CPU revs and
26  * bugs that I decided it was worth beeing over cautious
27  */
29 _GLOBAL(flush_disable_caches)
30 #ifndef CONFIG_6xx
31         blr
32 #else
33 BEGIN_FTR_SECTION
34         b       flush_disable_745x
35 END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
36 BEGIN_FTR_SECTION
37         b       flush_disable_75x
38 END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
39         b       __flush_disable_L1
41 /* This is the code for G3 and 74[01]0 */
42 flush_disable_75x:
43         mflr    r10
45         /* Turn off EE and DR in MSR */
46         mfmsr   r11
47         rlwinm  r0,r11,0,~MSR_EE
48         rlwinm  r0,r0,0,~MSR_DR
49         sync
50         mtmsr   r0
51         isync
53         /* Stop DST streams */
54 BEGIN_FTR_SECTION
55         DSSALL
56         sync
57 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
59         /* Stop DPM */
60         mfspr   r8,SPRN_HID0            /* Save SPRN_HID0 in r8 */
61         rlwinm  r4,r8,0,12,10           /* Turn off HID0[DPM] */
62         sync
63         mtspr   SPRN_HID0,r4            /* Disable DPM */
64         sync
67         /* ROM base by default */
68         lis     r4,0xfff0
69         mfpvr   r3
70         srwi    r3,r3,16
71         cmplwi  cr0,r3,0x7000
72         bne+    1f
73         /* RAM base on 750FX */
74         li      r4,0
75 1:      li      r4,0x4000
76         mtctr   r4
77 1:      lwz     r0,0(r4)
78         addi    r4,r4,32
79         bdnz    1b
80         sync
81         isync
83         /* Disable / invalidate / enable L1 data */
84         mfspr   r3,SPRN_HID0
85         rlwinm  r3,r3,0,~(HID0_DCE | HID0_ICE)
86         mtspr   SPRN_HID0,r3
87         sync
88         isync
89         ori     r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
90         sync
91         isync
92         mtspr   SPRN_HID0,r3
93         xori    r3,r3,(HID0_DCI|HID0_ICFI)
94         mtspr   SPRN_HID0,r3
95         sync
97         /* Get the current enable bit of the L2CR into r4 */
98         mfspr   r5,SPRN_L2CR
99         /* Set to data-only (pre-745x bit) */
100         oris    r3,r5,L2CR_L2DO@h
101         b       2f
102         /* When disabling L2, code must be in L1 */
103         .balign 32
104 1:      mtspr   SPRN_L2CR,r3
105 3:      sync
106         isync
107         b       1f
108 2:      b       3f
109 3:      sync
110         isync
111         b       1b
112 1:      /* disp-flush L2. The interesting thing here is that the L2 can be
113          * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
114          * but that is probbaly fine. We disp-flush over 4Mb to be safe
115          */
116         lis     r4,2
117         mtctr   r4
118         lis     r4,0xfff0
119 1:      lwz     r0,0(r4)
120         addi    r4,r4,32
121         bdnz    1b
122         sync
123         isync
124         lis     r4,2
125         mtctr   r4
126         lis     r4,0xfff0
127 1:      dcbf    0,r4
128         addi    r4,r4,32
129         bdnz    1b
130         sync
131         isync
133         /* now disable L2 */
134         rlwinm  r5,r5,0,~L2CR_L2E
135         b       2f
136         /* When disabling L2, code must be in L1 */
137         .balign 32
138 1:      mtspr   SPRN_L2CR,r5
139 3:      sync
140         isync
141         b       1f
142 2:      b       3f
143 3:      sync
144         isync
145         b       1b
146 1:      sync
147         isync
148         /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
149         oris    r4,r5,L2CR_L2I@h
150         mtspr   SPRN_L2CR,r4
151         sync
152         isync
154         /* Wait for the invalidation to complete */
155 1:      mfspr   r3,SPRN_L2CR
156         rlwinm. r0,r3,0,31,31
157         bne     1b
159         /* Clear L2I */
160         xoris   r4,r4,L2CR_L2I@h
161         sync
162         mtspr   SPRN_L2CR,r4
163         sync
165         /* now disable the L1 data cache */
166         mfspr   r0,SPRN_HID0
167         rlwinm  r0,r0,0,~(HID0_DCE|HID0_ICE)
168         mtspr   SPRN_HID0,r0
169         sync
170         isync
172         /* Restore HID0[DPM] to whatever it was before */
173         sync
174         mfspr   r0,SPRN_HID0
175         rlwimi  r0,r8,0,11,11           /* Turn back HID0[DPM] */
176         mtspr   SPRN_HID0,r0
177         sync
179         /* restore DR and EE */
180         sync
181         mtmsr   r11
182         isync
184         mtlr    r10
185         blr
187 /* This code is for 745x processors */
188 flush_disable_745x:
189         /* Turn off EE and DR in MSR */
190         mfmsr   r11
191         rlwinm  r0,r11,0,~MSR_EE
192         rlwinm  r0,r0,0,~MSR_DR
193         sync
194         mtmsr   r0
195         isync
197         /* Stop prefetch streams */
198         DSSALL
199         sync
201         /* Disable L2 prefetching */
202         mfspr   r0,SPRN_MSSCR0
203         rlwinm  r0,r0,0,0,29
204         mtspr   SPRN_MSSCR0,r0
205         sync
206         isync
207         lis     r4,0
208         dcbf    0,r4
209         dcbf    0,r4
210         dcbf    0,r4
211         dcbf    0,r4
212         dcbf    0,r4
213         dcbf    0,r4
214         dcbf    0,r4
215         dcbf    0,r4
217         /* Due to a bug with the HW flush on some CPU revs, we occasionally
218          * experience data corruption. I'm adding a displacement flush along
219          * with a dcbf loop over a few Mb to "help". The problem isn't totally
220          * fixed by this in theory, but at least, in practice, I couldn't reproduce
221          * it even with a big hammer...
222          */
224         lis     r4,0x0002
225         mtctr   r4
226         li      r4,0
228         lwz     r0,0(r4)
229         addi    r4,r4,32                /* Go to start of next cache line */
230         bdnz    1b
231         isync
233         /* Now, flush the first 4MB of memory */
234         lis     r4,0x0002
235         mtctr   r4
236         li      r4,0
237         sync
239         dcbf    0,r4
240         addi    r4,r4,32                /* Go to start of next cache line */
241         bdnz    1b
243         /* Flush and disable the L1 data cache */
244         mfspr   r6,SPRN_LDSTCR
245         lis     r3,0xfff0       /* read from ROM for displacement flush */
246         li      r4,0xfe         /* start with only way 0 unlocked */
247         li      r5,128          /* 128 lines in each way */
248 1:      mtctr   r5
249         rlwimi  r6,r4,0,24,31
250         mtspr   SPRN_LDSTCR,r6
251         sync
252         isync
253 2:      lwz     r0,0(r3)        /* touch each cache line */
254         addi    r3,r3,32
255         bdnz    2b
256         rlwinm  r4,r4,1,24,30   /* move on to the next way */
257         ori     r4,r4,1
258         cmpwi   r4,0xff         /* all done? */
259         bne     1b
260         /* now unlock the L1 data cache */
261         li      r4,0
262         rlwimi  r6,r4,0,24,31
263         sync
264         mtspr   SPRN_LDSTCR,r6
265         sync
266         isync
268         /* Flush the L2 cache using the hardware assist */
269         mfspr   r3,SPRN_L2CR
270         cmpwi   r3,0            /* check if it is enabled first */
271         bge     4f
272         oris    r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
273         b       2f
274         /* When disabling/locking L2, code must be in L1 */
275         .balign 32
276 1:      mtspr   SPRN_L2CR,r0    /* lock the L2 cache */
277 3:      sync
278         isync
279         b       1f
280 2:      b       3f
281 3:      sync
282         isync
283         b       1b
284 1:      sync
285         isync
286         ori     r0,r3,L2CR_L2HWF_745x
287         sync
288         mtspr   SPRN_L2CR,r0    /* set the hardware flush bit */
289 3:      mfspr   r0,SPRN_L2CR    /* wait for it to go to 0 */
290         andi.   r0,r0,L2CR_L2HWF_745x
291         bne     3b
292         sync
293         rlwinm  r3,r3,0,~L2CR_L2E
294         b       2f
295         /* When disabling L2, code must be in L1 */
296         .balign 32
297 1:      mtspr   SPRN_L2CR,r3    /* disable the L2 cache */
298 3:      sync
299         isync
300         b       1f
301 2:      b       3f
302 3:      sync
303         isync
304         b       1b
305 1:      sync
306         isync
307         oris    r4,r3,L2CR_L2I@h
308         mtspr   SPRN_L2CR,r4
309         sync
310         isync
311 1:      mfspr   r4,SPRN_L2CR
312         andis.  r0,r4,L2CR_L2I@h
313         bne     1b
314         sync
316 BEGIN_FTR_SECTION
317         /* Flush the L3 cache using the hardware assist */
318 4:      mfspr   r3,SPRN_L3CR
319         cmpwi   r3,0            /* check if it is enabled */
320         bge     6f
321         oris    r0,r3,L3CR_L3IO@h
322         ori     r0,r0,L3CR_L3DO
323         sync
324         mtspr   SPRN_L3CR,r0    /* lock the L3 cache */
325         sync
326         isync
327         ori     r0,r0,L3CR_L3HWF
328         sync
329         mtspr   SPRN_L3CR,r0    /* set the hardware flush bit */
330 5:      mfspr   r0,SPRN_L3CR    /* wait for it to go to zero */
331         andi.   r0,r0,L3CR_L3HWF
332         bne     5b
333         rlwinm  r3,r3,0,~L3CR_L3E
334         sync
335         mtspr   SPRN_L3CR,r3    /* disable the L3 cache */
336         sync
337         ori     r4,r3,L3CR_L3I
338         mtspr   SPRN_L3CR,r4
339 1:      mfspr   r4,SPRN_L3CR
340         andi.   r0,r4,L3CR_L3I
341         bne     1b
342         sync
343 END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
345 6:      mfspr   r0,SPRN_HID0    /* now disable the L1 data cache */
346         rlwinm  r0,r0,0,~HID0_DCE
347         mtspr   SPRN_HID0,r0
348         sync
349         isync
350         mtmsr   r11             /* restore DR and EE */
351         isync
352         blr
353 #endif  /* CONFIG_6xx */