aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/cpu-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
-rw-r--r--arch/mips/kernel/cpu-probe.c256
1 files changed, 186 insertions, 70 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 7685f8baf3f0..a263fb7a3971 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2,9 +2,9 @@
2 * Processor capabilities determination functions. 2 * Processor capabilities determination functions.
3 * 3 *
4 * Copyright (C) xxxx the Anonymous 4 * Copyright (C) xxxx the Anonymous
5 * Copyright (C) 2003 Maciej W. Rozycki 5 * Copyright (C) 2003, 2004 Maciej W. Rozycki
6 * Copyright (C) 1994 - 2003 Ralf Baechle 6 * Copyright (C) 1994 - 2003 Ralf Baechle
7 * Copyright (C) 2001 MIPS Inc. 7 * Copyright (C) 2001, 2004 MIPS Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -17,7 +17,6 @@
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/stddef.h> 18#include <linux/stddef.h>
19 19
20#include <asm/bugs.h>
21#include <asm/cpu.h> 20#include <asm/cpu.h>
22#include <asm/fpu.h> 21#include <asm/fpu.h>
23#include <asm/mipsregs.h> 22#include <asm/mipsregs.h>
@@ -51,36 +50,48 @@ static void r4k_wait(void)
51 ".set\tmips0"); 50 ".set\tmips0");
52} 51}
53 52
54/* 53/* The Au1xxx wait is available only if using 32khz counter or
55 * The Au1xxx wait is available only if we run CONFIG_PM and 54 * external timer source, but specifically not CP0 Counter. */
56 * the timer setup found we had a 32KHz counter available. 55int allow_au1k_wait;
57 * There are still problems with functions that may call au1k_wait
58 * directly, but that will be discovered pretty quickly.
59 */
60extern void (*au1k_wait_ptr)(void);
61 56
62void au1k_wait(void) 57static void au1k_wait(void)
63{ 58{
64#ifdef CONFIG_PM
65 /* using the wait instruction makes CP0 counter unusable */ 59 /* using the wait instruction makes CP0 counter unusable */
66 __asm__(".set\tmips3\n\t" 60 __asm__(".set mips3\n\t"
61 "cache 0x14, 0(%0)\n\t"
62 "cache 0x14, 32(%0)\n\t"
63 "sync\n\t"
64 "nop\n\t"
67 "wait\n\t" 65 "wait\n\t"
68 "nop\n\t" 66 "nop\n\t"
69 "nop\n\t" 67 "nop\n\t"
70 "nop\n\t" 68 "nop\n\t"
71 "nop\n\t" 69 "nop\n\t"
72 ".set\tmips0"); 70 ".set mips0\n\t"
73#else 71 : : "r" (au1k_wait));
74 __asm__("nop\n\t"
75 "nop");
76#endif
77} 72}
78 73
74static int __initdata nowait = 0;
75
76int __init wait_disable(char *s)
77{
78 nowait = 1;
79
80 return 1;
81}
82
83__setup("nowait", wait_disable);
84
79static inline void check_wait(void) 85static inline void check_wait(void)
80{ 86{
81 struct cpuinfo_mips *c = &current_cpu_data; 87 struct cpuinfo_mips *c = &current_cpu_data;
82 88
83 printk("Checking for 'wait' instruction... "); 89 printk("Checking for 'wait' instruction... ");
90 if (nowait) {
91 printk (" disabled.\n");
92 return;
93 }
94
84 switch (c->cputype) { 95 switch (c->cputype) {
85 case CPU_R3081: 96 case CPU_R3081:
86 case CPU_R3081E: 97 case CPU_R3081E:
@@ -109,22 +120,22 @@ static inline void check_wait(void)
109/* case CPU_20KC:*/ 120/* case CPU_20KC:*/
110 case CPU_24K: 121 case CPU_24K:
111 case CPU_25KF: 122 case CPU_25KF:
123 case CPU_34K:
124 case CPU_PR4450:
112 cpu_wait = r4k_wait; 125 cpu_wait = r4k_wait;
113 printk(" available.\n"); 126 printk(" available.\n");
114 break; 127 break;
115#ifdef CONFIG_PM
116 case CPU_AU1000: 128 case CPU_AU1000:
117 case CPU_AU1100: 129 case CPU_AU1100:
118 case CPU_AU1500: 130 case CPU_AU1500:
119 if (au1k_wait_ptr != NULL) { 131 case CPU_AU1550:
120 cpu_wait = au1k_wait_ptr; 132 case CPU_AU1200:
133 if (allow_au1k_wait) {
134 cpu_wait = au1k_wait;
121 printk(" available.\n"); 135 printk(" available.\n");
122 } 136 } else
123 else {
124 printk(" unavailable.\n"); 137 printk(" unavailable.\n");
125 }
126 break; 138 break;
127#endif
128 default: 139 default:
129 printk(" unavailable.\n"); 140 printk(" unavailable.\n");
130 break; 141 break;
@@ -180,7 +191,7 @@ static inline int __cpu_has_fpu(void)
180 return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); 191 return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
181} 192}
182 193
183#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ 194#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
184 | MIPS_CPU_COUNTER) 195 | MIPS_CPU_COUNTER)
185 196
186static inline void cpu_probe_legacy(struct cpuinfo_mips *c) 197static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
@@ -189,7 +200,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
189 case PRID_IMP_R2000: 200 case PRID_IMP_R2000:
190 c->cputype = CPU_R2000; 201 c->cputype = CPU_R2000;
191 c->isa_level = MIPS_CPU_ISA_I; 202 c->isa_level = MIPS_CPU_ISA_I;
192 c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; 203 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
204 MIPS_CPU_NOFPUEX;
193 if (__cpu_has_fpu()) 205 if (__cpu_has_fpu())
194 c->options |= MIPS_CPU_FPU; 206 c->options |= MIPS_CPU_FPU;
195 c->tlbsize = 64; 207 c->tlbsize = 64;
@@ -203,7 +215,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
203 else 215 else
204 c->cputype = CPU_R3000; 216 c->cputype = CPU_R3000;
205 c->isa_level = MIPS_CPU_ISA_I; 217 c->isa_level = MIPS_CPU_ISA_I;
206 c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; 218 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
219 MIPS_CPU_NOFPUEX;
207 if (__cpu_has_fpu()) 220 if (__cpu_has_fpu())
208 c->options |= MIPS_CPU_FPU; 221 c->options |= MIPS_CPU_FPU;
209 c->tlbsize = 64; 222 c->tlbsize = 64;
@@ -266,7 +279,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
266 case PRID_IMP_R4600: 279 case PRID_IMP_R4600:
267 c->cputype = CPU_R4600; 280 c->cputype = CPU_R4600;
268 c->isa_level = MIPS_CPU_ISA_III; 281 c->isa_level = MIPS_CPU_ISA_III;
269 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; 282 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
283 MIPS_CPU_LLSC;
270 c->tlbsize = 48; 284 c->tlbsize = 48;
271 break; 285 break;
272 #if 0 286 #if 0
@@ -285,7 +299,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
285 #endif 299 #endif
286 case PRID_IMP_TX39: 300 case PRID_IMP_TX39:
287 c->isa_level = MIPS_CPU_ISA_I; 301 c->isa_level = MIPS_CPU_ISA_I;
288 c->options = MIPS_CPU_TLB; 302 c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
289 303
290 if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { 304 if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
291 c->cputype = CPU_TX3927; 305 c->cputype = CPU_TX3927;
@@ -421,74 +435,147 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
421 } 435 }
422} 436}
423 437
424static inline void decode_config1(struct cpuinfo_mips *c) 438static inline unsigned int decode_config0(struct cpuinfo_mips *c)
425{ 439{
426 unsigned long config0 = read_c0_config(); 440 unsigned int config0;
427 unsigned long config1; 441 int isa;
442
443 config0 = read_c0_config();
428 444
429 if ((config0 & (1 << 31)) == 0) 445 if (((config0 & MIPS_CONF_MT) >> 7) == 1)
430 return; /* actually wort a panic() */ 446 c->options |= MIPS_CPU_TLB;
447 isa = (config0 & MIPS_CONF_AT) >> 13;
448 switch (isa) {
449 case 0:
450 c->isa_level = MIPS_CPU_ISA_M32;
451 break;
452 case 2:
453 c->isa_level = MIPS_CPU_ISA_M64;
454 break;
455 default:
456 panic("Unsupported ISA type, cp0.config0.at: %d.", isa);
457 }
458
459 return config0 & MIPS_CONF_M;
460}
461
462static inline unsigned int decode_config1(struct cpuinfo_mips *c)
463{
464 unsigned int config1;
431 465
432 /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
433 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
434 MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
435 MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
436 config1 = read_c0_config1(); 466 config1 = read_c0_config1();
437 if (config1 & (1 << 3)) 467
468 if (config1 & MIPS_CONF1_MD)
469 c->ases |= MIPS_ASE_MDMX;
470 if (config1 & MIPS_CONF1_WR)
438 c->options |= MIPS_CPU_WATCH; 471 c->options |= MIPS_CPU_WATCH;
439 if (config1 & (1 << 2)) 472 if (config1 & MIPS_CONF1_CA)
440 c->options |= MIPS_CPU_MIPS16; 473 c->ases |= MIPS_ASE_MIPS16;
441 if (config1 & (1 << 1)) 474 if (config1 & MIPS_CONF1_EP)
442 c->options |= MIPS_CPU_EJTAG; 475 c->options |= MIPS_CPU_EJTAG;
443 if (config1 & 1) { 476 if (config1 & MIPS_CONF1_FP) {
444 c->options |= MIPS_CPU_FPU; 477 c->options |= MIPS_CPU_FPU;
445 c->options |= MIPS_CPU_32FPR; 478 c->options |= MIPS_CPU_32FPR;
446 } 479 }
480 if (cpu_has_tlb)
481 c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
482
483 return config1 & MIPS_CONF_M;
484}
485
486static inline unsigned int decode_config2(struct cpuinfo_mips *c)
487{
488 unsigned int config2;
489
490 config2 = read_c0_config2();
491
492 if (config2 & MIPS_CONF2_SL)
493 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
494
495 return config2 & MIPS_CONF_M;
496}
497
498static inline unsigned int decode_config3(struct cpuinfo_mips *c)
499{
500 unsigned int config3;
501
502 config3 = read_c0_config3();
503
504 if (config3 & MIPS_CONF3_SM)
505 c->ases |= MIPS_ASE_SMARTMIPS;
506 if (config3 & MIPS_CONF3_DSP)
507 c->ases |= MIPS_ASE_DSP;
508 if (config3 & MIPS_CONF3_VINT)
509 c->options |= MIPS_CPU_VINT;
510 if (config3 & MIPS_CONF3_VEIC)
511 c->options |= MIPS_CPU_VEIC;
512 if (config3 & MIPS_CONF3_MT)
513 c->ases |= MIPS_ASE_MIPSMT;
514
515 return config3 & MIPS_CONF_M;
516}
517
518static inline void decode_configs(struct cpuinfo_mips *c)
519{
520 /* MIPS32 or MIPS64 compliant CPU. */
521 c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
522 MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
523
447 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 524 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
448 525
449 c->tlbsize = ((config1 >> 25) & 0x3f) + 1; 526 /* Read Config registers. */
527 if (!decode_config0(c))
528 return; /* actually worth a panic() */
529 if (!decode_config1(c))
530 return;
531 if (!decode_config2(c))
532 return;
533 if (!decode_config3(c))
534 return;
450} 535}
451 536
452static inline void cpu_probe_mips(struct cpuinfo_mips *c) 537static inline void cpu_probe_mips(struct cpuinfo_mips *c)
453{ 538{
454 decode_config1(c); 539 decode_configs(c);
455 switch (c->processor_id & 0xff00) { 540 switch (c->processor_id & 0xff00) {
456 case PRID_IMP_4KC: 541 case PRID_IMP_4KC:
457 c->cputype = CPU_4KC; 542 c->cputype = CPU_4KC;
458 c->isa_level = MIPS_CPU_ISA_M32;
459 break; 543 break;
460 case PRID_IMP_4KEC: 544 case PRID_IMP_4KEC:
461 c->cputype = CPU_4KEC; 545 c->cputype = CPU_4KEC;
462 c->isa_level = MIPS_CPU_ISA_M32; 546 break;
547 case PRID_IMP_4KECR2:
548 c->cputype = CPU_4KEC;
463 break; 549 break;
464 case PRID_IMP_4KSC: 550 case PRID_IMP_4KSC:
551 case PRID_IMP_4KSD:
465 c->cputype = CPU_4KSC; 552 c->cputype = CPU_4KSC;
466 c->isa_level = MIPS_CPU_ISA_M32;
467 break; 553 break;
468 case PRID_IMP_5KC: 554 case PRID_IMP_5KC:
469 c->cputype = CPU_5KC; 555 c->cputype = CPU_5KC;
470 c->isa_level = MIPS_CPU_ISA_M64;
471 break; 556 break;
472 case PRID_IMP_20KC: 557 case PRID_IMP_20KC:
473 c->cputype = CPU_20KC; 558 c->cputype = CPU_20KC;
474 c->isa_level = MIPS_CPU_ISA_M64;
475 break; 559 break;
476 case PRID_IMP_24K: 560 case PRID_IMP_24K:
561 case PRID_IMP_24KE:
477 c->cputype = CPU_24K; 562 c->cputype = CPU_24K;
478 c->isa_level = MIPS_CPU_ISA_M32;
479 break; 563 break;
480 case PRID_IMP_25KF: 564 case PRID_IMP_25KF:
481 c->cputype = CPU_25KF; 565 c->cputype = CPU_25KF;
482 c->isa_level = MIPS_CPU_ISA_M64;
483 /* Probe for L2 cache */ 566 /* Probe for L2 cache */
484 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 567 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
485 break; 568 break;
569 case PRID_IMP_34K:
570 c->cputype = CPU_34K;
571 c->isa_level = MIPS_CPU_ISA_M32;
572 break;
486 } 573 }
487} 574}
488 575
489static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) 576static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
490{ 577{
491 decode_config1(c); 578 decode_configs(c);
492 switch (c->processor_id & 0xff00) { 579 switch (c->processor_id & 0xff00) {
493 case PRID_IMP_AU1_REV1: 580 case PRID_IMP_AU1_REV1:
494 case PRID_IMP_AU1_REV2: 581 case PRID_IMP_AU1_REV2:
@@ -505,50 +592,70 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
505 case 3: 592 case 3:
506 c->cputype = CPU_AU1550; 593 c->cputype = CPU_AU1550;
507 break; 594 break;
595 case 4:
596 c->cputype = CPU_AU1200;
597 break;
508 default: 598 default:
509 panic("Unknown Au Core!"); 599 panic("Unknown Au Core!");
510 break; 600 break;
511 } 601 }
512 c->isa_level = MIPS_CPU_ISA_M32;
513 break; 602 break;
514 } 603 }
515} 604}
516 605
517static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) 606static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
518{ 607{
519 decode_config1(c); 608 decode_configs(c);
609
610 /*
611 * For historical reasons the SB1 comes with it's own variant of
612 * cache code which eventually will be folded into c-r4k.c. Until
613 * then we pretend it's got it's own cache architecture.
614 */
615 c->options &= ~MIPS_CPU_4K_CACHE;
616 c->options |= MIPS_CPU_SB1_CACHE;
617
520 switch (c->processor_id & 0xff00) { 618 switch (c->processor_id & 0xff00) {
521 case PRID_IMP_SB1: 619 case PRID_IMP_SB1:
522 c->cputype = CPU_SB1; 620 c->cputype = CPU_SB1;
523 c->isa_level = MIPS_CPU_ISA_M64; 621#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
524 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
525 MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
526 MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
527 MIPS_CPU_WATCH | MIPS_CPU_LLSC;
528#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
529 /* FPU in pass1 is known to have issues. */ 622 /* FPU in pass1 is known to have issues. */
530 c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; 623 c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
531#endif 624#endif
532 break; 625 break;
626 case PRID_IMP_SB1A:
627 c->cputype = CPU_SB1A;
628 break;
533 } 629 }
534} 630}
535 631
536static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) 632static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
537{ 633{
538 decode_config1(c); 634 decode_configs(c);
539 switch (c->processor_id & 0xff00) { 635 switch (c->processor_id & 0xff00) {
540 case PRID_IMP_SR71000: 636 case PRID_IMP_SR71000:
541 c->cputype = CPU_SR71000; 637 c->cputype = CPU_SR71000;
542 c->isa_level = MIPS_CPU_ISA_M64;
543 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
544 MIPS_CPU_4KTLB | MIPS_CPU_FPU |
545 MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
546 c->scache.ways = 8; 638 c->scache.ways = 8;
547 c->tlbsize = 64; 639 c->tlbsize = 64;
548 break; 640 break;
549 } 641 }
550} 642}
551 643
644static inline void cpu_probe_philips(struct cpuinfo_mips *c)
645{
646 decode_configs(c);
647 switch (c->processor_id & 0xff00) {
648 case PRID_IMP_PR4450:
649 c->cputype = CPU_PR4450;
650 c->isa_level = MIPS_CPU_ISA_M32;
651 break;
652 default:
653 panic("Unknown Philips Core!"); /* REVISIT: die? */
654 break;
655 }
656}
657
658
552__init void cpu_probe(void) 659__init void cpu_probe(void)
553{ 660{
554 struct cpuinfo_mips *c = &current_cpu_data; 661 struct cpuinfo_mips *c = &current_cpu_data;
@@ -571,15 +678,24 @@ __init void cpu_probe(void)
571 case PRID_COMP_SIBYTE: 678 case PRID_COMP_SIBYTE:
572 cpu_probe_sibyte(c); 679 cpu_probe_sibyte(c);
573 break; 680 break;
574
575 case PRID_COMP_SANDCRAFT: 681 case PRID_COMP_SANDCRAFT:
576 cpu_probe_sandcraft(c); 682 cpu_probe_sandcraft(c);
577 break; 683 break;
684 case PRID_COMP_PHILIPS:
685 cpu_probe_philips(c);
686 break;
578 default: 687 default:
579 c->cputype = CPU_UNKNOWN; 688 c->cputype = CPU_UNKNOWN;
580 } 689 }
581 if (c->options & MIPS_CPU_FPU) 690 if (c->options & MIPS_CPU_FPU) {
582 c->fpu_id = cpu_get_fpu_id(); 691 c->fpu_id = cpu_get_fpu_id();
692
693 if (c->isa_level == MIPS_CPU_ISA_M32 ||
694 c->isa_level == MIPS_CPU_ISA_M64) {
695 if (c->fpu_id & MIPS_FPIR_3D)
696 c->ases |= MIPS_ASE_MIPS3D;
697 }
698 }
583} 699}
584 700
585__init void cpu_report(void) 701__init void cpu_report(void)