aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/cache.S
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-05-06 17:50:22 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 15:12:58 -0400
commit1394f03221790a988afc3e4b3cb79f2e477246a9 (patch)
tree2c1963c9a4f2d84a5e021307fde240c5d567cf70 /arch/blackfin/mach-common/cache.S
parent73243284463a761e04d69d22c7516b2be7de096c (diff)
blackfin architecture
This adds support for the Analog Devices Blackfin processor architecture, and currently supports the BF533, BF532, BF531, BF537, BF536, BF534, and BF561 (Dual Core) devices, with a variety of development platforms including those avaliable from Analog Devices (BF533-EZKit, BF533-STAMP, BF537-STAMP, BF561-EZKIT), and Bluetechnix! Tinyboards. The Blackfin architecture was jointly developed by Intel and Analog Devices Inc. (ADI) as the Micro Signal Architecture (MSA) core and introduced it in December of 2000. Since then ADI has put this core into its Blackfin processor family of devices. The Blackfin core has the advantages of a clean, orthogonal,RISC-like microprocessor instruction set. It combines a dual-MAC (Multiply/Accumulate), state-of-the-art signal processing engine and single-instruction, multiple-data (SIMD) multimedia capabilities into a single instruction-set architecture. The Blackfin architecture, including the instruction set, is described by the ADSP-BF53x/BF56x Blackfin Processor Programming Reference http://blackfin.uclinux.org/gf/download/frsrelease/29/2549/Blackfin_PRM.pdf The Blackfin processor is already supported by major releases of gcc, and there are binary and source rpms/tarballs for many architectures at: http://blackfin.uclinux.org/gf/project/toolchain/frs There is complete documentation, including "getting started" guides available at: http://docs.blackfin.uclinux.org/ which provides links to the sources and patches you will need in order to set up a cross-compiling environment for bfin-linux-uclibc This patch, as well as the other patches (toolchain, distribution, uClibc) are actively supported by Analog Devices Inc, at: http://blackfin.uclinux.org/ We have tested this on LTP, and our test plan (including pass/fails) can be found at: http://docs.blackfin.uclinux.org/doku.php?id=testing_the_linux_kernel [m.kozlowski@tuxland.pl: balance parenthesis in blackfin header files] Signed-off-by: Bryan Wu <bryan.wu@analog.com> Signed-off-by: Mariusz Kozlowski <m.kozlowski@tuxland.pl> Signed-off-by: Aubrey Li <aubrey.li@analog.com> Signed-off-by: Jie Zhang <jie.zhang@analog.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/blackfin/mach-common/cache.S')
-rw-r--r--arch/blackfin/mach-common/cache.S253
1 files changed, 253 insertions, 0 deletions
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
new file mode 100644
index 000000000000..bb9446ef66ef
--- /dev/null
+++ b/arch/blackfin/mach-common/cache.S
@@ -0,0 +1,253 @@
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;
73
74/* Invalidate the Entire Instruction cache by
75 * disabling IMC bit
76 */
77ENTRY(_icache_invalidate)
78ENTRY(_invalidate_entire_icache)
79 [--SP] = ( R7:5);
80
81 P0.L = (IMEM_CONTROL & 0xFFFF);
82 P0.H = (IMEM_CONTROL >> 16);
83 R7 = [P0];
84
85 /* Clear the IMC bit , All valid bits in the instruction
86 * cache are set to the invalid state
87 */
88 BITCLR(R7,IMC_P);
89 CLI R6;
90 SSYNC; /* SSYNC required before invalidating cache. */
91 .align 8;
92 [P0] = R7;
93 SSYNC;
94 STI R6;
95
96 /* Configures the instruction cache agian */
97 R6 = (IMC | ENICPLB);
98 R7 = R7 | R6;
99
100 CLI R6;
101 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
102 .align 8;
103 [P0] = R7;
104 SSYNC;
105 STI R6;
106
107 ( R7:5) = [SP++];
108 RTS;
109
110/*
111 * blackfin_cache_flush_range(start, end)
112 * Invalidate all cache lines assocoiated with this
113 * area of memory.
114 *
115 * start: Start address
116 * end: End address
117 */
118ENTRY(_blackfin_icache_flush_range)
119 R2 = -L1_CACHE_BYTES;
120 R2 = R0 & R2;
121 P0 = R2;
122 P1 = R1;
123 CSYNC;
124 IFLUSH [P0];
1251:
126 IFLUSH [P0++];
127 CC = P0 < P1 (iu);
128 IF CC JUMP 1b (bp);
129 IFLUSH [P0];
130 SSYNC;
131 RTS;
132
133/*
134 * blackfin_icache_dcache_flush_range(start, end)
135 * FLUSH all cache lines assocoiated with this
136 * area of memory.
137 *
138 * start: Start address
139 * end: End address
140 */
141
142ENTRY(_blackfin_icache_dcache_flush_range)
143 R2 = -L1_CACHE_BYTES;
144 R2 = R0 & R2;
145 P0 = R2;
146 P1 = R1;
147 CSYNC;
148 IFLUSH [P0];
1491:
150 FLUSH [P0];
151 IFLUSH [P0++];
152 CC = P0 < P1 (iu);
153 IF CC JUMP 1b (bp);
154 IFLUSH [P0];
155 FLUSH [P0];
156 SSYNC;
157 RTS;
158
159/* Throw away all D-cached data in specified region without any obligation to
160 * write them back. However, we must clean the D-cached entries around the
161 * boundaries of the start and/or end address is not cache aligned.
162 *
163 * Start: start address,
164 * end : end address.
165 */
166
167ENTRY(_blackfin_dcache_invalidate_range)
168 R2 = -L1_CACHE_BYTES;
169 R2 = R0 & R2;
170 P0 = R2;
171 P1 = R1;
172 CSYNC;
173 FLUSHINV[P0];
1741:
175 FLUSHINV[P0++];
176 CC = P0 < P1 (iu);
177 IF CC JUMP 1b (bp);
178
179 /* If the data crosses a cache line, then we'll be pointing to
180 * the last cache line, but won't have flushed/invalidated it yet,
181 * so do one more.
182 */
183 FLUSHINV[P0];
184 SSYNC;
185 RTS;
186
187/* Invalidate the Entire Data cache by
188 * clearing DMC[1:0] bits
189 */
190ENTRY(_invalidate_entire_dcache)
191ENTRY(_dcache_invalidate)
192 [--SP] = ( R7:6);
193
194 P0.L = (DMEM_CONTROL & 0xFFFF);
195 P0.H = (DMEM_CONTROL >> 16);
196 R7 = [P0];
197
198 /* Clear the DMC[1:0] bits, All valid bits in the data
199 * cache are set to the invalid state
200 */
201 BITCLR(R7,DMC0_P);
202 BITCLR(R7,DMC1_P);
203 CLI R6;
204 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
205 .align 8;
206 [P0] = R7;
207 SSYNC;
208 STI R6;
209
210 /* Configures the data cache again */
211
212 R6 = DMEM_CNTR;
213 R7 = R7 | R6;
214
215 CLI R6;
216 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
217 .align 8;
218 [P0] = R7;
219 SSYNC;
220 STI R6;
221
222 ( R7:6) = [SP++];
223 RTS;
224
225ENTRY(_blackfin_dcache_flush_range)
226 R2 = -L1_CACHE_BYTES;
227 R2 = R0 & R2;
228 P0 = R2;
229 P1 = R1;
230 CSYNC;
231 FLUSH[P0];
2321:
233 FLUSH[P0++];
234 CC = P0 < P1 (iu);
235 IF CC JUMP 1b (bp);
236
237 /* If the data crosses a cache line, then we'll be pointing to
238 * the last cache line, but won't have flushed it yet, so do
239 * one more.
240 */
241 FLUSH[P0];
242 SSYNC;
243 RTS;
244
245ENTRY(_blackfin_dflush_page)
246 P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT);
247 P0 = R0;
248 CSYNC;
249 FLUSH[P0];
250 LSETUP (.Lfl1, .Lfl1) LC0 = P1;
251.Lfl1: FLUSH [P0++];
252 SSYNC;
253 RTS;