]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm926ejs/cache.c
Use the correct parameters in the flush_dcache_range() and flush_cache() functions
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / cache.c
1 /*
2  * (C) Copyright 2011
3  * Ilya Yanok, EmCraft Systems
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc.
21  */
22 #include <linux/types.h>
23 #include <common.h>
24
25 #define DCACHE_SIZE                     0x4000    // 16KB Size of data cache in bytes
26 #define DCACHE_LINE_SIZE                32    // Size of a data cache line
27 #define DCACHE_WAYS                     64    // Associativity of the cache
28 /*
29  * This is the maximum size of an area which will be invalidated
30  * using the single invalidate entry instructions.  Anything larger
31  * than this, and we go for the whole cache.
32  *
33  * This value should be chosen such that we choose the cheapest
34  * alternative.
35  */
36 #define CACHE_DLIMIT                    16384
37
38 #ifndef CONFIG_SYS_DCACHE_OFF
39 void invalidate_dcache_all(void)
40 {
41         asm volatile (
42                 "mcr    p15, 0, %0, c7, c6, 0\n" /* invalidate d-cache */
43                 "mcr    p15, 0, %0, c7, c5, 0\n" /* invalidate I cache */
44                 "mcr    p15, 0, %0, c7, c10, 4\n" /* data write back */
45                 :
46                 : "r"(0)
47                 : "memory");
48 }
49
50 void invalidate_dcache_range(unsigned long start, unsigned long end)
51 {
52         asm volatile (
53 #ifndef CONFIG_SYS_ARM_CACHE_WRITETHROUGH
54                 "tst    %1, %4\n"
55                 "mcrne  p15, 0, %1, c7, c10, 1\n" /* clean D entry */
56                 "tst    %2, %4\n"
57                 "mcrne  p15, 0, %2, c7, c10, 1\n" /* clean D entry */
58 #endif
59                 "bic    %1, %1, %4\n"
60                 "add    %2, %2, %4\n"
61                 "bic    %2, %2, %4\n"
62                 "1:\n"
63                 "mcr    p15, 0, %1, c7, c6, 1\n" /* invalidate D cache entry */
64                 "add    %1, %1, %3\n"
65                 "cmp    %1, %2\n"
66                 "blo    1b\n"
67                 "mcr    p15, 0, %0, c7, c5, 0\n" /* invalidate I cache */
68                 "mcr    p15, 0, %0, c7, c10, 4\n" /* data write back */
69                 :
70                 : "r"(0), "r"(start), "r"(end),
71                   "I"(DCACHE_LINE_SIZE),
72                   "I"(DCACHE_LINE_SIZE - 1)
73                 : "memory"
74                 );
75 }
76
77 #ifndef CONFIG_SYS_ARM_CACHE_WRITETHROUGH
78 void flush_dcache_range(unsigned long start, unsigned long end)
79 {
80         asm volatile (
81                 "bic    %1, %1, %4\n"
82                 "add    %2, %2, %4\n"
83                 "bic    %2, %2, %4\n"
84                 "1:\n"
85                 "mcr    p15, 0, %1, c7, c14, 1\n" /* clean and invalidate D entry */
86                 "add    %1, %1, %3\n"
87                 "cmp    %1, %2\n"
88                 "blo    1b\n"
89                 "mcr    p15, 0, %0, c7, c5, 0\n" /* invalidate I cache */
90                 "mcr    p15, 0, %0, c7, c10, 4\n" /* data write back */
91                 :
92                 : "r"(0), "r"(start), "r"(end),
93                   "I"(DCACHE_LINE_SIZE),
94                   "I"(DCACHE_LINE_SIZE - 1)
95                 : "memory"
96                 );
97 }
98
99 void flush_cache(unsigned long start, unsigned long size)
100 {
101         flush_dcache_range(start, start + size);
102 }
103
104 void flush_dcache_all(void)
105 {
106         asm volatile (
107                 "1:\n"
108                 "mrc    p15, 0, r15, c7, c14, 3\n" /* test,clean,invalidate */
109                 "bne    1b\n"
110                 "mcr    p15, 0, %0, c7, c5, 0\n" /* invalidate I cache */
111                 "mcr    p15, 0, %0, c7, c10, 4\n" /* data write back */
112                 :
113                 : "r"(0)
114                 : "memory"
115                 );
116 }
117 #else
118 void flush_dcache_range(unsigned long start, unsigned long end)
119 {
120         invalidate_dcache_range(start, end);
121 }
122
123 void flush_cache(unsigned long start, unsigned long end)
124 {
125         invalidate_dcache_range(start, end);
126 }
127
128 void flush_dcache_all(void)
129 {
130         invalidate_dcache_all();
131 }
132 #endif /* CONFIG_SYS_ARM_CACHE_WRITETHROUGH */
133
134 #else /* #ifndef CONFIG_SYS_DCACHE_OFF */
135 void invalidate_dcache_all(void)
136 {
137 }
138
139 void flush_dcache_all(void)
140 {
141 }
142
143 void invalidate_dcache_range(unsigned long start, unsigned long stop)
144 {
145 }
146
147 void flush_dcache_range(unsigned long start, unsigned long stop)
148 {
149 }
150
151 void  flush_cache(unsigned long start, unsigned long size)
152 {
153 }
154 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
155
156 /*
157  * Stub implementations for l2 cache operations
158  */
159 void __l2_cache_disable(void)
160 {
161 }
162 void l2_cache_disable(void)
163         __attribute__((weak, alias("__l2_cache_disable")));