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