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.c71
1 files changed, 67 insertions, 4 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index dc49cf30c2db..5342674842f5 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -69,6 +69,63 @@ static int __init htw_disable(char *s)
69 69
70__setup("nohtw", htw_disable); 70__setup("nohtw", htw_disable);
71 71
72static int mips_ftlb_disabled;
73static int mips_has_ftlb_configured;
74
75static void set_ftlb_enable(struct cpuinfo_mips *c, int enable);
76
77static int __init ftlb_disable(char *s)
78{
79 unsigned int config4, mmuextdef;
80
81 /*
82 * If the core hasn't done any FTLB configuration, there is nothing
83 * for us to do here.
84 */
85 if (!mips_has_ftlb_configured)
86 return 1;
87
88 /* Disable it in the boot cpu */
89 set_ftlb_enable(&cpu_data[0], 0);
90
91 back_to_back_c0_hazard();
92
93 config4 = read_c0_config4();
94
95 /* Check that FTLB has been disabled */
96 mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
97 /* MMUSIZEEXT == VTLB ON, FTLB OFF */
98 if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) {
99 /* This should never happen */
100 pr_warn("FTLB could not be disabled!\n");
101 return 1;
102 }
103
104 mips_ftlb_disabled = 1;
105 mips_has_ftlb_configured = 0;
106
107 /*
108 * noftlb is mainly used for debug purposes so print
109 * an informative message instead of using pr_debug()
110 */
111 pr_info("FTLB has been disabled\n");
112
113 /*
114 * Some of these bits are duplicated in the decode_config4.
115 * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case
116 * once FTLB has been disabled so undo what decode_config4 did.
117 */
118 cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways *
119 cpu_data[0].tlbsizeftlbsets;
120 cpu_data[0].tlbsizeftlbsets = 0;
121 cpu_data[0].tlbsizeftlbways = 0;
122
123 return 1;
124}
125
126__setup("noftlb", ftlb_disable);
127
128
72static inline void check_errata(void) 129static inline void check_errata(void)
73{ 130{
74 struct cpuinfo_mips *c = &current_cpu_data; 131 struct cpuinfo_mips *c = &current_cpu_data;
@@ -140,7 +197,7 @@ static inline unsigned long cpu_get_fpu_id(void)
140 */ 197 */
141static inline int __cpu_has_fpu(void) 198static inline int __cpu_has_fpu(void)
142{ 199{
143 return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE); 200 return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
144} 201}
145 202
146static inline unsigned long cpu_get_msa_id(void) 203static inline unsigned long cpu_get_msa_id(void)
@@ -399,6 +456,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
399 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; 456 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
400 /* fall through */ 457 /* fall through */
401 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: 458 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
459 if (mips_ftlb_disabled)
460 break;
402 newcf4 = (config4 & ~ftlb_page) | 461 newcf4 = (config4 & ~ftlb_page) |
403 (page_size_ftlb(mmuextdef) << 462 (page_size_ftlb(mmuextdef) <<
404 MIPS_CONF4_FTLBPAGESIZE_SHIFT); 463 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
@@ -418,6 +477,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
418 c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> 477 c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
419 MIPS_CONF4_FTLBWAYS_SHIFT) + 2; 478 MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
420 c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; 479 c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
480 mips_has_ftlb_configured = 1;
421 break; 481 break;
422 } 482 }
423 } 483 }
@@ -432,7 +492,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
432 unsigned int config5; 492 unsigned int config5;
433 493
434 config5 = read_c0_config5(); 494 config5 = read_c0_config5();
435 config5 &= ~MIPS_CONF5_UFR; 495 config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
436 write_c0_config5(config5); 496 write_c0_config5(config5);
437 497
438 if (config5 & MIPS_CONF5_EVA) 498 if (config5 & MIPS_CONF5_EVA)
@@ -453,8 +513,8 @@ static void decode_configs(struct cpuinfo_mips *c)
453 513
454 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 514 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
455 515
456 /* Enable FTLB if present */ 516 /* Enable FTLB if present and not disabled */
457 set_ftlb_enable(c, 1); 517 set_ftlb_enable(c, !mips_ftlb_disabled);
458 518
459 ok = decode_config0(c); /* Read Config registers. */ 519 ok = decode_config0(c); /* Read Config registers. */
460 BUG_ON(!ok); /* Arch spec violation! */ 520 BUG_ON(!ok); /* Arch spec violation! */
@@ -1058,6 +1118,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
1058 break; 1118 break;
1059 } 1119 }
1060 case PRID_IMP_BMIPS5000: 1120 case PRID_IMP_BMIPS5000:
1121 case PRID_IMP_BMIPS5200:
1061 c->cputype = CPU_BMIPS5000; 1122 c->cputype = CPU_BMIPS5000;
1062 __cpu_name[cpu] = "Broadcom BMIPS5000"; 1123 __cpu_name[cpu] = "Broadcom BMIPS5000";
1063 set_elf_platform(cpu, "bmips5000"); 1124 set_elf_platform(cpu, "bmips5000");
@@ -1288,6 +1349,8 @@ void cpu_probe(void)
1288 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { 1349 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
1289 if (c->fpu_id & MIPS_FPIR_3D) 1350 if (c->fpu_id & MIPS_FPIR_3D)
1290 c->ases |= MIPS_ASE_MIPS3D; 1351 c->ases |= MIPS_ASE_MIPS3D;
1352 if (c->fpu_id & MIPS_FPIR_FREP)
1353 c->options |= MIPS_CPU_FRE;
1291 } 1354 }
1292 } 1355 }
1293 1356