diff options
author | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 05:27:43 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 05:27:43 -0400 |
commit | 72c35543f8cf1316773ffbd9619575bb84ac44fb (patch) | |
tree | 5dc8ba51079cbc65be0ee0e881da03e6ac0b0b5b | |
parent | 9d549a7d8ef71f684a35cf1e438543957cf81d12 (diff) |
sh: Support for L2 cache on newer SH-4A CPUs.
This implements preliminary support for the L2 caches found
on newer SH-4A CPUs.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/kernel/cpu/sh4/probe.c | 47 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 6 | ||||
-rw-r--r-- | include/asm-sh/cpu-features.h | 1 | ||||
-rw-r--r-- | include/asm-sh/processor.h | 9 |
4 files changed, 57 insertions, 6 deletions
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 0e65aa6ddcaa..bee00cac0b16 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c | |||
@@ -29,7 +29,7 @@ int __init detect_cpu_and_cache_system(void) | |||
29 | [9] = (1 << 16) | 29 | [9] = (1 << 16) |
30 | }; | 30 | }; |
31 | 31 | ||
32 | pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff; | 32 | pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff; |
33 | prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; | 33 | prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; |
34 | cvr = (ctrl_inl(CCN_CVR)); | 34 | cvr = (ctrl_inl(CCN_CVR)); |
35 | 35 | ||
@@ -54,6 +54,26 @@ int __init detect_cpu_and_cache_system(void) | |||
54 | cpu_data->dcache.linesz = L1_CACHE_BYTES; | 54 | cpu_data->dcache.linesz = L1_CACHE_BYTES; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Setup some generic flags we can probe | ||
58 | * (L2 and DSP detection only work on SH-4A) | ||
59 | */ | ||
60 | if (((pvr >> 16) & 0xff) == 0x10) { | ||
61 | if ((cvr & 0x02000000) == 0) | ||
62 | cpu_data->flags |= CPU_HAS_L2_CACHE; | ||
63 | if ((cvr & 0x10000000) == 0) | ||
64 | cpu_data->flags |= CPU_HAS_DSP; | ||
65 | |||
66 | cpu_data->flags |= CPU_HAS_LLSC; | ||
67 | } | ||
68 | |||
69 | /* FPU detection works for everyone */ | ||
70 | if ((cvr & 0x20000000) == 1) | ||
71 | cpu_data->flags |= CPU_HAS_FPU; | ||
72 | |||
73 | /* Mask off the upper chip ID */ | ||
74 | pvr &= 0xffff; | ||
75 | |||
76 | /* | ||
57 | * Probe the underlying processor version/revision and | 77 | * Probe the underlying processor version/revision and |
58 | * adjust cpu_data setup accordingly. | 78 | * adjust cpu_data setup accordingly. |
59 | */ | 79 | */ |
@@ -181,5 +201,30 @@ int __init detect_cpu_and_cache_system(void) | |||
181 | cpu_data->dcache.way_size = cpu_data->dcache.sets * | 201 | cpu_data->dcache.way_size = cpu_data->dcache.sets * |
182 | cpu_data->dcache.linesz; | 202 | cpu_data->dcache.linesz; |
183 | 203 | ||
204 | /* | ||
205 | * Setup the L2 cache desc | ||
206 | * | ||
207 | * SH-4A's have an optional PIPT L2. | ||
208 | */ | ||
209 | if (cpu_data->flags & CPU_HAS_L2_CACHE) { | ||
210 | /* | ||
211 | * Size calculation is much more sensible | ||
212 | * than it is for the L1. | ||
213 | * | ||
214 | * Sizes are 128KB, 258KB, 512KB, and 1MB. | ||
215 | */ | ||
216 | size = (cvr & 0xf) << 17; | ||
217 | |||
218 | BUG_ON(!size); | ||
219 | |||
220 | cpu_data->scache.way_incr = (1 << 16); | ||
221 | cpu_data->scache.entry_shift = 5; | ||
222 | cpu_data->scache.entry_mask = 0xffe0; | ||
223 | cpu_data->scache.ways = 4; | ||
224 | cpu_data->scache.linesz = L1_CACHE_BYTES; | ||
225 | cpu_data->scache.sets = size / | ||
226 | (cpu_data->scache.linesz * cpu_data->scache.ways); | ||
227 | } | ||
228 | |||
184 | return 0; | 229 | return 0; |
185 | } | 230 | } |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 6810de3f8ed2..5f587332234a 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -416,7 +416,7 @@ const char *get_cpu_subtype(void) | |||
416 | /* Symbolic CPU flags, keep in sync with asm/cpu-features.h */ | 416 | /* Symbolic CPU flags, keep in sync with asm/cpu-features.h */ |
417 | static const char *cpu_flags[] = { | 417 | static const char *cpu_flags[] = { |
418 | "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", | 418 | "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", |
419 | "ptea", "llsc", NULL | 419 | "ptea", "llsc", "l2", NULL |
420 | }; | 420 | }; |
421 | 421 | ||
422 | static void show_cpuflags(struct seq_file *m) | 422 | static void show_cpuflags(struct seq_file *m) |
@@ -480,6 +480,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
480 | show_cacheinfo(m, "dcache", boot_cpu_data.dcache); | 480 | show_cacheinfo(m, "dcache", boot_cpu_data.dcache); |
481 | } | 481 | } |
482 | 482 | ||
483 | /* Optional secondary cache */ | ||
484 | if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) | ||
485 | show_cacheinfo(m, "scache", boot_cpu_data.scache); | ||
486 | |||
483 | seq_printf(m, "bogomips\t: %lu.%02lu\n", | 487 | seq_printf(m, "bogomips\t: %lu.%02lu\n", |
484 | boot_cpu_data.loops_per_jiffy/(500000/HZ), | 488 | boot_cpu_data.loops_per_jiffy/(500000/HZ), |
485 | (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100); | 489 | (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100); |
diff --git a/include/asm-sh/cpu-features.h b/include/asm-sh/cpu-features.h index e1260aae3ee3..4bccd7c032f9 100644 --- a/include/asm-sh/cpu-features.h +++ b/include/asm-sh/cpu-features.h | |||
@@ -19,5 +19,6 @@ | |||
19 | #define CPU_HAS_PERF_COUNTER 0x0010 /* Hardware performance counters */ | 19 | #define CPU_HAS_PERF_COUNTER 0x0010 /* Hardware performance counters */ |
20 | #define CPU_HAS_PTEA 0x0020 /* PTEA register */ | 20 | #define CPU_HAS_PTEA 0x0020 /* PTEA register */ |
21 | #define CPU_HAS_LLSC 0x0040 /* movli.l/movco.l */ | 21 | #define CPU_HAS_LLSC 0x0040 /* movli.l/movco.l */ |
22 | #define CPU_HAS_L2_CACHE 0x0080 /* Secondary cache / URAM */ | ||
22 | 23 | ||
23 | #endif /* __ASM_SH_CPU_FEATURES_H */ | 24 | #endif /* __ASM_SH_CPU_FEATURES_H */ |
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index bdd472705546..b7cba4e91a72 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h | |||
@@ -54,14 +54,15 @@ enum cpu_type { | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct sh_cpuinfo { | 56 | struct sh_cpuinfo { |
57 | enum cpu_type type; | 57 | unsigned int type; |
58 | unsigned long loops_per_jiffy; | 58 | unsigned long loops_per_jiffy; |
59 | 59 | ||
60 | struct cache_info icache; | 60 | struct cache_info icache; /* Primary I-cache */ |
61 | struct cache_info dcache; | 61 | struct cache_info dcache; /* Primary D-cache */ |
62 | struct cache_info scache; /* Secondary cache */ | ||
62 | 63 | ||
63 | unsigned long flags; | 64 | unsigned long flags; |
64 | }; | 65 | } __attribute__ ((aligned(SMP_CACHE_BYTES))); |
65 | 66 | ||
66 | extern struct sh_cpuinfo boot_cpu_data; | 67 | extern struct sh_cpuinfo boot_cpu_data; |
67 | 68 | ||