Commit | Line | Data |
---|---|---|
1394f032 BW |
1 | /* |
2 | * File: arch/blackfin/mach-common/cache.S | |
3 | * Based on: | |
4 | * Author: LG Soft India | |
5 | * | |
6 | * Created: | |
7 | * Description: cache control support | |
8 | * | |
9 | * Modified: | |
10 | * Copyright 2004-2006 Analog Devices Inc. | |
11 | * | |
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or modify | |
15 | * it under the terms of the GNU General Public License as published by | |
16 | * the Free Software Foundation; either version 2 of the License, or | |
17 | * (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; if not, see the file COPYING, or write | |
26 | * to the Free Software Foundation, Inc., | |
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
28 | */ | |
29 | ||
30 | #include <linux/linkage.h> | |
31 | #include <asm/cplb.h> | |
32 | #include <asm/entry.h> | |
33 | #include <asm/blackfin.h> | |
34 | #include <asm/cache.h> | |
35 | ||
36 | .text | |
37 | .align 2 | |
38 | ENTRY(_cache_invalidate) | |
39 | ||
40 | /* | |
41 | * Icache or DcacheA or DcacheB Invalidation | |
42 | * or any combination thereof | |
43 | * R0 has bits | |
44 | * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P | |
45 | * set as required | |
46 | */ | |
47 | [--SP] = R7; | |
48 | ||
49 | R7 = R0; | |
50 | CC = BITTST(R7,CPLB_ENABLE_ICACHE_P); | |
51 | IF !CC JUMP .Lno_icache; | |
52 | [--SP] = RETS; | |
53 | CALL _icache_invalidate; | |
54 | RETS = [SP++]; | |
55 | .Lno_icache: | |
56 | CC = BITTST(R7,CPLB_ENABLE_DCACHE_P); | |
57 | IF !CC JUMP .Lno_dcache_a; | |
58 | R0 = 0; /* specifies bank A */ | |
59 | [--SP] = RETS; | |
60 | CALL _dcache_invalidate; | |
61 | RETS = [SP++]; | |
62 | .Lno_dcache_a: | |
63 | CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P); | |
64 | IF !CC JUMP .Lno_dcache_b; | |
65 | R0 = 0; | |
66 | BITSET(R0, 23); /* specifies bank B */ | |
67 | [--SP] = RETS; | |
68 | CALL _dcache_invalidate; | |
69 | RETS = [SP++]; | |
70 | .Lno_dcache_b: | |
71 | R7 = [SP++]; | |
72 | RTS; | |
51be24c3 | 73 | ENDPROC(_cache_invalidate) |
1394f032 BW |
74 | |
75 | /* Invalidate the Entire Instruction cache by | |
76 | * disabling IMC bit | |
77 | */ | |
78 | ENTRY(_icache_invalidate) | |
79 | ENTRY(_invalidate_entire_icache) | |
80 | [--SP] = ( R7:5); | |
81 | ||
e208f83a MF |
82 | P0.L = LO(IMEM_CONTROL); |
83 | P0.H = HI(IMEM_CONTROL); | |
1394f032 BW |
84 | R7 = [P0]; |
85 | ||
86 | /* Clear the IMC bit , All valid bits in the instruction | |
87 | * cache are set to the invalid state | |
88 | */ | |
89 | BITCLR(R7,IMC_P); | |
90 | CLI R6; | |
91 | SSYNC; /* SSYNC required before invalidating cache. */ | |
92 | .align 8; | |
93 | [P0] = R7; | |
94 | SSYNC; | |
95 | STI R6; | |
96 | ||
97 | /* Configures the instruction cache agian */ | |
98 | R6 = (IMC | ENICPLB); | |
99 | R7 = R7 | R6; | |
100 | ||
101 | CLI R6; | |
102 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ | |
103 | .align 8; | |
104 | [P0] = R7; | |
105 | SSYNC; | |
106 | STI R6; | |
107 | ||
108 | ( R7:5) = [SP++]; | |
109 | RTS; | |
51be24c3 MF |
110 | ENDPROC(_invalidate_entire_icache) |
111 | ENDPROC(_icache_invalidate) | |
1394f032 BW |
112 | |
113 | /* | |
114 | * blackfin_cache_flush_range(start, end) | |
115 | * Invalidate all cache lines assocoiated with this | |
116 | * area of memory. | |
117 | * | |
118 | * start: Start address | |
119 | * end: End address | |
120 | */ | |
121 | ENTRY(_blackfin_icache_flush_range) | |
122 | R2 = -L1_CACHE_BYTES; | |
123 | R2 = R0 & R2; | |
124 | P0 = R2; | |
125 | P1 = R1; | |
4bf3f3cb | 126 | CSYNC(R3); |
1394f032 BW |
127 | IFLUSH [P0]; |
128 | 1: | |
129 | IFLUSH [P0++]; | |
130 | CC = P0 < P1 (iu); | |
131 | IF CC JUMP 1b (bp); | |
132 | IFLUSH [P0]; | |
4bf3f3cb | 133 | SSYNC(R3); |
1394f032 | 134 | RTS; |
51be24c3 | 135 | ENDPROC(_blackfin_icache_flush_range) |
1394f032 BW |
136 | |
137 | /* | |
138 | * blackfin_icache_dcache_flush_range(start, end) | |
139 | * FLUSH all cache lines assocoiated with this | |
140 | * area of memory. | |
141 | * | |
142 | * start: Start address | |
143 | * end: End address | |
144 | */ | |
145 | ||
146 | ENTRY(_blackfin_icache_dcache_flush_range) | |
147 | R2 = -L1_CACHE_BYTES; | |
148 | R2 = R0 & R2; | |
149 | P0 = R2; | |
150 | P1 = R1; | |
4bf3f3cb | 151 | CSYNC(R3); |
1394f032 BW |
152 | IFLUSH [P0]; |
153 | 1: | |
154 | FLUSH [P0]; | |
155 | IFLUSH [P0++]; | |
156 | CC = P0 < P1 (iu); | |
157 | IF CC JUMP 1b (bp); | |
158 | IFLUSH [P0]; | |
159 | FLUSH [P0]; | |
4bf3f3cb | 160 | SSYNC(R3); |
1394f032 | 161 | RTS; |
51be24c3 | 162 | ENDPROC(_blackfin_icache_dcache_flush_range) |
1394f032 BW |
163 | |
164 | /* Throw away all D-cached data in specified region without any obligation to | |
165 | * write them back. However, we must clean the D-cached entries around the | |
166 | * boundaries of the start and/or end address is not cache aligned. | |
167 | * | |
168 | * Start: start address, | |
169 | * end : end address. | |
170 | */ | |
171 | ||
172 | ENTRY(_blackfin_dcache_invalidate_range) | |
173 | R2 = -L1_CACHE_BYTES; | |
174 | R2 = R0 & R2; | |
175 | P0 = R2; | |
176 | P1 = R1; | |
4bf3f3cb | 177 | CSYNC(R3); |
1394f032 BW |
178 | FLUSHINV[P0]; |
179 | 1: | |
180 | FLUSHINV[P0++]; | |
181 | CC = P0 < P1 (iu); | |
182 | IF CC JUMP 1b (bp); | |
183 | ||
184 | /* If the data crosses a cache line, then we'll be pointing to | |
185 | * the last cache line, but won't have flushed/invalidated it yet, | |
186 | * so do one more. | |
187 | */ | |
188 | FLUSHINV[P0]; | |
4bf3f3cb | 189 | SSYNC(R3); |
1394f032 | 190 | RTS; |
51be24c3 | 191 | ENDPROC(_blackfin_dcache_invalidate_range) |
1394f032 BW |
192 | |
193 | /* Invalidate the Entire Data cache by | |
194 | * clearing DMC[1:0] bits | |
195 | */ | |
196 | ENTRY(_invalidate_entire_dcache) | |
197 | ENTRY(_dcache_invalidate) | |
198 | [--SP] = ( R7:6); | |
199 | ||
e208f83a MF |
200 | P0.L = LO(DMEM_CONTROL); |
201 | P0.H = HI(DMEM_CONTROL); | |
1394f032 BW |
202 | R7 = [P0]; |
203 | ||
204 | /* Clear the DMC[1:0] bits, All valid bits in the data | |
205 | * cache are set to the invalid state | |
206 | */ | |
207 | BITCLR(R7,DMC0_P); | |
208 | BITCLR(R7,DMC1_P); | |
209 | CLI R6; | |
210 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ | |
211 | .align 8; | |
212 | [P0] = R7; | |
213 | SSYNC; | |
214 | STI R6; | |
215 | ||
216 | /* Configures the data cache again */ | |
217 | ||
218 | R6 = DMEM_CNTR; | |
219 | R7 = R7 | R6; | |
220 | ||
221 | CLI R6; | |
222 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ | |
223 | .align 8; | |
224 | [P0] = R7; | |
225 | SSYNC; | |
226 | STI R6; | |
227 | ||
228 | ( R7:6) = [SP++]; | |
229 | RTS; | |
51be24c3 MF |
230 | ENDPROC(_dcache_invalidate) |
231 | ENDPROC(_invalidate_entire_dcache) | |
1394f032 BW |
232 | |
233 | ENTRY(_blackfin_dcache_flush_range) | |
234 | R2 = -L1_CACHE_BYTES; | |
235 | R2 = R0 & R2; | |
236 | P0 = R2; | |
237 | P1 = R1; | |
4bf3f3cb | 238 | CSYNC(R3); |
1394f032 BW |
239 | FLUSH[P0]; |
240 | 1: | |
241 | FLUSH[P0++]; | |
242 | CC = P0 < P1 (iu); | |
243 | IF CC JUMP 1b (bp); | |
244 | ||
245 | /* If the data crosses a cache line, then we'll be pointing to | |
246 | * the last cache line, but won't have flushed it yet, so do | |
247 | * one more. | |
248 | */ | |
249 | FLUSH[P0]; | |
4bf3f3cb | 250 | SSYNC(R3); |
1394f032 | 251 | RTS; |
51be24c3 | 252 | ENDPROC(_blackfin_dcache_flush_range) |
1394f032 BW |
253 | |
254 | ENTRY(_blackfin_dflush_page) | |
255 | P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT); | |
256 | P0 = R0; | |
4bf3f3cb | 257 | CSYNC(R3); |
1394f032 BW |
258 | FLUSH[P0]; |
259 | LSETUP (.Lfl1, .Lfl1) LC0 = P1; | |
260 | .Lfl1: FLUSH [P0++]; | |
4bf3f3cb | 261 | SSYNC(R3); |
1394f032 | 262 | RTS; |
51be24c3 | 263 | ENDPROC(_blackfin_dflush_page) |