Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / arch / arm / mm / cache-fa.S
blob4a3668b52a2db076b92ebfed6fd42f59d692842f
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 <linux/cfi_types.h>
16 #include <asm/assembler.h>
17 #include <asm/page.h>
19 #include "proc-macros.S"
22  * The size of one data cache line.
23  */
24 #define CACHE_DLINESIZE 16
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 
35 /* FIXME: put optimal value here. Current one is just estimation */
36 #define CACHE_DLIMIT    (CACHE_DSIZE * 2)
39  *      flush_icache_all()
40  *
41  *      Unconditionally clean and invalidate the entire icache.
42  */
43 SYM_TYPED_FUNC_START(fa_flush_icache_all)
44         mov     r0, #0
45         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
46         ret     lr
47 SYM_FUNC_END(fa_flush_icache_all)
50  *      flush_user_cache_all()
51  *
52  *      Clean and invalidate all cache entries in a particular address
53  *      space.
54  */
55 SYM_FUNC_ALIAS(fa_flush_user_cache_all, fa_flush_kern_cache_all)
58  *      flush_kern_cache_all()
59  *
60  *      Clean and invalidate the entire cache.
61  */
62 SYM_TYPED_FUNC_START(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 SYM_FUNC_END(fa_flush_kern_cache_all)
76  *      flush_user_cache_range(start, end, flags)
77  *
78  *      Invalidate a range of cache entries in the specified
79  *      address space.
80  *
81  *      - start - start address (inclusive, page aligned)
82  *      - end   - end address (exclusive, page aligned)
83  *      - flags - vma_area_struct flags describing address space
84  */
85 SYM_TYPED_FUNC_START(fa_flush_user_cache_range)
86         mov     ip, #0
87         sub     r3, r1, r0                      @ calculate total size
88         cmp     r3, #CACHE_DLIMIT               @ total size >= limit?
89         bhs     __flush_whole_cache             @ flush whole D cache
91 1:      tst     r2, #VM_EXEC
92         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I line
93         mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
94         add     r0, r0, #CACHE_DLINESIZE
95         cmp     r0, r1
96         blo     1b
97         tst     r2, #VM_EXEC
98         mcrne   p15, 0, ip, c7, c5, 6           @ invalidate BTB
99         mcrne   p15, 0, ip, c7, c10, 4          @ data write barrier
100         mcrne   p15, 0, ip, c7, c5, 4           @ prefetch flush
101         ret     lr
102 SYM_FUNC_END(fa_flush_user_cache_range)
105  *      coherent_kern_range(start, end)
107  *      Ensure coherency between the Icache and the Dcache in the
108  *      region described by start.  If you have non-snooping
109  *      Harvard caches, you need to implement this function.
111  *      - start  - virtual start address
112  *      - end    - virtual end address
113  */
114 SYM_TYPED_FUNC_START(fa_coherent_kern_range)
115 #ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
116         b       fa_coherent_user_range
117 #endif
118 SYM_FUNC_END(fa_coherent_kern_range)
121  *      coherent_user_range(start, end)
123  *      Ensure coherency between the Icache and the Dcache in the
124  *      region described by start.  If you have non-snooping
125  *      Harvard caches, you need to implement this function.
127  *      - start  - virtual start address
128  *      - end    - virtual end address
129  */
130 SYM_TYPED_FUNC_START(fa_coherent_user_range)
131         bic     r0, r0, #CACHE_DLINESIZE - 1
132 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
133         mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
134         add     r0, r0, #CACHE_DLINESIZE
135         cmp     r0, r1
136         blo     1b
137         mov     r0, #0
138         mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
139         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
140         mcr     p15, 0, r0, c7, c5, 4           @ prefetch flush
141         ret     lr
142 SYM_FUNC_END(fa_coherent_user_range)
145  *      flush_kern_dcache_area(void *addr, size_t size)
147  *      Ensure that the data held in the page kaddr is written back
148  *      to the page in question.
150  *      - addr  - kernel address
151  *      - size  - size of region
152  */
153 SYM_TYPED_FUNC_START(fa_flush_kern_dcache_area)
154         add     r1, r0, r1
155 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
156         add     r0, r0, #CACHE_DLINESIZE
157         cmp     r0, r1
158         blo     1b
159         mov     r0, #0
160         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
161         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
162         ret     lr
163 SYM_FUNC_END(fa_flush_kern_dcache_area)
166  *      dma_inv_range(start, end)
168  *      Invalidate (discard) the specified virtual address range.
169  *      May not write back any entries.  If 'start' or 'end'
170  *      are not cache line aligned, those lines must be written
171  *      back.
173  *      - start  - virtual start address
174  *      - end    - virtual end address
175  */
176 fa_dma_inv_range:
177         tst     r0, #CACHE_DLINESIZE - 1
178         bic     r0, r0, #CACHE_DLINESIZE - 1
179         mcrne   p15, 0, r0, c7, c14, 1          @ clean & invalidate D entry
180         tst     r1, #CACHE_DLINESIZE - 1
181         bic     r1, r1, #CACHE_DLINESIZE - 1
182         mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D entry
183 1:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
184         add     r0, r0, #CACHE_DLINESIZE
185         cmp     r0, r1
186         blo     1b
187         mov     r0, #0
188         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
189         ret     lr
192  *      dma_clean_range(start, end)
194  *      Clean (write back) the specified virtual address range.
196  *      - start  - virtual start address
197  *      - end    - virtual end address
198  */
199 fa_dma_clean_range:
200         bic     r0, r0, #CACHE_DLINESIZE - 1
201 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
202         add     r0, r0, #CACHE_DLINESIZE
203         cmp     r0, r1
204         blo     1b
205         mov     r0, #0  
206         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
207         ret     lr
210  *      dma_flush_range(start,end)
211  *      - start   - virtual start address of region
212  *      - end     - virtual end address of region
213  */
214 SYM_TYPED_FUNC_START(fa_dma_flush_range)
215         bic     r0, r0, #CACHE_DLINESIZE - 1
216 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D entry
217         add     r0, r0, #CACHE_DLINESIZE
218         cmp     r0, r1
219         blo     1b
220         mov     r0, #0  
221         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
222         ret     lr
223 SYM_FUNC_END(fa_dma_flush_range)
226  *      dma_map_area(start, size, dir)
227  *      - start - kernel virtual start address
228  *      - size  - size of region
229  *      - dir   - DMA direction
230  */
231 SYM_TYPED_FUNC_START(fa_dma_map_area)
232         add     r1, r1, r0
233         cmp     r2, #DMA_TO_DEVICE
234         beq     fa_dma_clean_range
235         bcs     fa_dma_inv_range
236         b       fa_dma_flush_range
237 SYM_FUNC_END(fa_dma_map_area)
240  *      dma_unmap_area(start, size, dir)
241  *      - start - kernel virtual start address
242  *      - size  - size of region
243  *      - dir   - DMA direction
244  */
245 SYM_TYPED_FUNC_START(fa_dma_unmap_area)
246         ret     lr
247 SYM_FUNC_END(fa_dma_unmap_area)