Loading arch/mips/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -325,6 +325,7 @@ config MIPS_MALTA select I8259 select MIPS_BOARDS_GEN select MIPS_BONITO64 select MIPS_CPU_SCACHE select MIPS_GT64120 select MIPS_MSC select SWAP_IO_SPACE Loading Loading @@ -1478,6 +1479,13 @@ config IP22_CPU_SCACHE bool select BOARD_SCACHE # # Support for a MIPS32 / MIPS64 style S-caches # config MIPS_CPU_SCACHE bool select BOARD_SCACHE config R5000_CPU_SCACHE bool select BOARD_SCACHE Loading arch/mips/kernel/cpu-probe.c +0 −2 Original line number Diff line number Diff line Loading @@ -597,8 +597,6 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) break; case PRID_IMP_25KF: c->cputype = CPU_25KF; /* Probe for L2 cache */ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; break; case PRID_IMP_34K: c->cputype = CPU_34K; Loading arch/mips/mm/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading arch/mips/mm/c-r4k.c +18 −5 Original line number Diff line number Diff line Loading @@ -1092,6 +1092,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) { Loading Loading @@ -1139,17 +1140,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; Loading arch/mips/mm/sc-mips.c 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * 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) { unsigned long sc_lsize = cpu_scache_line_size(); unsigned long end, a; pr_debug("mips_sc_wback_inv[%08lx,%08lx]", addr, size); /* Catch bad driver code */ BUG_ON(size == 0); a = addr & ~(sc_lsize - 1); end = (addr + size - 1) & ~(sc_lsize - 1); while (1) { flush_scache_line(a); /* Hit_Writeback_Inv_SD */ if (a == end) break; a += sc_lsize; } } /* * Invalidate the secondary cache before DMA. */ static void mips_sc_inv(unsigned long addr, unsigned long size) { unsigned long sc_lsize = cpu_scache_line_size(); unsigned long end, a; pr_debug("mips_sc_inv[%08lx,%08lx]", addr, size); /* Catch bad driver code */ BUG_ON(size == 0); a = addr & ~(sc_lsize - 1); end = (addr + size - 1) & ~(sc_lsize - 1); while (1) { invalidate_scache_line(a); /* Hit_Invalidate_SD */ if (a == end) break; a += sc_lsize; } } 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.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; } Loading
arch/mips/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -325,6 +325,7 @@ config MIPS_MALTA select I8259 select MIPS_BOARDS_GEN select MIPS_BONITO64 select MIPS_CPU_SCACHE select MIPS_GT64120 select MIPS_MSC select SWAP_IO_SPACE Loading Loading @@ -1478,6 +1479,13 @@ config IP22_CPU_SCACHE bool select BOARD_SCACHE # # Support for a MIPS32 / MIPS64 style S-caches # config MIPS_CPU_SCACHE bool select BOARD_SCACHE config R5000_CPU_SCACHE bool select BOARD_SCACHE Loading
arch/mips/kernel/cpu-probe.c +0 −2 Original line number Diff line number Diff line Loading @@ -597,8 +597,6 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) break; case PRID_IMP_25KF: c->cputype = CPU_25KF; /* Probe for L2 cache */ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; break; case PRID_IMP_34K: c->cputype = CPU_34K; Loading
arch/mips/mm/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
arch/mips/mm/c-r4k.c +18 −5 Original line number Diff line number Diff line Loading @@ -1092,6 +1092,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) { Loading Loading @@ -1139,17 +1140,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; Loading
arch/mips/mm/sc-mips.c 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * 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) { unsigned long sc_lsize = cpu_scache_line_size(); unsigned long end, a; pr_debug("mips_sc_wback_inv[%08lx,%08lx]", addr, size); /* Catch bad driver code */ BUG_ON(size == 0); a = addr & ~(sc_lsize - 1); end = (addr + size - 1) & ~(sc_lsize - 1); while (1) { flush_scache_line(a); /* Hit_Writeback_Inv_SD */ if (a == end) break; a += sc_lsize; } } /* * Invalidate the secondary cache before DMA. */ static void mips_sc_inv(unsigned long addr, unsigned long size) { unsigned long sc_lsize = cpu_scache_line_size(); unsigned long end, a; pr_debug("mips_sc_inv[%08lx,%08lx]", addr, size); /* Catch bad driver code */ BUG_ON(size == 0); a = addr & ~(sc_lsize - 1); end = (addr + size - 1) & ~(sc_lsize - 1); while (1) { invalidate_scache_line(a); /* Hit_Invalidate_SD */ if (a == end) break; a += sc_lsize; } } 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.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; }