diff options
Diffstat (limited to 'arch/avr32/kernel/cpu.c')
-rw-r--r-- | arch/avr32/kernel/cpu.c | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c index 2714cf6452b5..b8409caeb23d 100644 --- a/arch/avr32/kernel/cpu.c +++ b/arch/avr32/kernel/cpu.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
14 | #include <linux/param.h> | 14 | #include <linux/param.h> |
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/clk.h> | ||
16 | 17 | ||
17 | #include <asm/setup.h> | 18 | #include <asm/setup.h> |
18 | #include <asm/sysreg.h> | 19 | #include <asm/sysreg.h> |
@@ -187,9 +188,20 @@ static int __init topology_init(void) | |||
187 | 188 | ||
188 | subsys_initcall(topology_init); | 189 | subsys_initcall(topology_init); |
189 | 190 | ||
191 | struct chip_id_map { | ||
192 | u16 mid; | ||
193 | u16 pn; | ||
194 | const char *name; | ||
195 | }; | ||
196 | |||
197 | static const struct chip_id_map chip_names[] = { | ||
198 | { .mid = 0x1f, .pn = 0x1e82, .name = "AT32AP700x" }, | ||
199 | }; | ||
200 | #define NR_CHIP_NAMES ARRAY_SIZE(chip_names) | ||
201 | |||
190 | static const char *cpu_names[] = { | 202 | static const char *cpu_names[] = { |
191 | "Morgan", | 203 | "Morgan", |
192 | "AP7000", | 204 | "AP7", |
193 | }; | 205 | }; |
194 | #define NR_CPU_NAMES ARRAY_SIZE(cpu_names) | 206 | #define NR_CPU_NAMES ARRAY_SIZE(cpu_names) |
195 | 207 | ||
@@ -206,12 +218,32 @@ static const char *mmu_types[] = { | |||
206 | "MPU" | 218 | "MPU" |
207 | }; | 219 | }; |
208 | 220 | ||
221 | static const char *cpu_feature_flags[] = { | ||
222 | "rmw", "dsp", "simd", "ocd", "perfctr", "java", "fpu", | ||
223 | }; | ||
224 | |||
225 | static const char *get_chip_name(struct avr32_cpuinfo *cpu) | ||
226 | { | ||
227 | unsigned int i; | ||
228 | unsigned int mid = avr32_get_manufacturer_id(cpu); | ||
229 | unsigned int pn = avr32_get_product_number(cpu); | ||
230 | |||
231 | for (i = 0; i < NR_CHIP_NAMES; i++) { | ||
232 | if (chip_names[i].mid == mid && chip_names[i].pn == pn) | ||
233 | return chip_names[i].name; | ||
234 | } | ||
235 | |||
236 | return "(unknown)"; | ||
237 | } | ||
238 | |||
209 | void __init setup_processor(void) | 239 | void __init setup_processor(void) |
210 | { | 240 | { |
211 | unsigned long config0, config1; | 241 | unsigned long config0, config1; |
212 | unsigned long features; | 242 | unsigned long features; |
213 | unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type; | 243 | unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type; |
244 | unsigned device_id; | ||
214 | unsigned tmp; | 245 | unsigned tmp; |
246 | unsigned i; | ||
215 | 247 | ||
216 | config0 = sysreg_read(CONFIG0); | 248 | config0 = sysreg_read(CONFIG0); |
217 | config1 = sysreg_read(CONFIG1); | 249 | config1 = sysreg_read(CONFIG1); |
@@ -221,11 +253,14 @@ void __init setup_processor(void) | |||
221 | arch_rev = SYSREG_BFEXT(AR, config0); | 253 | arch_rev = SYSREG_BFEXT(AR, config0); |
222 | mmu_type = SYSREG_BFEXT(MMUT, config0); | 254 | mmu_type = SYSREG_BFEXT(MMUT, config0); |
223 | 255 | ||
256 | device_id = ocd_read(DID); | ||
257 | |||
224 | boot_cpu_data.arch_type = arch_id; | 258 | boot_cpu_data.arch_type = arch_id; |
225 | boot_cpu_data.cpu_type = cpu_id; | 259 | boot_cpu_data.cpu_type = cpu_id; |
226 | boot_cpu_data.arch_revision = arch_rev; | 260 | boot_cpu_data.arch_revision = arch_rev; |
227 | boot_cpu_data.cpu_revision = cpu_rev; | 261 | boot_cpu_data.cpu_revision = cpu_rev; |
228 | boot_cpu_data.tlb_config = mmu_type; | 262 | boot_cpu_data.tlb_config = mmu_type; |
263 | boot_cpu_data.device_id = device_id; | ||
229 | 264 | ||
230 | tmp = SYSREG_BFEXT(ILSZ, config1); | 265 | tmp = SYSREG_BFEXT(ILSZ, config1); |
231 | if (tmp) { | 266 | if (tmp) { |
@@ -247,41 +282,34 @@ void __init setup_processor(void) | |||
247 | return; | 282 | return; |
248 | } | 283 | } |
249 | 284 | ||
250 | printk ("CPU: %s [%02x] revision %d (%s revision %d)\n", | 285 | printk ("CPU: %s chip revision %c\n", get_chip_name(&boot_cpu_data), |
286 | avr32_get_chip_revision(&boot_cpu_data) + 'A'); | ||
287 | printk ("CPU: %s [%02x] core revision %d (%s arch revision %d)\n", | ||
251 | cpu_names[cpu_id], cpu_id, cpu_rev, | 288 | cpu_names[cpu_id], cpu_id, cpu_rev, |
252 | arch_names[arch_id], arch_rev); | 289 | arch_names[arch_id], arch_rev); |
253 | printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]); | 290 | printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]); |
254 | 291 | ||
255 | printk ("CPU: features:"); | 292 | printk ("CPU: features:"); |
256 | features = 0; | 293 | features = 0; |
257 | if (config0 & SYSREG_BIT(CONFIG0_R)) { | 294 | if (config0 & SYSREG_BIT(CONFIG0_R)) |
258 | features |= AVR32_FEATURE_RMW; | 295 | features |= AVR32_FEATURE_RMW; |
259 | printk(" rmw"); | 296 | if (config0 & SYSREG_BIT(CONFIG0_D)) |
260 | } | ||
261 | if (config0 & SYSREG_BIT(CONFIG0_D)) { | ||
262 | features |= AVR32_FEATURE_DSP; | 297 | features |= AVR32_FEATURE_DSP; |
263 | printk(" dsp"); | 298 | if (config0 & SYSREG_BIT(CONFIG0_S)) |
264 | } | ||
265 | if (config0 & SYSREG_BIT(CONFIG0_S)) { | ||
266 | features |= AVR32_FEATURE_SIMD; | 299 | features |= AVR32_FEATURE_SIMD; |
267 | printk(" simd"); | 300 | if (config0 & SYSREG_BIT(CONFIG0_O)) |
268 | } | ||
269 | if (config0 & SYSREG_BIT(CONFIG0_O)) { | ||
270 | features |= AVR32_FEATURE_OCD; | 301 | features |= AVR32_FEATURE_OCD; |
271 | printk(" ocd"); | 302 | if (config0 & SYSREG_BIT(CONFIG0_P)) |
272 | } | ||
273 | if (config0 & SYSREG_BIT(CONFIG0_P)) { | ||
274 | features |= AVR32_FEATURE_PCTR; | 303 | features |= AVR32_FEATURE_PCTR; |
275 | printk(" perfctr"); | 304 | if (config0 & SYSREG_BIT(CONFIG0_J)) |
276 | } | ||
277 | if (config0 & SYSREG_BIT(CONFIG0_J)) { | ||
278 | features |= AVR32_FEATURE_JAVA; | 305 | features |= AVR32_FEATURE_JAVA; |
279 | printk(" java"); | 306 | if (config0 & SYSREG_BIT(CONFIG0_F)) |
280 | } | ||
281 | if (config0 & SYSREG_BIT(CONFIG0_F)) { | ||
282 | features |= AVR32_FEATURE_FPU; | 307 | features |= AVR32_FEATURE_FPU; |
283 | printk(" fpu"); | 308 | |
284 | } | 309 | for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++) |
310 | if (features & (1 << i)) | ||
311 | printk(" %s", cpu_feature_flags[i]); | ||
312 | |||
285 | printk("\n"); | 313 | printk("\n"); |
286 | boot_cpu_data.features = features; | 314 | boot_cpu_data.features = features; |
287 | } | 315 | } |
@@ -291,6 +319,8 @@ static int c_show(struct seq_file *m, void *v) | |||
291 | { | 319 | { |
292 | unsigned int icache_size, dcache_size; | 320 | unsigned int icache_size, dcache_size; |
293 | unsigned int cpu = smp_processor_id(); | 321 | unsigned int cpu = smp_processor_id(); |
322 | unsigned int freq; | ||
323 | unsigned int i; | ||
294 | 324 | ||
295 | icache_size = boot_cpu_data.icache.ways * | 325 | icache_size = boot_cpu_data.icache.ways * |
296 | boot_cpu_data.icache.sets * | 326 | boot_cpu_data.icache.sets * |
@@ -301,15 +331,21 @@ static int c_show(struct seq_file *m, void *v) | |||
301 | 331 | ||
302 | seq_printf(m, "processor\t: %d\n", cpu); | 332 | seq_printf(m, "processor\t: %d\n", cpu); |
303 | 333 | ||
334 | seq_printf(m, "chip type\t: %s revision %c\n", | ||
335 | get_chip_name(&boot_cpu_data), | ||
336 | avr32_get_chip_revision(&boot_cpu_data) + 'A'); | ||
304 | if (boot_cpu_data.arch_type < NR_ARCH_NAMES) | 337 | if (boot_cpu_data.arch_type < NR_ARCH_NAMES) |
305 | seq_printf(m, "cpu family\t: %s revision %d\n", | 338 | seq_printf(m, "cpu arch\t: %s revision %d\n", |
306 | arch_names[boot_cpu_data.arch_type], | 339 | arch_names[boot_cpu_data.arch_type], |
307 | boot_cpu_data.arch_revision); | 340 | boot_cpu_data.arch_revision); |
308 | if (boot_cpu_data.cpu_type < NR_CPU_NAMES) | 341 | if (boot_cpu_data.cpu_type < NR_CPU_NAMES) |
309 | seq_printf(m, "cpu type\t: %s revision %d\n", | 342 | seq_printf(m, "cpu core\t: %s revision %d\n", |
310 | cpu_names[boot_cpu_data.cpu_type], | 343 | cpu_names[boot_cpu_data.cpu_type], |
311 | boot_cpu_data.cpu_revision); | 344 | boot_cpu_data.cpu_revision); |
312 | 345 | ||
346 | freq = (clk_get_rate(boot_cpu_data.clk) + 500) / 1000; | ||
347 | seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, freq % 1000); | ||
348 | |||
313 | seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n", | 349 | seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n", |
314 | icache_size >> 10, | 350 | icache_size >> 10, |
315 | boot_cpu_data.icache.ways, | 351 | boot_cpu_data.icache.ways, |
@@ -320,7 +356,13 @@ static int c_show(struct seq_file *m, void *v) | |||
320 | boot_cpu_data.dcache.ways, | 356 | boot_cpu_data.dcache.ways, |
321 | boot_cpu_data.dcache.sets, | 357 | boot_cpu_data.dcache.sets, |
322 | boot_cpu_data.dcache.linesz); | 358 | boot_cpu_data.dcache.linesz); |
323 | seq_printf(m, "bogomips\t: %lu.%02lu\n", | 359 | |
360 | seq_printf(m, "features\t:"); | ||
361 | for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++) | ||
362 | if (boot_cpu_data.features & (1 << i)) | ||
363 | seq_printf(m, " %s", cpu_feature_flags[i]); | ||
364 | |||
365 | seq_printf(m, "\nbogomips\t: %lu.%02lu\n", | ||
324 | boot_cpu_data.loops_per_jiffy / (500000/HZ), | 366 | boot_cpu_data.loops_per_jiffy / (500000/HZ), |
325 | (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100); | 367 | (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100); |
326 | 368 | ||
@@ -343,7 +385,7 @@ static void c_stop(struct seq_file *m, void *v) | |||
343 | 385 | ||
344 | } | 386 | } |
345 | 387 | ||
346 | struct seq_operations cpuinfo_op = { | 388 | const struct seq_operations cpuinfo_op = { |
347 | .start = c_start, | 389 | .start = c_start, |
348 | .next = c_next, | 390 | .next = c_next, |
349 | .stop = c_stop, | 391 | .stop = c_stop, |