aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu
diff options
context:
space:
mode:
authorRichard Curnow <richard.curnow@st.com>2006-09-27 01:09:26 -0400
committerPaul Mundt <lethal@linux-sh.org>2006-09-27 01:09:26 -0400
commitb638d0b921dc95229af0dfd09cd24850336a2f75 (patch)
tree0ef34527a47b22421fb92ba2141052fecfe36482 /arch/sh/kernel/cpu
parentfdfc74f9fcebdda14609159d5010b758a9409acf (diff)
sh: Optimized cache handling for SH-4/SH-4A caches.
This reworks some of the SH-4 cache handling code to more easily accomodate newer-style caches (particularly for the > direct-mapped case), as well as optimizing some of the old code. Signed-off-by: Richard Curnow <richard.curnow@st.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu')
-rw-r--r--arch/sh/kernel/cpu/init.c16
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c11
2 files changed, 26 insertions, 1 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 868e68b28880..731dd61419dd 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -4,6 +4,7 @@
4 * CPU init code 4 * CPU init code
5 * 5 *
6 * Copyright (C) 2002, 2003 Paul Mundt 6 * Copyright (C) 2002, 2003 Paul Mundt
7 * Copyright (C) 2003 Richard Curnow
7 * 8 *
8 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 10 * License. See the file "COPYING" in the main directory of this archive
@@ -51,7 +52,15 @@ static void __init cache_init(void)
51 ccr = ctrl_inl(CCR); 52 ccr = ctrl_inl(CCR);
52 53
53 /* 54 /*
54 * If the cache is already enabled .. flush it. 55 * At this point we don't know whether the cache is enabled or not - a
56 * bootloader may have enabled it. There are at least 2 things that
57 * could be dirty in the cache at this point:
58 * 1. kernel command line set up by boot loader
59 * 2. spilled registers from the prolog of this function
60 * => before re-initialising the cache, we must do a purge of the whole
61 * cache out to memory for safety. As long as nothing is spilled
62 * during the loop to lines that have already been done, this is safe.
63 * - RPC
55 */ 64 */
56 if (ccr & CCR_CACHE_ENABLE) { 65 if (ccr & CCR_CACHE_ENABLE) {
57 unsigned long ways, waysize, addrstart; 66 unsigned long ways, waysize, addrstart;
@@ -98,6 +107,8 @@ static void __init cache_init(void)
98 /* Force EMODE if possible */ 107 /* Force EMODE if possible */
99 if (cpu_data->dcache.ways > 1) 108 if (cpu_data->dcache.ways > 1)
100 flags |= CCR_CACHE_EMODE; 109 flags |= CCR_CACHE_EMODE;
110 else
111 flags &= ~CCR_CACHE_EMODE;
101#endif 112#endif
102 113
103#ifdef CONFIG_SH_WRITETHROUGH 114#ifdef CONFIG_SH_WRITETHROUGH
@@ -112,6 +123,9 @@ static void __init cache_init(void)
112 /* Turn on OCRAM -- halve the OC */ 123 /* Turn on OCRAM -- halve the OC */
113 flags |= CCR_CACHE_ORA; 124 flags |= CCR_CACHE_ORA;
114 cpu_data->dcache.sets >>= 1; 125 cpu_data->dcache.sets >>= 1;
126
127 cpu_data->dcache.way_size = cpu_data->dcache.sets *
128 cpu_data->dcache.linesz;
115#endif 129#endif
116 130
117 ctrl_outl(flags, CCR); 131 ctrl_outl(flags, CCR);
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 42427b79697b..1208da8fe5db 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -113,6 +113,11 @@ int __init detect_cpu_and_cache_system(void)
113 break; 113 break;
114 } 114 }
115 115
116#ifdef CONFIG_SH_DIRECT_MAPPED
117 cpu_data->icache.ways = 1;
118 cpu_data->dcache.ways = 1;
119#endif
120
116 /* 121 /*
117 * On anything that's not a direct-mapped cache, look to the CVR 122 * On anything that's not a direct-mapped cache, look to the CVR
118 * for I/D-cache specifics. 123 * for I/D-cache specifics.
@@ -125,6 +130,9 @@ int __init detect_cpu_and_cache_system(void)
125 (cpu_data->icache.way_incr - (1 << 5)); 130 (cpu_data->icache.way_incr - (1 << 5));
126 } 131 }
127 132
133 cpu_data->icache.way_size = cpu_data->icache.sets *
134 cpu_data->icache.linesz;
135
128 if (cpu_data->dcache.ways > 1) { 136 if (cpu_data->dcache.ways > 1) {
129 size = sizes[(cvr >> 16) & 0xf]; 137 size = sizes[(cvr >> 16) & 0xf];
130 cpu_data->dcache.way_incr = (size >> 1); 138 cpu_data->dcache.way_incr = (size >> 1);
@@ -133,6 +141,9 @@ int __init detect_cpu_and_cache_system(void)
133 (cpu_data->dcache.way_incr - (1 << 5)); 141 (cpu_data->dcache.way_incr - (1 << 5));
134 } 142 }
135 143
144 cpu_data->dcache.way_size = cpu_data->dcache.sets *
145 cpu_data->dcache.linesz;
146
136 return 0; 147 return 0;
137} 148}
138 149