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