linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / mips / mm / c-r4k.c
index 069803f..a761f99 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/war.h>
 #include <asm/cacheflush.h> /* for run_uncached() */
 
-
-/*
- * Special Variant of smp_call_function for use by cache functions:
- *
- *  o No return value
- *  o collapses to normal function call on UP kernels
- *  o collapses to normal function call on systems with a single shared
- *    primary cache.
- */
-static inline void r4k_on_each_cpu(void (*func) (void *info), void *info,
-                                   int retry, int wait)
-{
-       preempt_disable();
-
-#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
-       smp_call_function(func, info, retry, wait);
-#endif
-       func(info);
-       preempt_enable();
-}
-
 /*
  * Must die.
  */
@@ -59,13 +39,13 @@ static unsigned long scache_size __read_mostly;
 /*
  * Dummy cache handling routines for machines without boardcaches
  */
-static void cache_noop(void) {}
+static void no_sc_noop(void) {}
 
 static struct bcache_ops no_sc_ops = {
-       .bc_enable = (void *)cache_noop,
-       .bc_disable = (void *)cache_noop,
-       .bc_wback_inv = (void *)cache_noop,
-       .bc_inv = (void *)cache_noop
+       .bc_enable = (void *)no_sc_noop,
+       .bc_disable = (void *)no_sc_noop,
+       .bc_wback_inv = (void *)no_sc_noop,
+       .bc_inv = (void *)no_sc_noop
 };
 
 struct bcache_ops *bcops = &no_sc_ops;
@@ -93,9 +73,7 @@ static inline void r4k_blast_dcache_page_setup(void)
 {
        unsigned long  dc_lsize = cpu_dcache_line_size();
 
-       if (dc_lsize == 0)
-               r4k_blast_dcache_page = (void *)cache_noop;
-       else if (dc_lsize == 16)
+       if (dc_lsize == 16)
                r4k_blast_dcache_page = blast_dcache16_page;
        else if (dc_lsize == 32)
                r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
@@ -107,9 +85,7 @@ static inline void r4k_blast_dcache_page_indexed_setup(void)
 {
        unsigned long dc_lsize = cpu_dcache_line_size();
 
-       if (dc_lsize == 0)
-               r4k_blast_dcache_page_indexed = (void *)cache_noop;
-       else if (dc_lsize == 16)
+       if (dc_lsize == 16)
                r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed;
        else if (dc_lsize == 32)
                r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
@@ -121,9 +97,7 @@ static inline void r4k_blast_dcache_setup(void)
 {
        unsigned long dc_lsize = cpu_dcache_line_size();
 
-       if (dc_lsize == 0)
-               r4k_blast_dcache = (void *)cache_noop;
-       else if (dc_lsize == 16)
+       if (dc_lsize == 16)
                r4k_blast_dcache = blast_dcache16;
        else if (dc_lsize == 32)
                r4k_blast_dcache = blast_dcache32;
@@ -206,9 +180,7 @@ static inline void r4k_blast_icache_page_setup(void)
 {
        unsigned long ic_lsize = cpu_icache_line_size();
 
-       if (ic_lsize == 0)
-               r4k_blast_icache_page = (void *)cache_noop;
-       else if (ic_lsize == 16)
+       if (ic_lsize == 16)
                r4k_blast_icache_page = blast_icache16_page;
        else if (ic_lsize == 32)
                r4k_blast_icache_page = blast_icache32_page;
@@ -223,9 +195,7 @@ static inline void r4k_blast_icache_page_indexed_setup(void)
 {
        unsigned long ic_lsize = cpu_icache_line_size();
 
-       if (ic_lsize == 0)
-               r4k_blast_icache_page_indexed = (void *)cache_noop;
-       else if (ic_lsize == 16)
+       if (ic_lsize == 16)
                r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
        else if (ic_lsize == 32) {
                if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
@@ -247,9 +217,7 @@ static inline void r4k_blast_icache_setup(void)
 {
        unsigned long ic_lsize = cpu_icache_line_size();
 
-       if (ic_lsize == 0)
-               r4k_blast_icache = (void *)cache_noop;
-       else if (ic_lsize == 16)
+       if (ic_lsize == 16)
                r4k_blast_icache = blast_icache16;
        else if (ic_lsize == 32) {
                if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
@@ -269,7 +237,7 @@ static inline void r4k_blast_scache_page_setup(void)
        unsigned long sc_lsize = cpu_scache_line_size();
 
        if (scache_size == 0)
-               r4k_blast_scache_page = (void *)cache_noop;
+               r4k_blast_scache_page = (void *)no_sc_noop;
        else if (sc_lsize == 16)
                r4k_blast_scache_page = blast_scache16_page;
        else if (sc_lsize == 32)
@@ -287,7 +255,7 @@ static inline void r4k_blast_scache_page_indexed_setup(void)
        unsigned long sc_lsize = cpu_scache_line_size();
 
        if (scache_size == 0)
-               r4k_blast_scache_page_indexed = (void *)cache_noop;
+               r4k_blast_scache_page_indexed = (void *)no_sc_noop;
        else if (sc_lsize == 16)
                r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
        else if (sc_lsize == 32)
@@ -305,7 +273,7 @@ static inline void r4k_blast_scache_setup(void)
        unsigned long sc_lsize = cpu_scache_line_size();
 
        if (scache_size == 0)
-               r4k_blast_scache = (void *)cache_noop;
+               r4k_blast_scache = (void *)no_sc_noop;
        else if (sc_lsize == 16)
                r4k_blast_scache = blast_scache16;
        else if (sc_lsize == 32)
@@ -331,7 +299,7 @@ static void r4k_flush_cache_all(void)
        if (!cpu_has_dc_aliases)
                return;
 
-       r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1);
+       on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1);
 }
 
 static inline void local_r4k___flush_cache_all(void * args)
@@ -346,14 +314,13 @@ static inline void local_r4k___flush_cache_all(void * args)
        case CPU_R4400MC:
        case CPU_R10000:
        case CPU_R12000:
-       case CPU_R14000:
                r4k_blast_scache();
        }
 }
 
 static void r4k___flush_cache_all(void)
 {
-       r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1);
+       on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1);
 }
 
 static inline void local_r4k_flush_cache_range(void * args)
@@ -374,7 +341,7 @@ static inline void local_r4k_flush_cache_range(void * args)
 static void r4k_flush_cache_range(struct vm_area_struct *vma,
        unsigned long start, unsigned long end)
 {
-       r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
+       on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
 }
 
 static inline void local_r4k_flush_cache_mm(void * args)
@@ -403,7 +370,7 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
        if (!cpu_has_dc_aliases)
                return;
 
-       r4k_on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
+       on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
 }
 
 struct flush_cache_page_args {
@@ -494,7 +461,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,
        args.addr = addr;
        args.pfn = pfn;
 
-       r4k_on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
+       on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
 }
 
 static inline void local_r4k_flush_data_cache_page(void * addr)
@@ -504,7 +471,7 @@ static inline void local_r4k_flush_data_cache_page(void * addr)
 
 static void r4k_flush_data_cache_page(unsigned long addr)
 {
-       r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr, 1, 1);
+       on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr, 1, 1);
 }
 
 struct flush_icache_range_args {
@@ -519,7 +486,7 @@ static inline void local_r4k_flush_icache_range(void *args)
        unsigned long end = fir_args->end;
 
        if (!cpu_has_ic_fills_f_dc) {
-               if (end - start >= dcache_size) {
+               if (end - start > dcache_size) {
                        r4k_blast_dcache();
                } else {
                        R4600_HIT_CACHEOP_WAR_IMPL;
@@ -547,7 +514,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
        args.start = start;
        args.end = end;
 
-       r4k_on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
+       on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
        instruction_hazard();
 }
 
@@ -578,7 +545,7 @@ static inline void local_r4k_flush_icache_page(void *args)
         * secondary cache will result in any entries in the primary caches
         * also getting invalidated which hopefully is a bit more economical.
         */
-       if (cpu_has_inclusive_pcaches) {
+       if (cpu_has_subset_pcaches) {
                unsigned long addr = (unsigned long) page_address(page);
 
                r4k_blast_scache_page(addr);
@@ -623,7 +590,7 @@ static void r4k_flush_icache_page(struct vm_area_struct *vma,
        args.vma = vma;
        args.page = page;
 
-       r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
+       on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
 }
 
 
@@ -634,7 +601,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
        /* Catch bad driver code */
        BUG_ON(size == 0);
 
-       if (cpu_has_inclusive_pcaches) {
+       if (cpu_has_subset_pcaches) {
                if (size >= scache_size)
                        r4k_blast_scache();
                else
@@ -662,7 +629,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
        /* Catch bad driver code */
        BUG_ON(size == 0);
 
-       if (cpu_has_inclusive_pcaches) {
+       if (cpu_has_subset_pcaches) {
                if (size >= scache_size)
                        r4k_blast_scache();
                else
@@ -694,12 +661,10 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
        unsigned long addr = (unsigned long) arg;
 
        R4600_HIT_CACHEOP_WAR_IMPL;
-       if (dc_lsize)
-               protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+       protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
        if (!cpu_icache_snoops_remote_store && scache_size)
                protected_writeback_scache_line(addr & ~(sc_lsize - 1));
-       if (ic_lsize)
-               protected_flush_icache_line(addr & ~(ic_lsize - 1));
+       protected_flush_icache_line(addr & ~(ic_lsize - 1));
        if (MIPS4K_ICACHE_REFILL_WAR) {
                __asm__ __volatile__ (
                        ".set push\n\t"
@@ -724,7 +689,7 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
 
 static void r4k_flush_cache_sigtramp(unsigned long addr)
 {
-       r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1, 1);
+       on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1, 1);
 }
 
 static void r4k_flush_icache_all(void)
@@ -785,12 +750,12 @@ static void __init probe_pcache(void)
                icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
                c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
                c->icache.ways = 2;
-               c->icache.waybit = __ffs(icache_size/2);
+               c->icache.waybit = ffs(icache_size/2) - 1;
 
                dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
                c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
                c->dcache.ways = 2;
-               c->dcache.waybit= __ffs(dcache_size/2);
+               c->dcache.waybit= ffs(dcache_size/2) - 1;
 
                c->options |= MIPS_CPU_CACHE_CDEX_P;
                break;
@@ -822,7 +787,6 @@ static void __init probe_pcache(void)
                c->dcache.waybit = 0;
 
                c->options |= MIPS_CPU_CACHE_CDEX_P;
-               c->options |= MIPS_CPU_PREFETCH;
                break;
 
        case CPU_R4000PC:
@@ -847,7 +811,6 @@ static void __init probe_pcache(void)
 
        case CPU_R10000:
        case CPU_R12000:
-       case CPU_R14000:
                icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29));
                c->icache.linesz = 64;
                c->icache.ways = 2;
@@ -862,27 +825,26 @@ static void __init probe_pcache(void)
                break;
 
        case CPU_VR4133:
-               write_c0_config(config & ~VR41_CONF_P4K);
+               write_c0_config(config & ~CONF_EB);
        case CPU_VR4131:
                /* Workaround for cache instruction bug of VR4131 */
                if (c->processor_id == 0x0c80U || c->processor_id == 0x0c81U ||
                    c->processor_id == 0x0c82U) {
-                       config |= 0x00400000U;
-                       if (c->processor_id == 0x0c80U)
-                               config |= VR41_CONF_BP;
+                       config &= ~0x00000030U;
+                       config |= 0x00410000U;
                        write_c0_config(config);
-               } else
-                       c->options |= MIPS_CPU_CACHE_CDEX_P;
-
+               }
                icache_size = 1 << (10 + ((config & CONF_IC) >> 9));
                c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
                c->icache.ways = 2;
-               c->icache.waybit = __ffs(icache_size/2);
+               c->icache.waybit = ffs(icache_size/2) - 1;
 
                dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));
                c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
                c->dcache.ways = 2;
-               c->dcache.waybit = __ffs(dcache_size/2);
+               c->dcache.waybit = ffs(dcache_size/2) - 1;
+
+               c->options |= MIPS_CPU_CACHE_CDEX_P;
                break;
 
        case CPU_VR41XX:
@@ -911,12 +873,12 @@ static void __init probe_pcache(void)
                icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
                c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
                c->icache.ways = 4;
-               c->icache.waybit = __ffs(icache_size / c->icache.ways);
+               c->icache.waybit = ffs(icache_size / c->icache.ways) - 1;
 
                dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
                c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
                c->dcache.ways = 4;
-               c->dcache.waybit = __ffs(dcache_size / c->dcache.ways);
+               c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
 
 #if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
                c->options |= MIPS_CPU_CACHE_CDEX_P;
@@ -944,7 +906,7 @@ static void __init probe_pcache(void)
                icache_size = c->icache.sets *
                              c->icache.ways *
                              c->icache.linesz;
-               c->icache.waybit = __ffs(icache_size/c->icache.ways);
+               c->icache.waybit = ffs(icache_size/c->icache.ways) - 1;
 
                if (config & 0x8)               /* VI bit */
                        c->icache.flags |= MIPS_CACHE_VTAG;
@@ -964,7 +926,7 @@ static void __init probe_pcache(void)
                dcache_size = c->dcache.sets *
                              c->dcache.ways *
                              c->dcache.linesz;
-               c->dcache.waybit = __ffs(dcache_size/c->dcache.ways);
+               c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1;
 
                c->options |= MIPS_CPU_PREFETCH;
                break;
@@ -987,10 +949,8 @@ static void __init probe_pcache(void)
        c->icache.waysize = icache_size / c->icache.ways;
        c->dcache.waysize = dcache_size / c->dcache.ways;
 
-       c->icache.sets = c->icache.linesz ?
-               icache_size / (c->icache.linesz * c->icache.ways) : 0;
-       c->dcache.sets = c->dcache.linesz ?
-               dcache_size / (c->dcache.linesz * c->dcache.ways) : 0;
+       c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways);
+       c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways);
 
        /*
         * R10000 and R12000 P-caches are odd in a positive way.  They're 32kB
@@ -1004,21 +964,13 @@ static void __init probe_pcache(void)
                c->dcache.flags |= MIPS_CACHE_PINDEX;
        case CPU_R10000:
        case CPU_R12000:
-       case CPU_R14000:
        case CPU_SB1:
                break;
        case CPU_24K:
-       case CPU_34K:
-       case CPU_74K:
-               if ((read_c0_config7() & (1 << 16))) {
-                       /* effectively physically indexed dcache,
-                          thus no virtual aliases. */
-                       c->dcache.flags |= MIPS_CACHE_PINDEX;
-                       break;
-               }
+               if (!(read_c0_config7() & (1 << 16)))
        default:
-               if (c->dcache.waysize > PAGE_SIZE)
-                       c->dcache.flags |= MIPS_CACHE_ALIASES;
+                       if (c->dcache.waysize > PAGE_SIZE)
+                               c->dcache.flags |= MIPS_CACHE_ALIASES;
        }
 
        switch (c->cputype) {
@@ -1114,7 +1066,6 @@ static int __init probe_scache(void)
 
 extern int r5k_sc_init(void);
 extern int rm7k_sc_init(void);
-extern int mips_sc_init(void);
 
 static void __init setup_scache(void)
 {
@@ -1139,7 +1090,6 @@ static void __init setup_scache(void)
 
        case CPU_R10000:
        case CPU_R12000:
-       case CPU_R14000:
                scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16);
                c->scache.linesz = 64 << ((config >> 13) & 1);
                c->scache.ways = 2;
@@ -1162,29 +1112,17 @@ static void __init setup_scache(void)
                return;
 
        default:
-               if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
-                   c->isa_level == MIPS_CPU_ISA_M32R2 ||
-                   c->isa_level == MIPS_CPU_ISA_M64R1 ||
-                   c->isa_level == MIPS_CPU_ISA_M64R2) {
-#ifdef CONFIG_MIPS_CPU_SCACHE
-                       if (mips_sc_init ()) {
-                               scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;
-                               printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n",
-                                      scache_size >> 10,
-                                      way_string[c->scache.ways], c->scache.linesz);
-                       }
-#else
-                       if (!(c->scache.flags & MIPS_CACHE_NOT_PRESENT))
-                               panic("Dunno how to handle MIPS32 / MIPS64 second level cache");
-#endif
-                       return;
-               }
                sc_present = 0;
        }
 
        if (!sc_present)
                return;
 
+       if ((c->isa_level == MIPS_CPU_ISA_M32R1 ||
+            c->isa_level == MIPS_CPU_ISA_M64R1) &&
+           !(c->scache.flags & MIPS_CACHE_NOT_PRESENT))
+               panic("Dunno how to handle MIPS32 / MIPS64 second level cache");
+
        /* compute a couple of other cache variables */
        c->scache.waysize = scache_size / c->scache.ways;
 
@@ -1193,32 +1131,7 @@ static void __init setup_scache(void)
        printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
               scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
 
-       c->options |= MIPS_CPU_INCLUSIVE_CACHES;
-}
-
-void au1x00_fixup_config_od(void)
-{
-       /*
-        * c0_config.od (bit 19) was write only (and read as 0)
-        * on the early revisions of Alchemy SOCs.  It disables the bus
-        * transaction overlapping and needs to be set to fix various errata.
-        */
-       switch (read_c0_prid()) {
-       case 0x00030100: /* Au1000 DA */
-       case 0x00030201: /* Au1000 HA */
-       case 0x00030202: /* Au1000 HB */
-       case 0x01030200: /* Au1500 AB */
-       /*
-        * Au1100 errata actually keeps silence about this bit, so we set it
-        * just in case for those revisions that require it to be set according
-        * to arch/mips/au1000/common/cputable.c
-        */
-       case 0x02030200: /* Au1100 AB */
-       case 0x02030201: /* Au1100 BA */
-       case 0x02030202: /* Au1100 BC */
-               set_c0_config(1 << 19);
-               break;
-       }
+       c->options |= MIPS_CPU_SUBSET_CACHES;
 }
 
 static inline void coherency_setup(void)
@@ -1241,15 +1154,6 @@ static inline void coherency_setup(void)
        case CPU_R4400MC:
                clear_c0_config(CONF_CU);
                break;
-       /*
-        * We need to catch the ealry Alchemy SOCs with
-        * the write-only co_config.od bit and set it back to one...
-        */
-       case CPU_AU1000: /* rev. DA, HA, HB */
-       case CPU_AU1100: /* rev. AB, BA, BC ?? */
-       case CPU_AU1500: /* rev. AB */
-               au1x00_fixup_config_od();
-               break;
        }
 }
 
@@ -1281,12 +1185,10 @@ void __init r4k_cache_init(void)
         * This code supports virtually indexed processors and will be
         * unnecessarily inefficient on physically indexed processors.
         */
-       if (c->dcache.linesz)
-               shm_align_mask = max_t( unsigned long,
-                                       c->dcache.sets * c->dcache.linesz - 1,
-                                       PAGE_SIZE - 1);
-       else
-               shm_align_mask = PAGE_SIZE-1;
+       shm_align_mask = max_t( unsigned long,
+                               c->dcache.sets * c->dcache.linesz - 1,
+                               PAGE_SIZE - 1);
+
        flush_cache_all         = r4k_flush_cache_all;
        __flush_cache_all       = r4k___flush_cache_all;
        flush_cache_mm          = r4k_flush_cache_mm;
@@ -1296,7 +1198,6 @@ void __init r4k_cache_init(void)
 
        flush_cache_sigtramp    = r4k_flush_cache_sigtramp;
        flush_icache_all        = r4k_flush_icache_all;
-       local_flush_data_cache_page     = local_r4k_flush_data_cache_page;
        flush_data_cache_page   = r4k_flush_data_cache_page;
        flush_icache_range      = r4k_flush_icache_range;