Merge commit 'u-boot-fdt/testing'
[platform/kernel/u-boot.git] / cpu / ppc4xx / cache.S
1 /*
2  * This file contains miscellaneous low-level functions.
3  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4  *
5  * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
6  * and Paul Mackerras.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version
11  * 2 of the License, or (at your option) any later version.
12  *
13  */
14
15 #include <config.h>
16 #include <config.h>
17 #include <ppc4xx.h>
18 #include <ppc_asm.tmpl>
19 #include <ppc_defs.h>
20 #include <asm/cache.h>
21 #include <asm/mmu.h>
22
23 /*
24  * Flush instruction cache.
25  */
26 _GLOBAL(invalidate_icache)
27         iccci   r0,r0
28         isync
29         blr
30
31 /*
32  * Write any modified data cache blocks out to memory
33  * and invalidate the corresponding instruction cache blocks.
34  *
35  * flush_icache_range(unsigned long start, unsigned long stop)
36  */
37 _GLOBAL(flush_icache_range)
38         li      r5,L1_CACHE_BYTES-1
39         andc    r3,r3,r5
40         subf    r4,r3,r4
41         add     r4,r4,r5
42         srwi.   r4,r4,L1_CACHE_SHIFT
43         beqlr
44         mtctr   r4
45         mr      r6,r3
46 1:      dcbst   0,r3
47         addi    r3,r3,L1_CACHE_BYTES
48         bdnz    1b
49         sync                            /* wait for dcbst's to get to ram */
50         mtctr   r4
51 2:      icbi    0,r6
52         addi    r6,r6,L1_CACHE_BYTES
53         bdnz    2b
54         sync                            /* additional sync needed on g4 */
55         isync
56         blr
57
58 /*
59  * Write any modified data cache blocks out to memory.
60  * Does not invalidate the corresponding cache lines (especially for
61  * any corresponding instruction cache).
62  *
63  * clean_dcache_range(unsigned long start, unsigned long stop)
64  */
65 _GLOBAL(clean_dcache_range)
66         li      r5,L1_CACHE_BYTES-1
67         andc    r3,r3,r5
68         subf    r4,r3,r4
69         add     r4,r4,r5
70         srwi.   r4,r4,L1_CACHE_SHIFT
71         beqlr
72         mtctr   r4
73
74 1:      dcbst   0,r3
75         addi    r3,r3,L1_CACHE_BYTES
76         bdnz    1b
77         sync                            /* wait for dcbst's to get to ram */
78         blr
79
80 /*
81  * Write any modified data cache blocks out to memory and invalidate them.
82  * Does not invalidate the corresponding instruction cache blocks.
83  *
84  * flush_dcache_range(unsigned long start, unsigned long stop)
85  */
86 _GLOBAL(flush_dcache_range)
87         li      r5,L1_CACHE_BYTES-1
88         andc    r3,r3,r5
89         subf    r4,r3,r4
90         add     r4,r4,r5
91         srwi.   r4,r4,L1_CACHE_SHIFT
92         beqlr
93         mtctr   r4
94
95 1:      dcbf    0,r3
96         addi    r3,r3,L1_CACHE_BYTES
97         bdnz    1b
98         sync                            /* wait for dcbst's to get to ram */
99         blr
100
101 /*
102  * Like above, but invalidate the D-cache.  This is used by the 8xx
103  * to invalidate the cache so the PPC core doesn't get stale data
104  * from the CPM (no cache snooping here :-).
105  *
106  * invalidate_dcache_range(unsigned long start, unsigned long stop)
107  */
108 _GLOBAL(invalidate_dcache_range)
109         li      r5,L1_CACHE_BYTES-1
110         andc    r3,r3,r5
111         subf    r4,r3,r4
112         add     r4,r4,r5
113         srwi.   r4,r4,L1_CACHE_SHIFT
114         beqlr
115         mtctr   r4
116
117 1:      dcbi    0,r3
118         addi    r3,r3,L1_CACHE_BYTES
119         bdnz    1b
120         sync                            /* wait for dcbi's to get to ram */
121         blr
122
123 /*
124  * 40x cores have 8K or 16K dcache and 32 byte line size.
125  * 44x has a 32K dcache and 32 byte line size.
126  * 8xx has 1, 2, 4, 8K variants.
127  * For now, cover the worst case of the 44x.
128  * Must be called with external interrupts disabled.
129  */
130 #define CACHE_NWAYS     64
131 #define CACHE_NLINES    32
132
133 _GLOBAL(flush_dcache)
134         li      r4,(2 * CACHE_NWAYS * CACHE_NLINES)
135         mtctr   r4
136         lis     r5,0
137 1:      lwz     r3,0(r5)                /* Load one word from every line */
138         addi    r5,r5,L1_CACHE_BYTES
139         bdnz    1b
140         sync
141         blr
142
143 _GLOBAL(invalidate_dcache)
144         addi    r6,0,0x0000             /* clear GPR 6 */
145         /* Do loop for # of dcache congruence classes. */
146         lis     r7,(CFG_DCACHE_SIZE / L1_CACHE_BYTES / 2)@ha    /* TBS for large sized cache */
147         ori     r7,r7,(CFG_DCACHE_SIZE / L1_CACHE_BYTES / 2)@l
148                                         /* NOTE: dccci invalidates both */
149         mtctr   r7                      /* ways in the D cache */
150 ..dcloop:
151         dccci   0,r6                    /* invalidate line */
152         addi    r6,r6,L1_CACHE_BYTES    /* bump to next line */
153         bdnz    ..dcloop
154         sync
155         blr
156
157 /*
158  * Cache functions.
159  *
160  * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
161  * although for some cache-ralated calls stubs have to be provided to satisfy
162  * symbols resolution.
163  * Icache-related functions are used in POST framework.
164  *
165  */
166 #ifdef CONFIG_440
167
168        .globl  dcache_disable
169        .globl  icache_disable
170        .globl  icache_enable
171 dcache_disable:
172 icache_disable:
173 icache_enable:
174         blr
175
176         .globl  dcache_status
177         .globl  icache_status
178 dcache_status:
179 icache_status:
180         mr      r3,  0
181         blr
182
183 #else /* CONFIG_440 */
184
185         .globl  icache_enable
186 icache_enable:
187         mflr    r8
188         bl      invalidate_icache
189         mtlr    r8
190         isync
191         addis   r3,r0, 0xc000         /* set bit 0 */
192         mticcr  r3
193         blr
194
195         .globl  icache_disable
196 icache_disable:
197         addis   r3,r0, 0x0000         /* clear bit 0 */
198         mticcr  r3
199         isync
200         blr
201
202         .globl  icache_status
203 icache_status:
204         mficcr  r3
205         srwi    r3, r3, 31      /* >>31 => select bit 0 */
206         blr
207
208         .globl  dcache_enable
209 dcache_enable:
210         mflr    r8
211         bl      invalidate_dcache
212         mtlr    r8
213         isync
214         addis   r3,r0, 0x8000         /* set bit 0 */
215         mtdccr  r3
216         blr
217
218         .globl  dcache_disable
219 dcache_disable:
220         mflr    r8
221         bl      flush_dcache
222         mtlr    r8
223         addis   r3,r0, 0x0000         /* clear bit 0 */
224         mtdccr  r3
225         blr
226
227         .globl  dcache_status
228 dcache_status:
229         mfdccr  r3
230         srwi    r3, r3, 31      /* >>31 => select bit 0 */
231         blr
232
233 #endif /* CONFIG_440 */