]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm11/cpu.c
ARM: cache: implement a default weak flush_cache() function
[karo-tx-uboot.git] / arch / arm / cpu / arm11 / cpu.c
1 /*
2  * (C) Copyright 2004 Texas Insturments
3  *
4  * (C) Copyright 2002
5  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6  * Marius Groeger <mgroeger@sysgo.de>
7  *
8  * (C) Copyright 2002
9  * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
10  *
11  * SPDX-License-Identifier:     GPL-2.0+
12  */
13
14 /*
15  * CPU specific code
16  */
17
18 #include <common.h>
19 #include <command.h>
20 #include <asm/system.h>
21
22 static void cache_flush(void);
23
24 int cleanup_before_linux (void)
25 {
26         /*
27          * this function is called just before we call linux
28          * it prepares the processor for linux
29          *
30          * we turn off caches etc ...
31          */
32
33         disable_interrupts ();
34
35         /* turn off I/D-cache */
36         icache_disable();
37         dcache_disable();
38         /* flush I/D-cache */
39         cache_flush();
40
41         return 0;
42 }
43
44 static void cache_flush(void)
45 {
46         unsigned long i = 0;
47         /* clean entire data cache */
48         asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
49         /* invalidate both caches and flush btb */
50         asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
51         /* mem barrier to sync things */
52         asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
53 }
54
55 #ifndef CONFIG_SYS_DCACHE_OFF
56
57 #ifndef CONFIG_SYS_CACHELINE_SIZE
58 #define CONFIG_SYS_CACHELINE_SIZE       32
59 #endif
60
61 void invalidate_dcache_all(void)
62 {
63         asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
64 }
65
66 void flush_dcache_all(void)
67 {
68         asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
69         asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
70 }
71
72 static int check_cache_range(unsigned long start, unsigned long stop)
73 {
74         int ok = 1;
75
76         if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
77                 ok = 0;
78
79         if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
80                 ok = 0;
81
82         if (!ok)
83                 debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
84                         start, stop);
85
86         return ok;
87 }
88
89 void invalidate_dcache_range(unsigned long start, unsigned long stop)
90 {
91         if (!check_cache_range(start, stop))
92                 return;
93
94         while (start < stop) {
95                 asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
96                 start += CONFIG_SYS_CACHELINE_SIZE;
97         }
98 }
99
100 void flush_dcache_range(unsigned long start, unsigned long stop)
101 {
102         if (!check_cache_range(start, stop))
103                 return;
104
105         while (start < stop) {
106                 asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
107                 start += CONFIG_SYS_CACHELINE_SIZE;
108         }
109
110         asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
111 }
112
113 #else /* #ifndef CONFIG_SYS_DCACHE_OFF */
114 void invalidate_dcache_all(void)
115 {
116 }
117
118 void flush_dcache_all(void)
119 {
120 }
121 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
122
123 #if !defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF)
124 void enable_caches(void)
125 {
126 #ifndef CONFIG_SYS_ICACHE_OFF
127         icache_enable();
128 #endif
129 #ifndef CONFIG_SYS_DCACHE_OFF
130         dcache_enable();
131 #endif
132 }
133 #endif