diff options
| -rw-r--r-- | arch/avr32/kernel/cpu.c | 94 | ||||
| -rw-r--r-- | include/asm-avr32/processor.h | 14 |
2 files changed, 82 insertions, 26 deletions
diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c index 2714cf6452b5..14610019216e 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 | ||
diff --git a/include/asm-avr32/processor.h b/include/asm-avr32/processor.h index a52576b25afe..4212551c1cd9 100644 --- a/include/asm-avr32/processor.h +++ b/include/asm-avr32/processor.h | |||
| @@ -57,11 +57,25 @@ struct avr32_cpuinfo { | |||
| 57 | unsigned short cpu_revision; | 57 | unsigned short cpu_revision; |
| 58 | enum tlb_config tlb_config; | 58 | enum tlb_config tlb_config; |
| 59 | unsigned long features; | 59 | unsigned long features; |
| 60 | u32 device_id; | ||
| 60 | 61 | ||
| 61 | struct cache_info icache; | 62 | struct cache_info icache; |
| 62 | struct cache_info dcache; | 63 | struct cache_info dcache; |
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| 66 | static inline unsigned int avr32_get_manufacturer_id(struct avr32_cpuinfo *cpu) | ||
| 67 | { | ||
| 68 | return (cpu->device_id >> 1) & 0x7f; | ||
| 69 | } | ||
| 70 | static inline unsigned int avr32_get_product_number(struct avr32_cpuinfo *cpu) | ||
| 71 | { | ||
| 72 | return (cpu->device_id >> 12) & 0xffff; | ||
| 73 | } | ||
| 74 | static inline unsigned int avr32_get_chip_revision(struct avr32_cpuinfo *cpu) | ||
| 75 | { | ||
| 76 | return (cpu->device_id >> 28) & 0x0f; | ||
| 77 | } | ||
| 78 | |||
| 65 | extern struct avr32_cpuinfo boot_cpu_data; | 79 | extern struct avr32_cpuinfo boot_cpu_data; |
| 66 | 80 | ||
| 67 | #ifdef CONFIG_SMP | 81 | #ifdef CONFIG_SMP |
