diff options
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 103 |
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) | |||
163 | static char unknown_isa[] = KERN_ERR \ | 163 | static char unknown_isa[] = KERN_ERR \ |
164 | "Unsupported ISA type, c0.config0: %d."; | 164 | "Unsupported ISA type, c0.config0: %d."; |
165 | 165 | ||
166 | static 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 | |||
166 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) | 185 | static 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) | |||
279 | static inline unsigned int decode_config4(struct cpuinfo_mips *c) | 308 | static 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 | ||
676 | static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | 747 | static 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; |