1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include <common.h>
35#include <command.h>
36#include <asm/system.h>
37
38static void cache_flush(void);
39
40int cleanup_before_linux (void)
41{
42
43
44
45
46
47
48
49 disable_interrupts ();
50
51#ifdef CONFIG_LCD
52 {
53 extern void lcd_disable(void);
54 extern void lcd_panel_disable(void);
55
56 lcd_disable();
57 lcd_panel_disable();
58 }
59#endif
60
61
62 icache_disable();
63 dcache_disable();
64
65 cache_flush();
66
67 return 0;
68}
69
70static void cache_flush(void)
71{
72 unsigned long i = 0;
73
74 asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
75
76 asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
77
78 asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
79}
80
81#ifndef CONFIG_SYS_DCACHE_OFF
82
83#ifndef CONFIG_SYS_CACHELINE_SIZE
84#define CONFIG_SYS_CACHELINE_SIZE 32
85#endif
86
87void invalidate_dcache_all(void)
88{
89 asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
90}
91
92void flush_dcache_all(void)
93{
94 asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
95 asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
96}
97
98static inline int bad_cache_range(unsigned long start, unsigned long stop)
99{
100 int ok = 1;
101
102 if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
103 ok = 0;
104
105 if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
106 ok = 0;
107
108 if (!ok)
109 debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
110 start, stop);
111
112 return ok;
113}
114
115void invalidate_dcache_range(unsigned long start, unsigned long stop)
116{
117 if (bad_cache_range(start, stop))
118 return;
119
120 while (start < stop) {
121 asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
122 start += CONFIG_SYS_CACHELINE_SIZE;
123 }
124}
125
126void flush_dcache_range(unsigned long start, unsigned long stop)
127{
128 if (bad_cache_range(start, stop))
129 return;
130
131 while (start < stop) {
132 asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
133 start += CONFIG_SYS_CACHELINE_SIZE;
134 }
135
136 asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
137}
138
139void flush_cache(unsigned long start, unsigned long size)
140{
141 flush_dcache_range(start, start + size);
142}
143
144void enable_caches(void)
145{
146#ifndef CONFIG_SYS_ICACHE_OFF
147 icache_enable();
148#endif
149#ifndef CONFIG_SYS_DCACHE_OFF
150 dcache_enable();
151#endif
152}
153
154#else
155void invalidate_dcache_all(void)
156{
157}
158
159void flush_dcache_all(void)
160{
161}
162
163void invalidate_dcache_range(unsigned long start, unsigned long stop)
164{
165}
166
167void flush_dcache_range(unsigned long start, unsigned long stop)
168{
169}
170
171void flush_cache(unsigned long start, unsigned long size)
172{
173}
174#endif
175