diff options
author | Antony Pavlov <antonynpavlov@gmail.com> | 2012-05-22 16:17:00 +0400 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-05-23 18:47:53 +0200 |
commit | e41b0717dc6594e8cf063b7023fde814f2ac97b4 (patch) | |
tree | b226ae682ed82ed9ca14d48b51a5d91c74730e0a /arch/mips/lib/c-r4k.c | |
parent | 6a1e9a7c9b384d80c6977f2a1d5682a4e9e39de1 (diff) | |
download | barebox-e41b0717dc6594e8cf063b7023fde814f2ac97b4.tar.gz barebox-e41b0717dc6594e8cf063b7023fde814f2ac97b4.tar.xz |
MIPS: import CPU and cache detection code from Linux 3.4
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/mips/lib/c-r4k.c')
-rw-r--r-- | arch/mips/lib/c-r4k.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/arch/mips/lib/c-r4k.c b/arch/mips/lib/c-r4k.c new file mode 100644 index 0000000000..01b8665193 --- /dev/null +++ b/arch/mips/lib/c-r4k.c @@ -0,0 +1,97 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include <common.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/cpu.h> +#include <asm/cpu-info.h> +#include <asm/bitops.h> + +void r4k_cache_init(void); + +static void probe_pcache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int icache_size, dcache_size; + unsigned int config = read_c0_config(); + unsigned long config1; + unsigned int lsize; + + switch (c->cputype) { + + default: + /* + * So we seem to be a MIPS32 or MIPS64 CPU + * So let's probe the I-cache ... + */ + config1 = read_c0_config1(); + + if ((lsize = ((config1 >> 19) & 7))) + c->icache.linesz = 2 << lsize; + else + c->icache.linesz = lsize; + c->icache.sets = 64 << ((config1 >> 22) & 7); + c->icache.ways = 1 + ((config1 >> 16) & 7); + + icache_size = c->icache.sets * + c->icache.ways * + c->icache.linesz; + c->icache.waybit = __ffs(icache_size/c->icache.ways); + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + /* + * Now probe the MIPS32 / MIPS64 data cache. + */ + c->dcache.flags = 0; + + if ((lsize = ((config1 >> 10) & 7))) + c->dcache.linesz = 2 << lsize; + else + c->dcache.linesz= lsize; + c->dcache.sets = 64 << ((config1 >> 13) & 7); + c->dcache.ways = 1 + ((config1 >> 7) & 7); + + dcache_size = c->dcache.sets * + c->dcache.ways * + c->dcache.linesz; + c->dcache.waybit = __ffs(dcache_size/c->dcache.ways); + + c->options |= MIPS_CPU_PREFETCH; + break; + } + + /* compute a couple of other cache variables */ + 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; + + /* + * R10000 and R12000 P-caches are odd in a positive way. They're 32kB + * 2-way virtually indexed so normally would suffer from aliases. So + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ + switch (c->cputype) { + default: + if (c->dcache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + } +} + +void r4k_cache_init(void) +{ + probe_pcache(); +} |