Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[deliverable/linux.git] / arch / blackfin / mach-common / cache.S
CommitLineData
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
38ENTRY(_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 73ENDPROC(_cache_invalidate)
1394f032
BW
74
75/* Invalidate the Entire Instruction cache by
76 * disabling IMC bit
77 */
78ENTRY(_icache_invalidate)
79ENTRY(_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
110ENDPROC(_invalidate_entire_icache)
111ENDPROC(_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 */
121ENTRY(_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];
1281:
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 135ENDPROC(_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
146ENTRY(_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];
1531:
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 162ENDPROC(_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
172ENTRY(_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];
1791:
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 191ENDPROC(_blackfin_dcache_invalidate_range)
1394f032
BW
192
193/* Invalidate the Entire Data cache by
194 * clearing DMC[1:0] bits
195 */
196ENTRY(_invalidate_entire_dcache)
197ENTRY(_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
230ENDPROC(_dcache_invalidate)
231ENDPROC(_invalidate_entire_dcache)
1394f032
BW
232
233ENTRY(_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];
2401:
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 252ENDPROC(_blackfin_dcache_flush_range)
1394f032
BW
253
254ENTRY(_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 263ENDPROC(_blackfin_dflush_page)
This page took 0.132394 seconds and 5 git commands to generate.