aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh4/probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh4/probe.c')
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c130
1 files changed, 55 insertions, 75 deletions
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 91e3677ae09d..6c78d0a9c857 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -60,12 +60,18 @@ int __init detect_cpu_and_cache_system(void)
60 if ((cvr & 0x10000000) == 0) 60 if ((cvr & 0x10000000) == 0)
61 boot_cpu_data.flags |= CPU_HAS_DSP; 61 boot_cpu_data.flags |= CPU_HAS_DSP;
62 62
63 boot_cpu_data.flags |= CPU_HAS_LLSC; 63 boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER;
64 boot_cpu_data.cut_major = pvr & 0x7f; 64 boot_cpu_data.cut_major = pvr & 0x7f;
65
66 boot_cpu_data.icache.ways = 4;
67 boot_cpu_data.dcache.ways = 4;
68 } else {
69 /* And some SH-4 defaults.. */
70 boot_cpu_data.flags |= CPU_HAS_PTEA;
65 } 71 }
66 72
67 /* FPU detection works for everyone */ 73 /* FPU detection works for everyone */
68 if ((cvr & 0x20000000) == 1) 74 if ((cvr & 0x20000000))
69 boot_cpu_data.flags |= CPU_HAS_FPU; 75 boot_cpu_data.flags |= CPU_HAS_FPU;
70 76
71 /* Mask off the upper chip ID */ 77 /* Mask off the upper chip ID */
@@ -78,25 +84,20 @@ int __init detect_cpu_and_cache_system(void)
78 switch (pvr) { 84 switch (pvr) {
79 case 0x205: 85 case 0x205:
80 boot_cpu_data.type = CPU_SH7750; 86 boot_cpu_data.type = CPU_SH7750;
81 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | 87 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
82 CPU_HAS_PERF_COUNTER; 88 CPU_HAS_PERF_COUNTER;
83 break; 89 break;
84 case 0x206: 90 case 0x206:
85 boot_cpu_data.type = CPU_SH7750S; 91 boot_cpu_data.type = CPU_SH7750S;
86 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | 92 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
87 CPU_HAS_PERF_COUNTER; 93 CPU_HAS_PERF_COUNTER;
88 break; 94 break;
89 case 0x1100: 95 case 0x1100:
90 boot_cpu_data.type = CPU_SH7751; 96 boot_cpu_data.type = CPU_SH7751;
91 boot_cpu_data.flags |= CPU_HAS_FPU;
92 break; 97 break;
93 case 0x2001: 98 case 0x2001:
94 case 0x2004: 99 case 0x2004:
95 boot_cpu_data.type = CPU_SH7770; 100 boot_cpu_data.type = CPU_SH7770;
96 boot_cpu_data.icache.ways = 4;
97 boot_cpu_data.dcache.ways = 4;
98
99 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
100 break; 101 break;
101 case 0x2006: 102 case 0x2006:
102 case 0x200A: 103 case 0x200A:
@@ -107,45 +108,26 @@ int __init detect_cpu_and_cache_system(void)
107 else 108 else
108 boot_cpu_data.type = CPU_SH7780; 109 boot_cpu_data.type = CPU_SH7780;
109 110
110 boot_cpu_data.icache.ways = 4;
111 boot_cpu_data.dcache.ways = 4;
112
113 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
114 CPU_HAS_LLSC;
115 break; 111 break;
116 case 0x3000: 112 case 0x3000:
117 case 0x3003: 113 case 0x3003:
118 case 0x3009: 114 case 0x3009:
119 boot_cpu_data.type = CPU_SH7343; 115 boot_cpu_data.type = CPU_SH7343;
120 boot_cpu_data.icache.ways = 4;
121 boot_cpu_data.dcache.ways = 4;
122 boot_cpu_data.flags |= CPU_HAS_LLSC;
123 break; 116 break;
124 case 0x3004: 117 case 0x3004:
125 case 0x3007: 118 case 0x3007:
126 boot_cpu_data.type = CPU_SH7785; 119 boot_cpu_data.type = CPU_SH7785;
127 boot_cpu_data.icache.ways = 4;
128 boot_cpu_data.dcache.ways = 4;
129 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
130 CPU_HAS_LLSC;
131 break; 120 break;
132 case 0x4004: 121 case 0x4004:
133 boot_cpu_data.type = CPU_SH7786; 122 boot_cpu_data.type = CPU_SH7786;
134 boot_cpu_data.icache.ways = 4; 123 boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE;
135 boot_cpu_data.dcache.ways = 4;
136 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
137 CPU_HAS_LLSC | CPU_HAS_PTEAEX;
138 break; 124 break;
139 case 0x3008: 125 case 0x3008:
140 boot_cpu_data.icache.ways = 4;
141 boot_cpu_data.dcache.ways = 4;
142 boot_cpu_data.flags |= CPU_HAS_LLSC;
143
144 switch (prr) { 126 switch (prr) {
145 case 0x50: 127 case 0x50:
146 case 0x51: 128 case 0x51:
147 boot_cpu_data.type = CPU_SH7723; 129 boot_cpu_data.type = CPU_SH7723;
148 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_L2_CACHE; 130 boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
149 break; 131 break;
150 case 0x70: 132 case 0x70:
151 boot_cpu_data.type = CPU_SH7366; 133 boot_cpu_data.type = CPU_SH7366;
@@ -156,13 +138,13 @@ int __init detect_cpu_and_cache_system(void)
156 break; 138 break;
157 } 139 }
158 break; 140 break;
141 case 0x300b:
142 boot_cpu_data.type = CPU_SH7724;
143 boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
144 break;
159 case 0x4000: /* 1st cut */ 145 case 0x4000: /* 1st cut */
160 case 0x4001: /* 2nd cut */ 146 case 0x4001: /* 2nd cut */
161 boot_cpu_data.type = CPU_SHX3; 147 boot_cpu_data.type = CPU_SHX3;
162 boot_cpu_data.icache.ways = 4;
163 boot_cpu_data.dcache.ways = 4;
164 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
165 CPU_HAS_LLSC;
166 break; 148 break;
167 case 0x700: 149 case 0x700:
168 boot_cpu_data.type = CPU_SH4_501; 150 boot_cpu_data.type = CPU_SH4_501;
@@ -173,7 +155,6 @@ int __init detect_cpu_and_cache_system(void)
173 boot_cpu_data.type = CPU_SH4_202; 155 boot_cpu_data.type = CPU_SH4_202;
174 boot_cpu_data.icache.ways = 2; 156 boot_cpu_data.icache.ways = 2;
175 boot_cpu_data.dcache.ways = 2; 157 boot_cpu_data.dcache.ways = 2;
176 boot_cpu_data.flags |= CPU_HAS_FPU;
177 break; 158 break;
178 case 0x500 ... 0x501: 159 case 0x500 ... 0x501:
179 switch (prr) { 160 switch (prr) {
@@ -191,18 +172,12 @@ int __init detect_cpu_and_cache_system(void)
191 boot_cpu_data.icache.ways = 2; 172 boot_cpu_data.icache.ways = 2;
192 boot_cpu_data.dcache.ways = 2; 173 boot_cpu_data.dcache.ways = 2;
193 174
194 boot_cpu_data.flags |= CPU_HAS_FPU;
195
196 break; 175 break;
197 default: 176 default:
198 boot_cpu_data.type = CPU_SH_NONE; 177 boot_cpu_data.type = CPU_SH_NONE;
199 break; 178 break;
200 } 179 }
201 180
202#ifdef CONFIG_CPU_HAS_PTEA
203 boot_cpu_data.flags |= CPU_HAS_PTEA;
204#endif
205
206 /* 181 /*
207 * On anything that's not a direct-mapped cache, look to the CVR 182 * On anything that's not a direct-mapped cache, look to the CVR
208 * for I/D-cache specifics. 183 * for I/D-cache specifics.
@@ -222,43 +197,48 @@ int __init detect_cpu_and_cache_system(void)
222 } 197 }
223 198
224 /* 199 /*
225 * Setup the L2 cache desc
226 *
227 * SH-4A's have an optional PIPT L2. 200 * SH-4A's have an optional PIPT L2.
228 */ 201 */
229 if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { 202 if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
230 /* Bug if we can't decode the L2 info */
231 BUG_ON(!(cvr & 0xf));
232
233 /* Silicon and specifications have clearly never met.. */
234 cvr ^= 0xf;
235
236 /* 203 /*
237 * Size calculation is much more sensible 204 * Verify that it really has something hooked up, this
238 * than it is for the L1. 205 * is the safety net for CPUs that have optional L2
239 * 206 * support yet do not implement it.
240 * Sizes are 128KB, 258KB, 512KB, and 1MB.
241 */ 207 */
242 size = (cvr & 0xf) << 17; 208 if ((cvr & 0xf) == 0)
243 209 boot_cpu_data.flags &= ~CPU_HAS_L2_CACHE;
244 BUG_ON(!size); 210 else {
245 211 /*
246 boot_cpu_data.scache.way_incr = (1 << 16); 212 * Silicon and specifications have clearly never
247 boot_cpu_data.scache.entry_shift = 5; 213 * met..
248 boot_cpu_data.scache.ways = 4; 214 */
249 boot_cpu_data.scache.linesz = L1_CACHE_BYTES; 215 cvr ^= 0xf;
250 216
251 boot_cpu_data.scache.entry_mask = 217 /*
252 (boot_cpu_data.scache.way_incr - 218 * Size calculation is much more sensible
253 boot_cpu_data.scache.linesz); 219 * than it is for the L1.
254 220 *
255 boot_cpu_data.scache.sets = size / 221 * Sizes are 128KB, 258KB, 512KB, and 1MB.
256 (boot_cpu_data.scache.linesz * 222 */
257 boot_cpu_data.scache.ways); 223 size = (cvr & 0xf) << 17;
258 224
259 boot_cpu_data.scache.way_size = 225 boot_cpu_data.scache.way_incr = (1 << 16);
260 (boot_cpu_data.scache.sets * 226 boot_cpu_data.scache.entry_shift = 5;
261 boot_cpu_data.scache.linesz); 227 boot_cpu_data.scache.ways = 4;
228 boot_cpu_data.scache.linesz = L1_CACHE_BYTES;
229
230 boot_cpu_data.scache.entry_mask =
231 (boot_cpu_data.scache.way_incr -
232 boot_cpu_data.scache.linesz);
233
234 boot_cpu_data.scache.sets = size /
235 (boot_cpu_data.scache.linesz *
236 boot_cpu_data.scache.ways);
237
238 boot_cpu_data.scache.way_size =
239 (boot_cpu_data.scache.sets *
240 boot_cpu_data.scache.linesz);
241 }
262 } 242 }
263 243
264 return 0; 244 return 0;