ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+
[sfrench/cifs-2.6.git] / arch / arm / mm / cache-fa.S
1 /*
2  *  linux/arch/arm/mm/cache-fa.S
3  *
4  *  Copyright (C) 2005 Faraday Corp.
5  *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
6  *
7  * Based on cache-v4wb.S:
8  *  Copyright (C) 1997-2002 Russell king
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  *  Processors: FA520 FA526 FA626       
15  */
16 #include <linux/linkage.h>
17 #include <linux/init.h>
18 #include <asm/assembler.h>
19 #include <asm/memory.h>
20 #include <asm/page.h>
21
22 #include "proc-macros.S"
23
24 /*
25  * The size of one data cache line.
26  */
27 #define CACHE_DLINESIZE 16
28
29 /*
30  * The total size of the data cache.
31  */
32 #ifdef CONFIG_ARCH_GEMINI
33 #define CACHE_DSIZE     8192
34 #else
35 #define CACHE_DSIZE     16384 
36 #endif 
37
38 /* FIXME: put optimal value here. Current one is just estimation */
39 #define CACHE_DLIMIT    (CACHE_DSIZE * 2)
40
41 /*
42  *      flush_icache_all()
43  *
44  *      Unconditionally clean and invalidate the entire icache.
45  */
46 ENTRY(fa_flush_icache_all)
47         mov     r0, #0
48         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
49         ret     lr
50 ENDPROC(fa_flush_icache_all)
51
52 /*
53  *      flush_user_cache_all()
54  *
55  *      Clean and invalidate all cache entries in a particular address
56  *      space.
57  */
58 ENTRY(fa_flush_user_cache_all)
59         /* FALLTHROUGH */
60 /*
61  *      flush_kern_cache_all()
62  *
63  *      Clean and invalidate the entire cache.
64  */
65 ENTRY(fa_flush_kern_cache_all)
66         mov     ip, #0
67         mov     r2, #VM_EXEC
68 __flush_whole_cache:
69         mcr     p15, 0, ip, c7, c14, 0          @ clean/invalidate D cache
70         tst     r2, #VM_EXEC
71         mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
72         mcrne   p15, 0, ip, c7, c5, 6           @ invalidate BTB
73         mcrne   p15, 0, ip, c7, c10, 4          @ drain write buffer
74         mcrne   p15, 0, ip, c7, c5, 4           @ prefetch flush
75         ret     lr
76
77 /*
78  *      flush_user_cache_range(start, end, flags)
79  *
80  *      Invalidate a range of cache entries in the specified
81  *      address space.
82  *
83  *      - start - start address (inclusive, page aligned)
84  *      - end   - end address (exclusive, page aligned)
85  *      - flags - vma_area_struct flags describing address space
86  */
87 ENTRY(fa_flush_user_cache_range)
88         mov     ip, #0
89         sub     r3, r1, r0                      @ calculate total size
90         cmp     r3, #CACHE_DLIMIT               @ total size >= limit?
91         bhs     __flush_whole_cache             @ flush whole D cache
92
93 1:      tst     r2, #VM_EXEC
94         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I line
95         mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
96         add     r0, r0, #CACHE_DLINESIZE
97         cmp     r0, r1
98         blo     1b
99         tst     r2, #VM_EXEC
100         mcrne   p15, 0, ip, c7, c5, 6           @ invalidate BTB
101         mcrne   p15, 0, ip, c7, c10, 4          @ data write barrier
102         mcrne   p15, 0, ip, c7, c5, 4           @ prefetch flush
103         ret     lr
104
105 /*
106  *      coherent_kern_range(start, end)
107  *
108  *      Ensure coherency between the Icache and the Dcache in the
109  *      region described by start.  If you have non-snooping
110  *      Harvard caches, you need to implement this function.
111  *
112  *      - start  - virtual start address
113  *      - end    - virtual end address
114  */
115 ENTRY(fa_coherent_kern_range)
116         /* fall through */
117
118 /*
119  *      coherent_user_range(start, end)
120  *
121  *      Ensure coherency between the Icache and the Dcache in the
122  *      region described by start.  If you have non-snooping
123  *      Harvard caches, you need to implement this function.
124  *
125  *      - start  - virtual start address
126  *      - end    - virtual end address
127  */
128 ENTRY(fa_coherent_user_range)
129         bic     r0, r0, #CACHE_DLINESIZE - 1
130 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
131         mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
132         add     r0, r0, #CACHE_DLINESIZE
133         cmp     r0, r1
134         blo     1b
135         mov     r0, #0
136         mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
137         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
138         mcr     p15, 0, r0, c7, c5, 4           @ prefetch flush
139         ret     lr
140
141 /*
142  *      flush_kern_dcache_area(void *addr, size_t size)
143  *
144  *      Ensure that the data held in the page kaddr is written back
145  *      to the page in question.
146  *
147  *      - addr  - kernel address
148  *      - size  - size of region
149  */
150 ENTRY(fa_flush_kern_dcache_area)
151         add     r1, r0, r1
152 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
153         add     r0, r0, #CACHE_DLINESIZE
154         cmp     r0, r1
155         blo     1b
156         mov     r0, #0
157         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
158         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
159         ret     lr
160
161 /*
162  *      dma_inv_range(start, end)
163  *
164  *      Invalidate (discard) the specified virtual address range.
165  *      May not write back any entries.  If 'start' or 'end'
166  *      are not cache line aligned, those lines must be written
167  *      back.
168  *
169  *      - start  - virtual start address
170  *      - end    - virtual end address
171  */
172 fa_dma_inv_range:
173         tst     r0, #CACHE_DLINESIZE - 1
174         bic     r0, r0, #CACHE_DLINESIZE - 1
175         mcrne   p15, 0, r0, c7, c14, 1          @ clean & invalidate D entry
176         tst     r1, #CACHE_DLINESIZE - 1
177         bic     r1, r1, #CACHE_DLINESIZE - 1
178         mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D entry
179 1:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
180         add     r0, r0, #CACHE_DLINESIZE
181         cmp     r0, r1
182         blo     1b
183         mov     r0, #0
184         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
185         ret     lr
186
187 /*
188  *      dma_clean_range(start, end)
189  *
190  *      Clean (write back) the specified virtual address range.
191  *
192  *      - start  - virtual start address
193  *      - end    - virtual end address
194  */
195 fa_dma_clean_range:
196         bic     r0, r0, #CACHE_DLINESIZE - 1
197 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
198         add     r0, r0, #CACHE_DLINESIZE
199         cmp     r0, r1
200         blo     1b
201         mov     r0, #0  
202         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
203         ret     lr
204
205 /*
206  *      dma_flush_range(start,end)
207  *      - start   - virtual start address of region
208  *      - end     - virtual end address of region
209  */
210 ENTRY(fa_dma_flush_range)
211         bic     r0, r0, #CACHE_DLINESIZE - 1
212 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D entry
213         add     r0, r0, #CACHE_DLINESIZE
214         cmp     r0, r1
215         blo     1b
216         mov     r0, #0  
217         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
218         ret     lr
219
220 /*
221  *      dma_map_area(start, size, dir)
222  *      - start - kernel virtual start address
223  *      - size  - size of region
224  *      - dir   - DMA direction
225  */
226 ENTRY(fa_dma_map_area)
227         add     r1, r1, r0
228         cmp     r2, #DMA_TO_DEVICE
229         beq     fa_dma_clean_range
230         bcs     fa_dma_inv_range
231         b       fa_dma_flush_range
232 ENDPROC(fa_dma_map_area)
233
234 /*
235  *      dma_unmap_area(start, size, dir)
236  *      - start - kernel virtual start address
237  *      - size  - size of region
238  *      - dir   - DMA direction
239  */
240 ENTRY(fa_dma_unmap_area)
241         ret     lr
242 ENDPROC(fa_dma_unmap_area)
243
244         .globl  fa_flush_kern_cache_louis
245         .equ    fa_flush_kern_cache_louis, fa_flush_kern_cache_all
246
247         __INITDATA
248
249         @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
250         define_cache_functions fa