aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/cpu-probe.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2015-04-03 18:27:54 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-04-07 19:10:40 -0400
commit7aecd5ca80d1c08f882a5357ddae8c677c7fd1af (patch)
treea5f607ba95c3476881816dd0fb81c9def5044d6a /arch/mips/kernel/cpu-probe.c
parent9b26616c8d9dae53fbac7f7cb2c6dd1308102976 (diff)
MIPS: Factor out FPU feature probing
Factor out FPU feature probing, mainly to remove code duplication from `fpu_disable'. No functional change although shuffle some code to avoid forward references. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/9712/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
-rw-r--r--arch/mips/kernel/cpu-probe.c125
1 files changed, 71 insertions, 54 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 2911ad5977d7..73ab840f13bd 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -33,6 +33,41 @@
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34 34
35/* 35/*
36 * Get the FPU Implementation/Revision.
37 */
38static inline unsigned long cpu_get_fpu_id(void)
39{
40 unsigned long tmp, fpu_id;
41
42 tmp = read_c0_status();
43 __enable_fpu(FPU_AS_IS);
44 fpu_id = read_32bit_cp1_register(CP1_REVISION);
45 write_c0_status(tmp);
46 return fpu_id;
47}
48
49/*
50 * Check if the CPU has an external FPU.
51 */
52static inline int __cpu_has_fpu(void)
53{
54 return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
55}
56
57static inline unsigned long cpu_get_msa_id(void)
58{
59 unsigned long status, msa_id;
60
61 status = read_c0_status();
62 __enable_fpu(FPU_64BIT);
63 enable_msa();
64 msa_id = read_msa_ir();
65 disable_msa();
66 write_c0_status(status);
67 return msa_id;
68}
69
70/*
36 * Determine the FCSR mask for FPU hardware. 71 * Determine the FCSR mask for FPU hardware.
37 */ 72 */
38static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c) 73static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
@@ -82,13 +117,42 @@ static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
82/* Determined FPU emulator mask to use for the boot CPU with "nofpu". */ 117/* Determined FPU emulator mask to use for the boot CPU with "nofpu". */
83static unsigned int mips_nofpu_msk31; 118static unsigned int mips_nofpu_msk31;
84 119
120/*
121 * Set options for FPU hardware.
122 */
123static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
124{
125 c->fpu_id = cpu_get_fpu_id();
126 mips_nofpu_msk31 = c->fpu_msk31;
127
128 if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
129 MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
130 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
131 if (c->fpu_id & MIPS_FPIR_3D)
132 c->ases |= MIPS_ASE_MIPS3D;
133 if (c->fpu_id & MIPS_FPIR_FREP)
134 c->options |= MIPS_CPU_FRE;
135 }
136
137 cpu_set_fpu_fcsr_mask(c);
138}
139
140/*
141 * Set options for the FPU emulator.
142 */
143static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
144{
145 c->options &= ~MIPS_CPU_FPU;
146 c->fpu_msk31 = mips_nofpu_msk31;
147
148 cpu_set_nofpu_id(c);
149}
150
85static int mips_fpu_disabled; 151static int mips_fpu_disabled;
86 152
87static int __init fpu_disable(char *s) 153static int __init fpu_disable(char *s)
88{ 154{
89 boot_cpu_data.options &= ~MIPS_CPU_FPU; 155 cpu_set_nofpu_opts(&boot_cpu_data);
90 boot_cpu_data.fpu_msk31 = mips_nofpu_msk31;
91 cpu_set_nofpu_id(&boot_cpu_data);
92 mips_fpu_disabled = 1; 156 mips_fpu_disabled = 1;
93 157
94 return 1; 158 return 1;
@@ -231,41 +295,6 @@ static inline void set_elf_platform(int cpu, const char *plat)
231 __elf_platform = plat; 295 __elf_platform = plat;
232} 296}
233 297
234/*
235 * Get the FPU Implementation/Revision.
236 */
237static inline unsigned long cpu_get_fpu_id(void)
238{
239 unsigned long tmp, fpu_id;
240
241 tmp = read_c0_status();
242 __enable_fpu(FPU_AS_IS);
243 fpu_id = read_32bit_cp1_register(CP1_REVISION);
244 write_c0_status(tmp);
245 return fpu_id;
246}
247
248/*
249 * Check if the CPU has an external FPU.
250 */
251static inline int __cpu_has_fpu(void)
252{
253 return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
254}
255
256static inline unsigned long cpu_get_msa_id(void)
257{
258 unsigned long status, msa_id;
259
260 status = read_c0_status();
261 __enable_fpu(FPU_64BIT);
262 enable_msa();
263 msa_id = read_msa_ir();
264 disable_msa();
265 write_c0_status(status);
266 return msa_id;
267}
268
269static inline void cpu_probe_vmbits(struct cpuinfo_mips *c) 298static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
270{ 299{
271#ifdef __NEED_VMBITS_PROBE 300#ifdef __NEED_VMBITS_PROBE
@@ -1441,22 +1470,10 @@ void cpu_probe(void)
1441 ~(1 << MIPS_PWCTL_PWEN_SHIFT)); 1470 ~(1 << MIPS_PWCTL_PWEN_SHIFT));
1442 } 1471 }
1443 1472
1444 if (c->options & MIPS_CPU_FPU) { 1473 if (c->options & MIPS_CPU_FPU)
1445 c->fpu_id = cpu_get_fpu_id(); 1474 cpu_set_fpu_opts(c);
1446 mips_nofpu_msk31 = c->fpu_msk31; 1475 else
1447 1476 cpu_set_nofpu_opts(c);
1448 if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
1449 MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
1450 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
1451 if (c->fpu_id & MIPS_FPIR_3D)
1452 c->ases |= MIPS_ASE_MIPS3D;
1453 if (c->fpu_id & MIPS_FPIR_FREP)
1454 c->options |= MIPS_CPU_FRE;
1455 }
1456
1457 cpu_set_fpu_fcsr_mask(c);
1458 } else
1459 cpu_set_nofpu_id(c);
1460 1477
1461 if (cpu_has_mips_r2_r6) { 1478 if (cpu_has_mips_r2_r6) {
1462 c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; 1479 c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;