1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2002
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 */
6
7 #include <config.h>
8 #include <cpu_func.h>
9 #include <asm/immap.h>
10 #include <asm/cache.h>
11 #include <linux/errno.h>
12
13 volatile int *cf_icache_status = (int *)ICACHE_STATUS;
14 volatile int *cf_dcache_status = (int *)DCACHE_STATUS;
15
flush_cache(ulong start_addr,ulong size)16 void flush_cache(ulong start_addr, ulong size)
17 {
18 /* Must be implemented for all M68k processors with copy-back data cache */
19 }
20
icache_status(void)21 int icache_status(void)
22 {
23 return *cf_icache_status;
24 }
25
dcache_status(void)26 int dcache_status(void)
27 {
28 return *cf_dcache_status;
29 }
30
icache_enable(void)31 void icache_enable(void)
32 {
33 invalidate_icache_all();
34
35 *cf_icache_status = 1;
36
37 #if defined(CONFIG_CF_V4) || defined(CFG_CF_V4E)
38 __asm__ __volatile__("movec %0, %%acr2"::"r"(CFG_SYS_CACHE_ACR2));
39 __asm__ __volatile__("movec %0, %%acr3"::"r"(CFG_SYS_CACHE_ACR3));
40 #if defined(CFG_CF_V4E)
41 __asm__ __volatile__("movec %0, %%acr6"::"r"(CFG_SYS_CACHE_ACR6));
42 __asm__ __volatile__("movec %0, %%acr7"::"r"(CFG_SYS_CACHE_ACR7));
43 #endif
44 #else
45 __asm__ __volatile__("movec %0, %%acr0"::"r"(CFG_SYS_CACHE_ACR0));
46 __asm__ __volatile__("movec %0, %%acr1"::"r"(CFG_SYS_CACHE_ACR1));
47 #endif
48
49 __asm__ __volatile__("movec %0, %%cacr"::"r"(CFG_SYS_CACHE_ICACR));
50 }
51
icache_disable(void)52 void icache_disable(void)
53 {
54 u32 temp = 0;
55
56 *cf_icache_status = 0;
57 invalidate_icache_all();
58
59 #if defined(CONFIG_CF_V4) || defined(CFG_CF_V4E)
60 __asm__ __volatile__("movec %0, %%acr2"::"r"(temp));
61 __asm__ __volatile__("movec %0, %%acr3"::"r"(temp));
62 #if defined(CFG_CF_V4E)
63 __asm__ __volatile__("movec %0, %%acr6"::"r"(temp));
64 __asm__ __volatile__("movec %0, %%acr7"::"r"(temp));
65 #endif
66 #else
67 __asm__ __volatile__("movec %0, %%acr0"::"r"(temp));
68 __asm__ __volatile__("movec %0, %%acr1"::"r"(temp));
69 #endif
70 }
71
invalidate_icache_all(void)72 void invalidate_icache_all(void)
73 {
74 u32 temp;
75
76 temp = CFG_SYS_ICACHE_INV;
77 if (*cf_icache_status)
78 temp |= CFG_SYS_CACHE_ICACR;
79
80 __asm__ __volatile__("movec %0, %%cacr"::"r"(temp));
81 }
82
83 /*
84 * data cache only for ColdFire V4 such as MCF5445x
85 * the dcache will be dummy in ColdFire V2 and V3
86 */
dcache_enable(void)87 void dcache_enable(void)
88 {
89 dcache_invalid();
90 *cf_dcache_status = 1;
91
92 #if defined(CONFIG_CF_V4) || defined(CFG_CF_V4E)
93 __asm__ __volatile__("movec %0, %%acr0"::"r"(CFG_SYS_CACHE_ACR0));
94 __asm__ __volatile__("movec %0, %%acr1"::"r"(CFG_SYS_CACHE_ACR1));
95 #if defined(CFG_CF_V4E)
96 __asm__ __volatile__("movec %0, %%acr4"::"r"(CFG_SYS_CACHE_ACR4));
97 __asm__ __volatile__("movec %0, %%acr5"::"r"(CFG_SYS_CACHE_ACR5));
98 #endif
99 #endif
100
101 __asm__ __volatile__("movec %0, %%cacr"::"r"(CFG_SYS_CACHE_DCACR));
102 }
103
dcache_disable(void)104 void dcache_disable(void)
105 {
106 u32 temp = 0;
107
108 *cf_dcache_status = 0;
109 dcache_invalid();
110
111 __asm__ __volatile__("movec %0, %%cacr"::"r"(temp));
112
113 #if defined(CONFIG_CF_V4) || defined(CFG_CF_V4E)
114 __asm__ __volatile__("movec %0, %%acr0"::"r"(temp));
115 __asm__ __volatile__("movec %0, %%acr1"::"r"(temp));
116 #if defined(CFG_CF_V4E)
117 __asm__ __volatile__("movec %0, %%acr4"::"r"(temp));
118 __asm__ __volatile__("movec %0, %%acr5"::"r"(temp));
119 #endif
120 #endif
121 }
122
dcache_invalid(void)123 void dcache_invalid(void)
124 {
125 #if defined(CONFIG_CF_V4) || defined(CFG_CF_V4E)
126 u32 temp;
127
128 temp = CFG_SYS_DCACHE_INV;
129 if (*cf_dcache_status)
130 temp |= CFG_SYS_CACHE_DCACR;
131 if (*cf_icache_status)
132 temp |= CFG_SYS_CACHE_ICACR;
133
134 __asm__ __volatile__("movec %0, %%cacr"::"r"(temp));
135 #endif
136 }
137
138 /*
139 * Default implementation:
140 * do a range flush for the entire range
141 */
flush_dcache_all(void)142 __weak void flush_dcache_all(void)
143 {
144 flush_dcache_range(0, ~0);
145 }
146
invalidate_dcache_range(unsigned long start,unsigned long stop)147 __weak void invalidate_dcache_range(unsigned long start, unsigned long stop)
148 {
149 /* An empty stub, real implementation should be in platform code */
150 }
flush_dcache_range(unsigned long start,unsigned long stop)151 __weak void flush_dcache_range(unsigned long start, unsigned long stop)
152 {
153 /* An empty stub, real implementation should be in platform code */
154 }
155
pgprot_set_attrs(phys_addr_t addr,size_t size,enum pgprot_attrs perm)156 int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
157 {
158 return -ENOSYS;
159 }
160