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.c103
1 files changed, 96 insertions, 7 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index c814287bdf5d..530f832de02c 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -112,7 +112,7 @@ static inline unsigned long cpu_get_fpu_id(void)
112 unsigned long tmp, fpu_id; 112 unsigned long tmp, fpu_id;
113 113
114 tmp = read_c0_status(); 114 tmp = read_c0_status();
115 __enable_fpu(); 115 __enable_fpu(FPU_AS_IS);
116 fpu_id = read_32bit_cp1_register(CP1_REVISION); 116 fpu_id = read_32bit_cp1_register(CP1_REVISION);
117 write_c0_status(tmp); 117 write_c0_status(tmp);
118 return fpu_id; 118 return fpu_id;
@@ -163,6 +163,25 @@ static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
163static char unknown_isa[] = KERN_ERR \ 163static char unknown_isa[] = KERN_ERR \
164 "Unsupported ISA type, c0.config0: %d."; 164 "Unsupported ISA type, c0.config0: %d.";
165 165
166static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)
167{
168 unsigned int config6;
169 /*
170 * Config6 is implementation dependent and it's currently only
171 * used by proAptiv
172 */
173 if (c->cputype == CPU_PROAPTIV) {
174 config6 = read_c0_config6();
175 if (enable)
176 /* Enable FTLB */
177 write_c0_config6(config6 | MIPS_CONF6_FTLBEN);
178 else
179 /* Disable FTLB */
180 write_c0_config6(config6 & ~MIPS_CONF6_FTLBEN);
181 back_to_back_c0_hazard();
182 }
183}
184
166static inline unsigned int decode_config0(struct cpuinfo_mips *c) 185static inline unsigned int decode_config0(struct cpuinfo_mips *c)
167{ 186{
168 unsigned int config0; 187 unsigned int config0;
@@ -170,8 +189,13 @@ static inline unsigned int decode_config0(struct cpuinfo_mips *c)
170 189
171 config0 = read_c0_config(); 190 config0 = read_c0_config();
172 191
173 if (((config0 & MIPS_CONF_MT) >> 7) == 1) 192 /*
193 * Look for Standard TLB or Dual VTLB and FTLB
194 */
195 if ((((config0 & MIPS_CONF_MT) >> 7) == 1) ||
196 (((config0 & MIPS_CONF_MT) >> 7) == 4))
174 c->options |= MIPS_CPU_TLB; 197 c->options |= MIPS_CPU_TLB;
198
175 isa = (config0 & MIPS_CONF_AT) >> 13; 199 isa = (config0 & MIPS_CONF_AT) >> 13;
176 switch (isa) { 200 switch (isa) {
177 case 0: 201 case 0:
@@ -226,8 +250,11 @@ static inline unsigned int decode_config1(struct cpuinfo_mips *c)
226 c->options |= MIPS_CPU_FPU; 250 c->options |= MIPS_CPU_FPU;
227 c->options |= MIPS_CPU_32FPR; 251 c->options |= MIPS_CPU_32FPR;
228 } 252 }
229 if (cpu_has_tlb) 253 if (cpu_has_tlb) {
230 c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; 254 c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
255 c->tlbsizevtlb = c->tlbsize;
256 c->tlbsizeftlbsets = 0;
257 }
231 258
232 return config1 & MIPS_CONF_M; 259 return config1 & MIPS_CONF_M;
233} 260}
@@ -272,6 +299,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
272 c->options |= MIPS_CPU_MICROMIPS; 299 c->options |= MIPS_CPU_MICROMIPS;
273 if (config3 & MIPS_CONF3_VZ) 300 if (config3 & MIPS_CONF3_VZ)
274 c->ases |= MIPS_ASE_VZ; 301 c->ases |= MIPS_ASE_VZ;
302 if (config3 & MIPS_CONF3_SC)
303 c->options |= MIPS_CPU_SEGMENTS;
275 304
276 return config3 & MIPS_CONF_M; 305 return config3 & MIPS_CONF_M;
277} 306}
@@ -279,12 +308,51 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
279static inline unsigned int decode_config4(struct cpuinfo_mips *c) 308static inline unsigned int decode_config4(struct cpuinfo_mips *c)
280{ 309{
281 unsigned int config4; 310 unsigned int config4;
311 unsigned int newcf4;
312 unsigned int mmuextdef;
313 unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE;
282 314
283 config4 = read_c0_config4(); 315 config4 = read_c0_config4();
284 316
285 if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT 317 if (cpu_has_tlb) {
286 && cpu_has_tlb) 318 if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
287 c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; 319 c->options |= MIPS_CPU_TLBINV;
320 mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
321 switch (mmuextdef) {
322 case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:
323 c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
324 c->tlbsizevtlb = c->tlbsize;
325 break;
326 case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
327 c->tlbsizevtlb +=
328 ((config4 & MIPS_CONF4_VTLBSIZEEXT) >>
329 MIPS_CONF4_VTLBSIZEEXT_SHIFT) * 0x40;
330 c->tlbsize = c->tlbsizevtlb;
331 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
332 /* fall through */
333 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
334 newcf4 = (config4 & ~ftlb_page) |
335 (page_size_ftlb(mmuextdef) <<
336 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
337 write_c0_config4(newcf4);
338 back_to_back_c0_hazard();
339 config4 = read_c0_config4();
340 if (config4 != newcf4) {
341 pr_err("PAGE_SIZE 0x%lx is not supported by FTLB (config4=0x%x)\n",
342 PAGE_SIZE, config4);
343 /* Switch FTLB off */
344 set_ftlb_enable(c, 0);
345 break;
346 }
347 c->tlbsizeftlbsets = 1 <<
348 ((config4 & MIPS_CONF4_FTLBSETS) >>
349 MIPS_CONF4_FTLBSETS_SHIFT);
350 c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
351 MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
352 c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
353 break;
354 }
355 }
288 356
289 c->kscratch_mask = (config4 >> 16) & 0xff; 357 c->kscratch_mask = (config4 >> 16) & 0xff;
290 358
@@ -312,6 +380,9 @@ static void decode_configs(struct cpuinfo_mips *c)
312 380
313 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 381 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
314 382
383 /* Enable FTLB if present */
384 set_ftlb_enable(c, 1);
385
315 ok = decode_config0(c); /* Read Config registers. */ 386 ok = decode_config0(c); /* Read Config registers. */
316 BUG_ON(!ok); /* Arch spec violation! */ 387 BUG_ON(!ok); /* Arch spec violation! */
317 if (ok) 388 if (ok)
@@ -675,7 +746,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
675 746
676static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) 747static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
677{ 748{
678 decode_configs(c);
679 switch (c->processor_id & PRID_IMP_MASK) { 749 switch (c->processor_id & PRID_IMP_MASK) {
680 case PRID_IMP_4KC: 750 case PRID_IMP_4KC:
681 c->cputype = CPU_4KC; 751 c->cputype = CPU_4KC;
@@ -739,8 +809,26 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
739 c->cputype = CPU_74K; 809 c->cputype = CPU_74K;
740 __cpu_name[cpu] = "MIPS 1074Kc"; 810 __cpu_name[cpu] = "MIPS 1074Kc";
741 break; 811 break;
812 case PRID_IMP_INTERAPTIV_UP:
813 c->cputype = CPU_INTERAPTIV;
814 __cpu_name[cpu] = "MIPS interAptiv";
815 break;
816 case PRID_IMP_INTERAPTIV_MP:
817 c->cputype = CPU_INTERAPTIV;
818 __cpu_name[cpu] = "MIPS interAptiv (multi)";
819 break;
820 case PRID_IMP_PROAPTIV_UP:
821 c->cputype = CPU_PROAPTIV;
822 __cpu_name[cpu] = "MIPS proAptiv";
823 break;
824 case PRID_IMP_PROAPTIV_MP:
825 c->cputype = CPU_PROAPTIV;
826 __cpu_name[cpu] = "MIPS proAptiv (multi)";
827 break;
742 } 828 }
743 829
830 decode_configs(c);
831
744 spram_config(); 832 spram_config();
745} 833}
746 834
@@ -943,6 +1031,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
943 1031
944 switch (c->processor_id & PRID_IMP_MASK) { 1032 switch (c->processor_id & PRID_IMP_MASK) {
945 case PRID_IMP_NETLOGIC_XLP2XX: 1033 case PRID_IMP_NETLOGIC_XLP2XX:
1034 case PRID_IMP_NETLOGIC_XLP9XX:
946 c->cputype = CPU_XLP; 1035 c->cputype = CPU_XLP;
947 __cpu_name[cpu] = "Broadcom XLPII"; 1036 __cpu_name[cpu] = "Broadcom XLPII";
948 break; 1037 break;