Merge branches 'core/softlockup', 'core/softirq', 'core/resources', 'core/printk...
[linux-2.6] / arch / blackfin / mach-common / cache.S
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
38 /*
39  * blackfin_cache_flush_range(start, end)
40  * Invalidate all cache lines assocoiated with this
41  * area of memory.
42  *
43  * start:       Start address
44  * end:         End address
45  */
46 ENTRY(_blackfin_icache_flush_range)
47         R2 = -L1_CACHE_BYTES;
48         R2 = R0 & R2;
49         P0 = R2;
50         P1 = R1;
51         CSYNC(R3);
52         IFLUSH [P0];
53 1:
54         IFLUSH [P0++];
55         CC = P0 < P1 (iu);
56         IF CC JUMP 1b (bp);
57         IFLUSH [P0];
58         SSYNC(R3);
59         RTS;
60 ENDPROC(_blackfin_icache_flush_range)
61
62 /*
63  * blackfin_icache_dcache_flush_range(start, end)
64  * FLUSH all cache lines assocoiated with this
65  * area of memory.
66  *
67  * start:       Start address
68  * end:         End address
69  */
70
71 ENTRY(_blackfin_icache_dcache_flush_range)
72         R2 = -L1_CACHE_BYTES;
73         R2 = R0 & R2;
74         P0 = R2;
75         P1 = R1;
76         CSYNC(R3);
77         IFLUSH [P0];
78 1:
79         FLUSH [P0];
80         IFLUSH [P0++];
81         CC = P0 < P1 (iu);
82         IF CC JUMP 1b (bp);
83         IFLUSH [P0];
84         FLUSH [P0];
85         SSYNC(R3);
86         RTS;
87 ENDPROC(_blackfin_icache_dcache_flush_range)
88
89 /* Throw away all D-cached data in specified region without any obligation to
90  * write them back. However, we must clean the D-cached entries around the
91  * boundaries of the start and/or end address is not cache aligned.
92  *
93  * Start: start address,
94  * end  : end address.
95  */
96
97 ENTRY(_blackfin_dcache_invalidate_range)
98         R2 = -L1_CACHE_BYTES;
99         R2 = R0 & R2;
100         P0 = R2;
101         P1 = R1;
102         CSYNC(R3);
103         FLUSHINV[P0];
104 1:
105         FLUSHINV[P0++];
106         CC = P0 < P1 (iu);
107         IF CC JUMP 1b (bp);
108
109         /* If the data crosses a cache line, then we'll be pointing to
110          * the last cache line, but won't have flushed/invalidated it yet,
111          * so do one more.
112          */
113         FLUSHINV[P0];
114         SSYNC(R3);
115         RTS;
116 ENDPROC(_blackfin_dcache_invalidate_range)
117
118 ENTRY(_blackfin_dcache_flush_range)
119         R2 = -L1_CACHE_BYTES;
120         R2 = R0 & R2;
121         P0 = R2;
122         P1 = R1;
123         CSYNC(R3);
124         FLUSH[P0];
125 1:
126         FLUSH[P0++];
127         CC = P0 < P1 (iu);
128         IF CC JUMP 1b (bp);
129
130         /* If the data crosses a cache line, then we'll be pointing to
131          * the last cache line, but won't have flushed it yet, so do
132          * one more.
133          */
134         FLUSH[P0];
135         SSYNC(R3);
136         RTS;
137 ENDPROC(_blackfin_dcache_flush_range)
138
139 ENTRY(_blackfin_dflush_page)
140         P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT);
141         P0 = R0;
142         CSYNC(R3);
143         FLUSH[P0];
144         LSETUP (.Lfl1, .Lfl1) LC0 = P1;
145 .Lfl1:  FLUSH [P0++];
146         SSYNC(R3);
147         RTS;
148 ENDPROC(_blackfin_dflush_page)