Merge tag 'iwlwifi-next-for-kalle-2014-12-30' of https://git.kernel.org/pub/scm/linux...
[cascardo/linux.git] / arch / mips / kernel / cpu-probe.c
index dc49cf3..5342674 100644 (file)
@@ -69,6 +69,63 @@ static int __init htw_disable(char *s)
 
 __setup("nohtw", htw_disable);
 
+static int mips_ftlb_disabled;
+static int mips_has_ftlb_configured;
+
+static void set_ftlb_enable(struct cpuinfo_mips *c, int enable);
+
+static int __init ftlb_disable(char *s)
+{
+       unsigned int config4, mmuextdef;
+
+       /*
+        * If the core hasn't done any FTLB configuration, there is nothing
+        * for us to do here.
+        */
+       if (!mips_has_ftlb_configured)
+               return 1;
+
+       /* Disable it in the boot cpu */
+       set_ftlb_enable(&cpu_data[0], 0);
+
+       back_to_back_c0_hazard();
+
+       config4 = read_c0_config4();
+
+       /* Check that FTLB has been disabled */
+       mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
+       /* MMUSIZEEXT == VTLB ON, FTLB OFF */
+       if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) {
+               /* This should never happen */
+               pr_warn("FTLB could not be disabled!\n");
+               return 1;
+       }
+
+       mips_ftlb_disabled = 1;
+       mips_has_ftlb_configured = 0;
+
+       /*
+        * noftlb is mainly used for debug purposes so print
+        * an informative message instead of using pr_debug()
+        */
+       pr_info("FTLB has been disabled\n");
+
+       /*
+        * Some of these bits are duplicated in the decode_config4.
+        * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case
+        * once FTLB has been disabled so undo what decode_config4 did.
+        */
+       cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways *
+                              cpu_data[0].tlbsizeftlbsets;
+       cpu_data[0].tlbsizeftlbsets = 0;
+       cpu_data[0].tlbsizeftlbways = 0;
+
+       return 1;
+}
+
+__setup("noftlb", ftlb_disable);
+
+
 static inline void check_errata(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
@@ -140,7 +197,7 @@ static inline unsigned long cpu_get_fpu_id(void)
  */
 static inline int __cpu_has_fpu(void)
 {
-       return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE);
+       return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
 }
 
 static inline unsigned long cpu_get_msa_id(void)
@@ -399,6 +456,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
                        ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
                        /* fall through */
                case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
+                       if (mips_ftlb_disabled)
+                               break;
                        newcf4 = (config4 & ~ftlb_page) |
                                (page_size_ftlb(mmuextdef) <<
                                 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
@@ -418,6 +477,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
                        c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
                                              MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
                        c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
+                       mips_has_ftlb_configured = 1;
                        break;
                }
        }
@@ -432,7 +492,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
        unsigned int config5;
 
        config5 = read_c0_config5();
-       config5 &= ~MIPS_CONF5_UFR;
+       config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
        write_c0_config5(config5);
 
        if (config5 & MIPS_CONF5_EVA)
@@ -453,8 +513,8 @@ static void decode_configs(struct cpuinfo_mips *c)
 
        c->scache.flags = MIPS_CACHE_NOT_PRESENT;
 
-       /* Enable FTLB if present */
-       set_ftlb_enable(c, 1);
+       /* Enable FTLB if present and not disabled */
+       set_ftlb_enable(c, !mips_ftlb_disabled);
 
        ok = decode_config0(c);                 /* Read Config registers.  */
        BUG_ON(!ok);                            /* Arch spec violation!  */
@@ -1058,6 +1118,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
                break;
        }
        case PRID_IMP_BMIPS5000:
+       case PRID_IMP_BMIPS5200:
                c->cputype = CPU_BMIPS5000;
                __cpu_name[cpu] = "Broadcom BMIPS5000";
                set_elf_platform(cpu, "bmips5000");
@@ -1288,6 +1349,8 @@ void cpu_probe(void)
                                    MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
                        if (c->fpu_id & MIPS_FPIR_3D)
                                c->ases |= MIPS_ASE_MIPS3D;
+                       if (c->fpu_id & MIPS_FPIR_FREP)
+                               c->options |= MIPS_CPU_FRE;
                }
        }