diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 13:44:45 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 13:44:45 -0700 |
commit | 8d231c11fd0b694c447e59e687754b6999eea0a2 (patch) | |
tree | b0b3c17efff7018bbf948e489f642c8079f33cc0 /arch/mips/mm/sc-mips.c | |
parent | 1f1332f727c3229eb2166a83fec5d3de6a73dce2 (diff) | |
parent | 8db089c6b5594c961fb6bc6d613b9926e0d3d98f (diff) |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (33 commits)
[MIPS] Add missing backslashes to macro definitions.
[MIPS] Death list of board support to be removed after 2.6.18.
[MIPS] Remove BSD and Sys V compat data types.
[MIPS] ioc3.h: Uses u8, so include <linux/types.h>.
[MIPS] 74K: Assume it will also have an AR bit in config7
[MIPS] Treat CPUs with AR bit as physically indexed.
[MIPS] Oprofile: Support VSMP on 34K.
[MIPS] MIPS32/MIPS64 S-cache fix and cleanup
[MIPS] excite: PCI makefile needs to use += if it wants a chance to work.
[MIPS] excite: plat_setup -> plat_mem_setup.
[MIPS] au1xxx: export dbdma functions
[MIPS] au1xxx: dbdma, no sleeping under spin_lock
[MIPS] au1xxx: fix PSC_SMBTXRX_RSR.
[MIPS] Early printk for IP27.
[MIPS] Fix handling of 0 length I & D caches.
[MIPS] Typo fixes.
[MIPS] MIPS32/MIPS64 secondary cache management
[MIPS] Fix FIXADDR_TOP for TX39/TX49.
[MIPS] Remove first timer interrupt setup in wrppmc_timer_setup()
[MIPS] Fix configuration of R2 CPU features and multithreading.
...
Diffstat (limited to 'arch/mips/mm/sc-mips.c')
-rw-r--r-- | arch/mips/mm/sc-mips.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c new file mode 100644 index 00000000000..42b50964c64 --- /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; +} + |