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