arm64: dts: rk3368-android: reserve memory for drm-logo
[firefly-linux-kernel-4.4.55.git] / arch / arm64 / mm / cache.S
1 /*
2  * Cache maintenance
3  *
4  * Copyright (C) 2001 Deep Blue Solutions Ltd.
5  * Copyright (C) 2012 ARM Ltd.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/errno.h>
21 #include <linux/linkage.h>
22 #include <linux/init.h>
23 #include <asm/assembler.h>
24 #include <asm/cpufeature.h>
25 #include <asm/alternative.h>
26 #include <asm/uaccess.h>
27
28 /*
29  *      flush_icache_range(start,end)
30  *
31  *      Ensure that the I and D caches are coherent within specified region.
32  *      This is typically used when code has been written to a memory region,
33  *      and will be executed.
34  *
35  *      - start   - virtual start address of region
36  *      - end     - virtual end address of region
37  */
38 ENTRY(flush_icache_range)
39         /* FALLTHROUGH */
40
41 /*
42  *      __flush_cache_user_range(start,end)
43  *
44  *      Ensure that the I and D caches are coherent within specified region.
45  *      This is typically used when code has been written to a memory region,
46  *      and will be executed.
47  *
48  *      - start   - virtual start address of region
49  *      - end     - virtual end address of region
50  */
51 ENTRY(__flush_cache_user_range)
52         uaccess_ttbr0_enable x2, x3
53         dcache_line_size x2, x3
54         sub     x3, x2, #1
55         bic     x4, x0, x3
56 1:
57 user_alt 9f, "dc cvau, x4",  "dc civac, x4",  ARM64_WORKAROUND_CLEAN_CACHE
58         add     x4, x4, x2
59         cmp     x4, x1
60         b.lo    1b
61         dsb     ish
62
63         icache_line_size x2, x3
64         sub     x3, x2, #1
65         bic     x4, x0, x3
66 1:
67 USER(9f, ic     ivau, x4        )               // invalidate I line PoU
68         add     x4, x4, x2
69         cmp     x4, x1
70         b.lo    1b
71         dsb     ish
72         isb
73         mov     x0, #0
74 1:
75         uaccess_ttbr0_disable x1
76         ret
77 9:
78         mov     x0, #-EFAULT
79         b       1b
80 ENDPROC(flush_icache_range)
81 ENDPROC(__flush_cache_user_range)
82
83 /*
84  *      __flush_dcache_area(kaddr, size)
85  *
86  *      Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
87  *      are cleaned and invalidated to the PoC.
88  *
89  *      - kaddr   - kernel address
90  *      - size    - size in question
91  */
92 ENTRY(__flush_dcache_area)
93         dcache_by_line_op civac, sy, x0, x1, x2, x3
94         ret
95 ENDPIPROC(__flush_dcache_area)
96
97 /*
98  *      __clean_dcache_area_pou(kaddr, size)
99  *
100  *      Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
101  *      are cleaned to the PoU.
102  *
103  *      - kaddr   - kernel address
104  *      - size    - size in question
105  */
106 ENTRY(__clean_dcache_area_pou)
107         dcache_by_line_op cvau, ish, x0, x1, x2, x3
108         ret
109 ENDPROC(__clean_dcache_area_pou)
110
111 /*
112  *      __inval_cache_range(start, end)
113  *      - start   - start address of region
114  *      - end     - end address of region
115  */
116 ENTRY(__inval_cache_range)
117         /* FALLTHROUGH */
118
119 /*
120  *      __dma_inv_range(start, end)
121  *      - start   - virtual start address of region
122  *      - end     - virtual end address of region
123  */
124 __dma_inv_range:
125         dcache_line_size x2, x3
126         sub     x3, x2, #1
127         tst     x1, x3                          // end cache line aligned?
128         bic     x1, x1, x3
129         b.eq    1f
130         dc      civac, x1                       // clean & invalidate D / U line
131 1:      tst     x0, x3                          // start cache line aligned?
132         bic     x0, x0, x3
133         b.eq    2f
134         dc      civac, x0                       // clean & invalidate D / U line
135         b       3f
136 2:      dc      ivac, x0                        // invalidate D / U line
137 3:      add     x0, x0, x2
138         cmp     x0, x1
139         b.lo    2b
140         dsb     sy
141         ret
142 ENDPIPROC(__inval_cache_range)
143 ENDPROC(__dma_inv_range)
144
145 /*
146  *      __dma_clean_range(start, end)
147  *      - start   - virtual start address of region
148  *      - end     - virtual end address of region
149  */
150 __dma_clean_range:
151         dcache_line_size x2, x3
152         sub     x3, x2, #1
153         bic     x0, x0, x3
154 1:
155 alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
156         dc      cvac, x0
157 alternative_else
158         dc      civac, x0
159 alternative_endif
160         add     x0, x0, x2
161         cmp     x0, x1
162         b.lo    1b
163         dsb     sy
164         ret
165 ENDPROC(__dma_clean_range)
166
167 /*
168  *      __dma_flush_range(start, end)
169  *      - start   - virtual start address of region
170  *      - end     - virtual end address of region
171  */
172 ENTRY(__dma_flush_range)
173         dcache_line_size x2, x3
174         sub     x3, x2, #1
175         bic     x0, x0, x3
176 1:      dc      civac, x0                       // clean & invalidate D / U line
177         add     x0, x0, x2
178         cmp     x0, x1
179         b.lo    1b
180         dsb     sy
181         ret
182 ENDPIPROC(__dma_flush_range)
183
184 /*
185  *      __dma_map_area(start, size, dir)
186  *      - start - kernel virtual start address
187  *      - size  - size of region
188  *      - dir   - DMA direction
189  */
190 ENTRY(__dma_map_area)
191         add     x1, x1, x0
192         cmp     w2, #DMA_FROM_DEVICE
193         b.eq    __dma_inv_range
194         b       __dma_clean_range
195 ENDPIPROC(__dma_map_area)
196
197 /*
198  *      __dma_unmap_area(start, size, dir)
199  *      - start - kernel virtual start address
200  *      - size  - size of region
201  *      - dir   - DMA direction
202  */
203 ENTRY(__dma_unmap_area)
204         add     x1, x1, x0
205         cmp     w2, #DMA_TO_DEVICE
206         b.ne    __dma_inv_range
207         ret
208 ENDPIPROC(__dma_unmap_area)