diff options
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/mm/c-r4k.c | 100 | ||||
-rw-r--r-- | arch/mips/mm/c-sb1.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/cache.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/cerr-sb1.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/dma-coherent.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/dma-noncoherent.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/highmem.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/pg-sb1.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/pgtable-32.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/pgtable.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/sc-mips.c | 112 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r8k.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 1 |
16 files changed, 181 insertions, 45 deletions
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 4a6220116c96..19e41fd186c4 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o +obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o # # Choose one DMA coherency model diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 4a43924cd4fc..857b726f4d41 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -7,7 +7,6 @@ * 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> @@ -60,13 +59,13 @@ static unsigned long scache_size __read_mostly; /* * Dummy cache handling routines for machines without boardcaches */ -static void no_sc_noop(void) {} +static void cache_noop(void) {} static struct bcache_ops no_sc_ops = { - .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 + .bc_enable = (void *)cache_noop, + .bc_disable = (void *)cache_noop, + .bc_wback_inv = (void *)cache_noop, + .bc_inv = (void *)cache_noop }; struct bcache_ops *bcops = &no_sc_ops; @@ -94,7 +93,9 @@ static inline void r4k_blast_dcache_page_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); - if (dc_lsize == 16) + if (dc_lsize == 0) + r4k_blast_dcache_page = (void *)cache_noop; + else 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; @@ -106,7 +107,9 @@ static inline void r4k_blast_dcache_page_indexed_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); - if (dc_lsize == 16) + if (dc_lsize == 0) + r4k_blast_dcache_page_indexed = (void *)cache_noop; + else 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; @@ -118,7 +121,9 @@ static inline void r4k_blast_dcache_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); - if (dc_lsize == 16) + if (dc_lsize == 0) + r4k_blast_dcache = (void *)cache_noop; + else if (dc_lsize == 16) r4k_blast_dcache = blast_dcache16; else if (dc_lsize == 32) r4k_blast_dcache = blast_dcache32; @@ -201,7 +206,9 @@ static inline void r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); - if (ic_lsize == 16) + if (ic_lsize == 0) + r4k_blast_icache_page = (void *)cache_noop; + else if (ic_lsize == 16) r4k_blast_icache_page = blast_icache16_page; else if (ic_lsize == 32) r4k_blast_icache_page = blast_icache32_page; @@ -216,7 +223,9 @@ static inline void r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); - if (ic_lsize == 16) + if (ic_lsize == 0) + r4k_blast_icache_page_indexed = (void *)cache_noop; + else 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()) @@ -238,7 +247,9 @@ static inline void r4k_blast_icache_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); - if (ic_lsize == 16) + if (ic_lsize == 0) + r4k_blast_icache = (void *)cache_noop; + else 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()) @@ -258,7 +269,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 *)no_sc_noop; + r4k_blast_scache_page = (void *)cache_noop; else if (sc_lsize == 16) r4k_blast_scache_page = blast_scache16_page; else if (sc_lsize == 32) @@ -276,7 +287,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 *)no_sc_noop; + r4k_blast_scache_page_indexed = (void *)cache_noop; else if (sc_lsize == 16) r4k_blast_scache_page_indexed = blast_scache16_page_indexed; else if (sc_lsize == 32) @@ -294,7 +305,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 *)no_sc_noop; + r4k_blast_scache = (void *)cache_noop; else if (sc_lsize == 16) r4k_blast_scache = blast_scache16; else if (sc_lsize == 32) @@ -508,7 +519,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; @@ -683,10 +694,12 @@ static void local_r4k_flush_cache_sigtramp(void * arg) unsigned long addr = (unsigned long) arg; R4600_HIT_CACHEOP_WAR_IMPL; - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + if (dc_lsize) + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); if (!cpu_icache_snoops_remote_store && scache_size) protected_writeback_scache_line(addr & ~(sc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); + if (ic_lsize) + protected_flush_icache_line(addr & ~(ic_lsize - 1)); if (MIPS4K_ICACHE_REFILL_WAR) { __asm__ __volatile__ ( ".set push\n\t" @@ -973,8 +986,10 @@ 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 = icache_size / (c->icache.linesz * c->icache.ways); - c->dcache.sets = dcache_size / (c->dcache.linesz * 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; /* * R10000 and R12000 P-caches are odd in a positive way. They're 32kB @@ -993,10 +1008,16 @@ static void __init probe_pcache(void) break; case CPU_24K: case CPU_34K: - if (!(read_c0_config7() & (1 << 16))) + case CPU_74K: + if ((read_c0_config7() & (1 << 16))) { + /* effectively physically indexed dcache, + thus no virtual aliases. */ + c->dcache.flags |= MIPS_CACHE_PINDEX; + break; + } 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) { @@ -1092,6 +1113,7 @@ 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,17 +1161,29 @@ 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; @@ -1246,10 +1280,12 @@ void __init r4k_cache_init(void) * This code supports virtually indexed processors and will be * unnecessarily inefficient on physically indexed processors. */ - shm_align_mask = max_t( unsigned long, - c->dcache.sets * c->dcache.linesz - 1, - PAGE_SIZE - 1); - + 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; flush_cache_all = r4k_flush_cache_all; __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index f9b129491b1e..2d71efb82ac5 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -18,7 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <linux/config.h> #include <linux/init.h> #include <asm/asm.h> diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 83a56296be86..ddd3a2de1d73 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -5,7 +5,6 @@ * * Copyright (C) 1994 - 2003 by Ralf Baechle */ -#include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c index 1cf3c6006ccd..e19fbb9ee47f 100644 --- a/arch/mips/mm/cerr-sb1.c +++ b/arch/mips/mm/cerr-sb1.c @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <linux/config.h> #include <linux/sched.h> #include <asm/mipsregs.h> #include <asm/sibyte/sb1250.h> diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c index f6b3c722230c..7fa5fd16e46b 100644 --- a/arch/mips/mm/dma-coherent.c +++ b/arch/mips/mm/dma-coherent.c @@ -7,7 +7,6 @@ * Copyright (C) 2000, 2001 Ralf Baechle <ralf@gnu.org> * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/dma-mapping.h> #include <linux/mm.h> diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index cd4ea8474f89..2eeffe5c2a3a 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -7,7 +7,6 @@ * Copyright (C) 2000, 2001 Ralf Baechle <ralf@gnu.org> * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/mm.h> #include <linux/module.h> diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 0c544375b856..99ebf3ccc222 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/module.h> #include <linux/highmem.h> #include <asm/tlbflush.h> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 33f6e1cdfd5b..802bdd32aa2b 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -8,7 +8,6 @@ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ -#include <linux/config.h> #include <linux/init.h> #include <linux/module.h> #include <linux/signal.h> diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c index 148c65b9cd8b..fc3c7878fb45 100644 --- a/arch/mips/mm/pg-sb1.c +++ b/arch/mips/mm/pg-sb1.c @@ -22,7 +22,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/smp.h> diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c index 4a3c4919e314..4bdaa05f485b 100644 --- a/arch/mips/mm/pgtable-32.c +++ b/arch/mips/mm/pgtable-32.c @@ -5,7 +5,6 @@ * * Copyright (C) 2003 by Ralf Baechle */ -#include <linux/config.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/bootmem.h> diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c index 3fe94202da8c..792c6eb44232 100644 --- a/arch/mips/mm/pgtable.c +++ b/arch/mips/mm/pgtable.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/swap.h> diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c new file mode 100644 index 000000000000..42b50964c644 --- /dev/null +++ b/arch/mips/mm/sc-mips.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2006 Chris Dearman (chris@mips.com), + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/mipsregs.h> +#include <asm/bcache.h> +#include <asm/cacheops.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/mmu_context.h> +#include <asm/r4kcache.h> + +/* + * MIPS32/MIPS64 L2 cache handling + */ + +/* + * Writeback and invalidate the secondary cache before DMA. + */ +static void mips_sc_wback_inv(unsigned long addr, unsigned long size) +{ + blast_scache_range(addr, addr + size); +} + +/* + * Invalidate the secondary cache before DMA. + */ +static void mips_sc_inv(unsigned long addr, unsigned long size) +{ + blast_inv_scache_range(addr, addr + size); +} + +static void mips_sc_enable(void) +{ + /* L2 cache is permanently enabled */ +} + +static void mips_sc_disable(void) +{ + /* L2 cache is permanently enabled */ +} + +static struct bcache_ops mips_sc_ops = { + .bc_enable = mips_sc_enable, + .bc_disable = mips_sc_disable, + .bc_wback_inv = mips_sc_wback_inv, + .bc_inv = mips_sc_inv +}; + +static inline int __init mips_sc_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config1, config2; + unsigned int tmp; + + /* Mark as not present until probe completed */ + c->scache.flags |= MIPS_CACHE_NOT_PRESENT; + + /* Ignore anything but MIPSxx processors */ + 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) + return 0; + + /* Does this MIPS32/MIPS64 CPU have a config2 register? */ + config1 = read_c0_config1(); + if (!(config1 & MIPS_CONF_M)) + return 0; + + config2 = read_c0_config2(); + tmp = (config2 >> 4) & 0x0f; + if (0 < tmp && tmp <= 7) + c->scache.linesz = 2 << tmp; + else + return 0; + + tmp = (config2 >> 8) & 0x0f; + if (0 <= tmp && tmp <= 7) + c->scache.sets = 64 << tmp; + else + return 0; + + tmp = (config2 >> 0) & 0x0f; + if (0 <= tmp && tmp <= 7) + c->scache.ways = tmp + 1; + else + return 0; + + c->scache.waysize = c->scache.sets * c->scache.linesz; + c->scache.waybit = __ffs(c->scache.waysize); + + c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; + + return 1; +} + +int __init mips_sc_init(void) +{ + int found = mips_sc_probe (); + if (found) { + mips_sc_enable(); + bcops = &mips_sc_ops; + } + return found; +} + diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 965cb4c4359d..2cde1b772443 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -8,7 +8,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. */ -#include <linux/config.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/mm.h> diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c index 1bfb09198ce3..266a47d65eed 100644 --- a/arch/mips/mm/tlb-r8k.c +++ b/arch/mips/mm/tlb-r8k.c @@ -8,7 +8,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. */ -#include <linux/config.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/mm.h> diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 54507be2ab5b..e1a8139fc8fb 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -21,7 +21,6 @@ #include <stdarg.h> -#include <linux/config.h> #include <linux/mm.h> #include <linux/kernel.h> #include <linux/types.h> |