diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-08-19 09:55:09 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-10-11 11:18:42 -0400 |
commit | d10e025f0e4ba4b96d7b5786d232ac5b0b232b11 (patch) | |
tree | a417a55071b4b7edc22b7c5bb1a2352e7b5986d9 /arch/mips/txx9/generic | |
parent | 860e546c19d88c21819c7f0861c505debd2d6eed (diff) |
MIPS: TXx9: Cache fixup
TX39/TX49 can enable/disable I/D cache at runtime. Add kernel options
to control them. This is useful to debug some cache-related issues,
such as aliasing or I/D coherency. Also enable CWF bit for TX49 SoCs.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/txx9/generic')
-rw-r--r-- | arch/mips/txx9/generic/setup.c | 113 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup_tx3927.c | 18 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup_tx4927.c | 1 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup_tx4938.c | 1 |
4 files changed, 123 insertions, 10 deletions
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index dc5dbcc53a91..fa88aefea9ef 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/bootinfo.h> | 25 | #include <asm/bootinfo.h> |
26 | #include <asm/time.h> | 26 | #include <asm/time.h> |
27 | #include <asm/reboot.h> | 27 | #include <asm/reboot.h> |
28 | #include <asm/r4kcache.h> | ||
28 | #include <asm/txx9/generic.h> | 29 | #include <asm/txx9/generic.h> |
29 | #include <asm/txx9/pci.h> | 30 | #include <asm/txx9/pci.h> |
30 | #ifdef CONFIG_CPU_TX49XX | 31 | #ifdef CONFIG_CPU_TX49XX |
@@ -186,6 +187,110 @@ static void __init prom_init_cmdline(void) | |||
186 | } | 187 | } |
187 | } | 188 | } |
188 | 189 | ||
190 | static int txx9_ic_disable __initdata; | ||
191 | static int txx9_dc_disable __initdata; | ||
192 | |||
193 | #if defined(CONFIG_CPU_TX49XX) | ||
194 | /* flush all cache on very early stage (before 4k_cache_init) */ | ||
195 | static void __init early_flush_dcache(void) | ||
196 | { | ||
197 | unsigned int conf = read_c0_config(); | ||
198 | unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6)); | ||
199 | unsigned int linesz = 32; | ||
200 | unsigned long addr, end; | ||
201 | |||
202 | end = INDEX_BASE + dc_size / 4; | ||
203 | /* 4way, waybit=0 */ | ||
204 | for (addr = INDEX_BASE; addr < end; addr += linesz) { | ||
205 | cache_op(Index_Writeback_Inv_D, addr | 0); | ||
206 | cache_op(Index_Writeback_Inv_D, addr | 1); | ||
207 | cache_op(Index_Writeback_Inv_D, addr | 2); | ||
208 | cache_op(Index_Writeback_Inv_D, addr | 3); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | static void __init txx9_cache_fixup(void) | ||
213 | { | ||
214 | unsigned int conf; | ||
215 | |||
216 | conf = read_c0_config(); | ||
217 | /* flush and disable */ | ||
218 | if (txx9_ic_disable) { | ||
219 | conf |= TX49_CONF_IC; | ||
220 | write_c0_config(conf); | ||
221 | } | ||
222 | if (txx9_dc_disable) { | ||
223 | early_flush_dcache(); | ||
224 | conf |= TX49_CONF_DC; | ||
225 | write_c0_config(conf); | ||
226 | } | ||
227 | |||
228 | /* enable cache */ | ||
229 | conf = read_c0_config(); | ||
230 | if (!txx9_ic_disable) | ||
231 | conf &= ~TX49_CONF_IC; | ||
232 | if (!txx9_dc_disable) | ||
233 | conf &= ~TX49_CONF_DC; | ||
234 | write_c0_config(conf); | ||
235 | |||
236 | if (conf & TX49_CONF_IC) | ||
237 | pr_info("TX49XX I-Cache disabled.\n"); | ||
238 | if (conf & TX49_CONF_DC) | ||
239 | pr_info("TX49XX D-Cache disabled.\n"); | ||
240 | } | ||
241 | #elif defined(CONFIG_CPU_TX39XX) | ||
242 | /* flush all cache on very early stage (before tx39_cache_init) */ | ||
243 | static void __init early_flush_dcache(void) | ||
244 | { | ||
245 | unsigned int conf = read_c0_config(); | ||
246 | unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >> | ||
247 | TX39_CONF_DCS_SHIFT)); | ||
248 | unsigned int linesz = 16; | ||
249 | unsigned long addr, end; | ||
250 | |||
251 | end = INDEX_BASE + dc_size / 2; | ||
252 | /* 2way, waybit=0 */ | ||
253 | for (addr = INDEX_BASE; addr < end; addr += linesz) { | ||
254 | cache_op(Index_Writeback_Inv_D, addr | 0); | ||
255 | cache_op(Index_Writeback_Inv_D, addr | 1); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | static void __init txx9_cache_fixup(void) | ||
260 | { | ||
261 | unsigned int conf; | ||
262 | |||
263 | conf = read_c0_config(); | ||
264 | /* flush and disable */ | ||
265 | if (txx9_ic_disable) { | ||
266 | conf &= ~TX39_CONF_ICE; | ||
267 | write_c0_config(conf); | ||
268 | } | ||
269 | if (txx9_dc_disable) { | ||
270 | early_flush_dcache(); | ||
271 | conf &= ~TX39_CONF_DCE; | ||
272 | write_c0_config(conf); | ||
273 | } | ||
274 | |||
275 | /* enable cache */ | ||
276 | conf = read_c0_config(); | ||
277 | if (!txx9_ic_disable) | ||
278 | conf |= TX39_CONF_ICE; | ||
279 | if (!txx9_dc_disable) | ||
280 | conf |= TX39_CONF_DCE; | ||
281 | write_c0_config(conf); | ||
282 | |||
283 | if (!(conf & TX39_CONF_ICE)) | ||
284 | pr_info("TX39XX I-Cache disabled.\n"); | ||
285 | if (!(conf & TX39_CONF_DCE)) | ||
286 | pr_info("TX39XX D-Cache disabled.\n"); | ||
287 | } | ||
288 | #else | ||
289 | static inline void txx9_cache_fixup(void) | ||
290 | { | ||
291 | } | ||
292 | #endif | ||
293 | |||
189 | static void __init preprocess_cmdline(void) | 294 | static void __init preprocess_cmdline(void) |
190 | { | 295 | { |
191 | char cmdline[CL_SIZE]; | 296 | char cmdline[CL_SIZE]; |
@@ -204,11 +309,19 @@ static void __init preprocess_cmdline(void) | |||
204 | if (strict_strtoul(str + 10, 10, &val) == 0) | 309 | if (strict_strtoul(str + 10, 10, &val) == 0) |
205 | txx9_master_clock = val; | 310 | txx9_master_clock = val; |
206 | continue; | 311 | continue; |
312 | } else if (strcmp(str, "icdisable") == 0) { | ||
313 | txx9_ic_disable = 1; | ||
314 | continue; | ||
315 | } else if (strcmp(str, "dcdisable") == 0) { | ||
316 | txx9_dc_disable = 1; | ||
317 | continue; | ||
207 | } | 318 | } |
208 | if (arcs_cmdline[0]) | 319 | if (arcs_cmdline[0]) |
209 | strcat(arcs_cmdline, " "); | 320 | strcat(arcs_cmdline, " "); |
210 | strcat(arcs_cmdline, str); | 321 | strcat(arcs_cmdline, str); |
211 | } | 322 | } |
323 | |||
324 | txx9_cache_fixup(); | ||
212 | } | 325 | } |
213 | 326 | ||
214 | static void __init select_board(void) | 327 | static void __init select_board(void) |
diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c index 7bd963d37fc3..4bc2f859379d 100644 --- a/arch/mips/txx9/generic/setup_tx3927.c +++ b/arch/mips/txx9/generic/setup_tx3927.c | |||
@@ -99,16 +99,14 @@ void __init tx3927_setup(void) | |||
99 | txx9_gpio_init(TX3927_PIO_REG, 0, 16); | 99 | txx9_gpio_init(TX3927_PIO_REG, 0, 16); |
100 | 100 | ||
101 | conf = read_c0_conf(); | 101 | conf = read_c0_conf(); |
102 | if (!(conf & TX39_CONF_ICE)) | 102 | if (conf & TX39_CONF_DCE) { |
103 | printk(KERN_INFO "TX3927 I-Cache disabled.\n"); | 103 | if (!(conf & TX39_CONF_WBON)) |
104 | if (!(conf & TX39_CONF_DCE)) | 104 | pr_info("TX3927 D-Cache WriteThrough.\n"); |
105 | printk(KERN_INFO "TX3927 D-Cache disabled.\n"); | 105 | else if (!(conf & TX39_CONF_CWFON)) |
106 | else if (!(conf & TX39_CONF_WBON)) | 106 | pr_info("TX3927 D-Cache WriteBack.\n"); |
107 | printk(KERN_INFO "TX3927 D-Cache WriteThrough.\n"); | 107 | else |
108 | else if (!(conf & TX39_CONF_CWFON)) | 108 | pr_info("TX3927 D-Cache WriteBack (CWF) .\n"); |
109 | printk(KERN_INFO "TX3927 D-Cache WriteBack.\n"); | 109 | } |
110 | else | ||
111 | printk(KERN_INFO "TX3927 D-Cache WriteBack (CWF) .\n"); | ||
112 | } | 110 | } |
113 | 111 | ||
114 | void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr) | 112 | void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr) |
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index f80d4b7a694d..e679c79a4b0f 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c | |||
@@ -44,6 +44,7 @@ void __init tx4927_setup(void) | |||
44 | 44 | ||
45 | txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE, | 45 | txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE, |
46 | TX4927_REG_SIZE); | 46 | TX4927_REG_SIZE); |
47 | set_c0_config(TX49_CONF_CWFON); | ||
47 | 48 | ||
48 | /* SDRAMC,EBUSC are configured by PROM */ | 49 | /* SDRAMC,EBUSC are configured by PROM */ |
49 | for (i = 0; i < 8; i++) { | 50 | for (i = 0; i < 8; i++) { |
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index f3040b9ba059..95c058f0a96c 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c | |||
@@ -47,6 +47,7 @@ void __init tx4938_setup(void) | |||
47 | 47 | ||
48 | txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE, | 48 | txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE, |
49 | TX4938_REG_SIZE); | 49 | TX4938_REG_SIZE); |
50 | set_c0_config(TX49_CONF_CWFON); | ||
50 | 51 | ||
51 | /* SDRAMC,EBUSC are configured by PROM */ | 52 | /* SDRAMC,EBUSC are configured by PROM */ |
52 | for (i = 0; i < 8; i++) { | 53 | for (i = 0; i < 8; i++) { |