diff options
Diffstat (limited to 'arch/sh/kernel/cpu/sh4/probe.c')
-rw-r--r-- | arch/sh/kernel/cpu/sh4/probe.c | 130 |
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; |