MINI2440: Updated early nand loader
[u-boot-openmoko/mini2440.git] / cpu / mpc86xx / cache.S
blobf316b3ec13fe59ea4012714d58617b82e12f7d66
1 #include <config.h>
2 #include <mpc86xx.h>
3 #include <version.h>
5 #include <ppc_asm.tmpl>
6 #include <ppc_defs.h>
8 #include <asm/cache.h>
9 #include <asm/mmu.h>
11 #ifndef CACHE_LINE_SIZE
12 # define CACHE_LINE_SIZE L1_CACHE_BYTES
13 #endif
15 #if CACHE_LINE_SIZE == 128
16 #define LG_CACHE_LINE_SIZE 7
17 #elif CACHE_LINE_SIZE == 32
18 #define LG_CACHE_LINE_SIZE 5
19 #elif CACHE_LINE_SIZE == 16
20 #define LG_CACHE_LINE_SIZE 4
21 #elif CACHE_LINE_SIZE == 8
22 #define LG_CACHE_LINE_SIZE 3
23 #else
24 # error "Invalid cache line size!"
25 #endif
28  * Most of this code is taken from 74xx_7xx/cache.S
29  * and then cleaned up a bit
30  */
33  * Invalidate L1 instruction cache.
34  */
35 _GLOBAL(invalidate_l1_instruction_cache)
36         /* use invalidate-all bit in HID0 */
37         mfspr   r3,HID0
38         ori     r3,r3,HID0_ICFI
39         mtspr   HID0,r3
40         isync
41         blr
44  * Invalidate L1 data cache.
45  */
46 _GLOBAL(invalidate_l1_data_cache)
47         mfspr   r3,HID0
48         ori     r3,r3,HID0_DCFI
49         mtspr   HID0,r3
50         isync
51         blr
54  * Flush data cache.
55  */
56 _GLOBAL(flush_data_cache)
57         lis     r3,0
58         lis     r5,CACHE_LINE_SIZE
59 flush:
60         cmp     0,1,r3,r5
61         bge     done
62         lwz     r5,0(r3)
63         lis     r5,CACHE_LINE_SIZE
64         addi    r3,r3,0x4
65         b       flush
66 done:
67         blr
69  * Write any modified data cache blocks out to memory
70  * and invalidate the corresponding instruction cache blocks.
71  * This is a no-op on the 601.
72  *
73  * flush_icache_range(unsigned long start, unsigned long stop)
74  */
75 _GLOBAL(flush_icache_range)
76         li      r5,CACHE_LINE_SIZE-1
77         andc    r3,r3,r5
78         subf    r4,r3,r4
79         add     r4,r4,r5
80         srwi.   r4,r4,LG_CACHE_LINE_SIZE
81         beqlr
82         mtctr   r4
83         mr      r6,r3
84 1:      dcbst   0,r3
85         addi    r3,r3,CACHE_LINE_SIZE
86         bdnz    1b
87         sync                            /* wait for dcbst's to get to ram */
88         mtctr   r4
89 2:      icbi    0,r6
90         addi    r6,r6,CACHE_LINE_SIZE
91         bdnz    2b
92         sync                            /* additional sync needed on g4 */
93         isync
94         blr
96  * Write any modified data cache blocks out to memory.
97  * Does not invalidate the corresponding cache lines (especially for
98  * any corresponding instruction cache).
99  *
100  * clean_dcache_range(unsigned long start, unsigned long stop)
101  */
102 _GLOBAL(clean_dcache_range)
103         li      r5,CACHE_LINE_SIZE-1
104         andc    r3,r3,r5        /* align r3 down to cache line */
105         subf    r4,r3,r4        /* r4 = offset of stop from start of cache line */
106         add     r4,r4,r5        /* r4 += cache_line_size-1 */
107         srwi.   r4,r4,LG_CACHE_LINE_SIZE  /* r4 = number of cache lines to flush */
108         beqlr                             /* if r4 == 0 return */
109         mtctr   r4                        /* ctr = r4 */
111         sync
112 1:      dcbst   0,r3
113         addi    r3,r3,CACHE_LINE_SIZE
114         bdnz    1b
115         sync                            /* wait for dcbst's to get to ram */
116         blr
119  * Write any modified data cache blocks out to memory
120  * and invalidate the corresponding instruction cache blocks.
122  * flush_dcache_range(unsigned long start, unsigned long stop)
123  */
124 _GLOBAL(flush_dcache_range)
125         li      r5,CACHE_LINE_SIZE-1
126         andc    r3,r3,r5
127         subf    r4,r3,r4
128         add     r4,r4,r5
129         srwi.   r4,r4,LG_CACHE_LINE_SIZE
130         beqlr
131         mtctr   r4
133         sync
134 1:      dcbf    0,r3
135         addi    r3,r3,CACHE_LINE_SIZE
136         bdnz    1b
137         sync                            /* wait for dcbf's to get to ram */
138         blr
141  * Like above, but invalidate the D-cache.  This is used by the 8xx
142  * to invalidate the cache so the PPC core doesn't get stale data
143  * from the CPM (no cache snooping here :-).
145  * invalidate_dcache_range(unsigned long start, unsigned long stop)
146  */
147 _GLOBAL(invalidate_dcache_range)
148         li      r5,CACHE_LINE_SIZE-1
149         andc    r3,r3,r5
150         subf    r4,r3,r4
151         add     r4,r4,r5
152         srwi.   r4,r4,LG_CACHE_LINE_SIZE
153         beqlr
154         mtctr   r4
156         sync
157 1:      dcbi    0,r3
158         addi    r3,r3,CACHE_LINE_SIZE
159         bdnz    1b
160         sync                            /* wait for dcbi's to get to ram */
161         blr
164  * Flush a particular page from the data cache to RAM.
165  * Note: this is necessary because the instruction cache does *not*
166  * snoop from the data cache.
168  *      void __flush_page_to_ram(void *page)
169  */
170 _GLOBAL(__flush_page_to_ram)
171         rlwinm  r3,r3,0,0,19            /* Get page base address */
172         li      r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
173         mtctr   r4
174         mr      r6,r3
175 0:      dcbst   0,r3                    /* Write line to ram */
176         addi    r3,r3,CACHE_LINE_SIZE
177         bdnz    0b
178         sync
179         mtctr   r4
180 1:      icbi    0,r6
181         addi    r6,r6,CACHE_LINE_SIZE
182         bdnz    1b
183         sync
184         isync
185         blr
188  * Flush a particular page from the instruction cache.
189  * Note: this is necessary because the instruction cache does *not*
190  * snoop from the data cache.
192  *      void __flush_icache_page(void *page)
193  */
194 _GLOBAL(__flush_icache_page)
195         li      r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
196         mtctr   r4
197 1:      icbi    0,r3
198         addi    r3,r3,CACHE_LINE_SIZE
199         bdnz    1b
200         sync
201         isync
202         blr
205  * Clear a page using the dcbz instruction, which doesn't cause any
206  * memory traffic (except to write out any cache lines which get
207  * displaced).  This only works on cacheable memory.
208  */
209 _GLOBAL(clear_page)
210         li      r0,4096/CACHE_LINE_SIZE
211         mtctr   r0
212 1:      dcbz    0,r3
213         addi    r3,r3,CACHE_LINE_SIZE
214         bdnz    1b
215         blr
218  * Enable L1 Instruction cache
219  */
220 _GLOBAL(icache_enable)
221         mfspr   r3, HID0
222         li      r5, HID0_ICFI|HID0_ILOCK
223         andc    r3, r3, r5
224         ori     r3, r3, HID0_ICE
225         ori     r5, r3, HID0_ICFI
226         mtspr   HID0, r5
227         mtspr   HID0, r3
228         isync
229         blr
232  * Disable L1 Instruction cache
233  */
234 _GLOBAL(icache_disable)
235         mfspr   r3, HID0
236         li      r5, 0
237         ori     r5, r5, HID0_ICE
238         andc    r3, r3, r5
239         mtspr   HID0, r3
240         isync
241         blr
244  * Is instruction cache enabled?
245  */
246 _GLOBAL(icache_status)
247         mfspr   r3, HID0
248         andi.   r3, r3, HID0_ICE
249         blr
252 _GLOBAL(l1dcache_enable)
253         mfspr   r3, HID0
254         li      r5, HID0_DCFI|HID0_DLOCK
255         andc    r3, r3, r5
256         mtspr   HID0, r3                /* no invalidate, unlock */
257         ori     r3, r3, HID0_DCE
258         ori     r5, r3, HID0_DCFI
259         mtspr   HID0, r5                /* enable + invalidate */
260         mtspr   HID0, r3                /* enable */
261         sync
262         blr
265  * Enable data cache(s) - L1 and optionally L2
266  * Calls l2cache_enable. LR saved in r5
267  */
268 _GLOBAL(dcache_enable)
269         mfspr   r3, HID0
270         li      r5, HID0_DCFI|HID0_DLOCK
271         andc    r3, r3, r5
272         mtspr   HID0, r3                /* no invalidate, unlock */
273         ori     r3, r3, HID0_DCE
274         ori     r5, r3, HID0_DCFI
275         mtspr   HID0, r5                /* enable + invalidate */
276         mtspr   HID0, r3                /* enable */
277         sync
278 #ifdef CFG_L2
279         mflr    r5
280         bl      l2cache_enable          /* uses r3 and r4 */
281         sync
282         mtlr    r5
283 #endif
284         blr
288  * Disable data cache(s) - L1 and optionally L2
289  * Calls flush_data_cache and l2cache_disable_no_flush.
290  * LR saved in r4
291  */
292 _GLOBAL(dcache_disable)
293         mflr    r4                      /* save link register */
294         bl      flush_data_cache        /* uses r3 and r5 */
295         sync
296         mfspr   r3, HID0
297         li      r5, HID0_DCFI|HID0_DLOCK
298         andc    r3, r3, r5
299         mtspr   HID0, r3                /* no invalidate, unlock */
300         li      r5, HID0_DCE|HID0_DCFI
301         andc    r3, r3, r5              /* no enable, no invalidate */
302         mtspr   HID0, r3
303         sync
304 #ifdef CFG_L2
305         bl      l2cache_disable_no_flush /* uses r3 */
306 #endif
307         mtlr    r4                      /* restore link register */
308         blr
311  * Is data cache enabled?
312  */
313 _GLOBAL(dcache_status)
314         mfspr   r3, HID0
315         andi.   r3, r3, HID0_DCE
316         blr
319  * Invalidate L2 cache using L2I, assume L2 is enabled
320  */
321 _GLOBAL(l2cache_invalidate)
322         mfspr   r3, l2cr
323         rlwinm. r3, r3, 0, 0, 0
324         beq     1f
326         mfspr   r3, l2cr
327         rlwinm  r3, r3, 0, 1, 31
329 #ifdef  CONFIG_ALTIVEC
330         dssall
331 #endif
332         sync
333         mtspr   l2cr, r3
334         sync
335 1:      mfspr   r3, l2cr
336         oris    r3, r3, L2CR_L2I@h
337         mtspr   l2cr, r3
339 invl2:
340         mfspr   r3, l2cr
341         andi.   r3, r3, L2CR_L2I@h
342         bne     invl2
343         blr
346  * Enable L2 cache
347  * Calls l2cache_invalidate. LR is saved in r4
348  */
349 _GLOBAL(l2cache_enable)
350         mflr    r4                      /* save link register */
351         bl      l2cache_invalidate      /* uses r3 */
352         sync
353         lis     r3, L2_ENABLE@h
354         ori     r3, r3, L2_ENABLE@l
355         mtspr   l2cr, r3
356         isync
357         mtlr    r4                      /* restore link register */
358         blr
361  * Disable L2 cache
362  * Calls flush_data_cache. LR is saved in r4
363  */
364 _GLOBAL(l2cache_disable)
365         mflr    r4                      /* save link register */
366         bl      flush_data_cache        /* uses r3 and r5 */
367         sync
368         mtlr    r4                      /* restore link register */
369 l2cache_disable_no_flush:               /* provide way to disable L2 w/o flushing */
370         lis     r3, L2_INIT@h
371         ori     r3, r3, L2_INIT@l
372         mtspr   l2cr, r3
373         isync
374         blr