blob: cbd04bd2f3bab5891134385b8751220d2e45649e [file] [log] [blame]
wdenkc0218802003-03-27 12:09:35 +00001/*
Shinya Kuribayashi373b16f2008-03-25 21:30:07 +09002 * Cache-handling routined for MIPS CPUs
wdenkc0218802003-03-27 12:09:35 +00003 *
4 * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
5 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenkc0218802003-03-27 12:09:35 +00007 */
8
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +02009#include <asm-offsets.h>
wdenkc0218802003-03-27 12:09:35 +000010#include <config.h>
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +090011#include <asm/asm.h>
wdenkc0218802003-03-27 12:09:35 +000012#include <asm/regdef.h>
13#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/cacheops.h>
16
Daniel Schwierzeck979cfea2012-04-02 02:57:55 +000017#ifndef CONFIG_SYS_MIPS_CACHE_MODE
18#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
19#endif
20
Shinya Kuribayashi7daf2eb2008-06-05 22:29:00 +090021#define INDEX_BASE CKSEG0
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090022
Shinya Kuribayashi18988402008-03-25 21:30:06 +090023 .macro f_fill64 dst, offset, val
24 LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
25 LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
26 LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
27 LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
28 LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
29 LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
30 LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
31 LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
32#if LONGSIZE == 4
33 LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
34 LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
35 LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
36 LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
37 LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
38 LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
39 LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
40 LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
41#endif
42 .endm
43
Paul Burtonac22fec2015-01-29 01:28:00 +000044 .macro cache_loop curr, end, line_sz, op
4510: cache \op, 0(\curr)
46 PTR_ADDU \curr, \curr, \line_sz
47 bne \curr, \end, 10b
48 .endm
49
Paul Burton536cb7c2015-01-29 01:27:59 +000050 .macro l1_info sz, line_sz, off
51 .set push
52 .set noat
53
54 mfc0 $1, CP0_CONFIG, 1
55
56 /* detect line size */
57 srl \line_sz, $1, \off + MIPS_CONF1_DL_SHIFT - MIPS_CONF1_DA_SHIFT
58 andi \line_sz, \line_sz, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT)
59 move \sz, zero
60 beqz \line_sz, 10f
61 li \sz, 2
62 sllv \line_sz, \sz, \line_sz
63
64 /* detect associativity */
65 srl \sz, $1, \off + MIPS_CONF1_DA_SHIFT - MIPS_CONF1_DA_SHIFT
66 andi \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT)
67 addi \sz, \sz, 1
68
69 /* sz *= line_sz */
70 mul \sz, \sz, \line_sz
71
72 /* detect log32(sets) */
73 srl $1, $1, \off + MIPS_CONF1_DS_SHIFT - MIPS_CONF1_DA_SHIFT
74 andi $1, $1, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT)
75 addiu $1, $1, 1
76 andi $1, $1, 0x7
77
78 /* sz <<= log32(sets) */
79 sllv \sz, \sz, $1
80
81 /* sz *= 32 */
82 li $1, 32
83 mul \sz, \sz, $1
8410:
85 .set pop
86 .endm
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +090087/*
88 * mips_cache_reset - low level initialisation of the primary caches
89 *
90 * This routine initialises the primary caches to ensure that they have good
91 * parity. It must be called by the ROM before any cached locations are used
92 * to prevent the possibility of data with bad parity being written to memory.
93 *
94 * To initialise the instruction cache it is essential that a source of data
95 * with good parity is available. This routine will initialise an area of
96 * memory starting at location zero to be used as a source of parity.
97 *
98 * RETURNS: N/A
99 *
100 */
Paul Burtonca4e8332015-01-29 01:28:01 +0000101LEAF(mips_cache_reset)
Paul Burtonfa476f72013-11-08 11:18:42 +0000102#ifdef CONFIG_SYS_ICACHE_SIZE
103 li t2, CONFIG_SYS_ICACHE_SIZE
Paul Burton536cb7c2015-01-29 01:27:59 +0000104 li t8, CONFIG_SYS_CACHELINE_SIZE
Paul Burtonfa476f72013-11-08 11:18:42 +0000105#else
Paul Burton536cb7c2015-01-29 01:27:59 +0000106 l1_info t2, t8, MIPS_CONF1_IA_SHIFT
Paul Burtonfa476f72013-11-08 11:18:42 +0000107#endif
108
109#ifdef CONFIG_SYS_DCACHE_SIZE
110 li t3, CONFIG_SYS_DCACHE_SIZE
Paul Burton536cb7c2015-01-29 01:27:59 +0000111 li t9, CONFIG_SYS_CACHELINE_SIZE
Paul Burtonfa476f72013-11-08 11:18:42 +0000112#else
Paul Burton536cb7c2015-01-29 01:27:59 +0000113 l1_info t3, t9, MIPS_CONF1_DA_SHIFT
Paul Burtonfa476f72013-11-08 11:18:42 +0000114#endif
115
116 /* Determine the largest L1 cache size */
117#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE)
118#if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE
119 li v0, CONFIG_SYS_ICACHE_SIZE
120#else
121 li v0, CONFIG_SYS_DCACHE_SIZE
122#endif
123#else
124 move v0, t2
125 sltu t1, t2, t3
126 movn v0, t3, t1
127#endif
Shinya Kuribayashi18988402008-03-25 21:30:06 +0900128 /*
129 * Now clear that much memory starting from zero.
wdenkc0218802003-03-27 12:09:35 +0000130 */
Shinya Kuribayashi7daf2eb2008-06-05 22:29:00 +0900131 PTR_LI a0, CKSEG1
Shinya Kuribayashi18988402008-03-25 21:30:06 +0900132 PTR_ADDU a1, a0, v0
1332: PTR_ADDIU a0, 64
134 f_fill64 a0, -64, zero
135 bne a0, a1, 2b
wdenk8bde7f72003-06-27 21:31:46 +0000136
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900137 /*
138 * The caches are probably in an indeterminate state,
139 * so we force good parity into them by doing an
140 * invalidate, load/fill, invalidate for each line.
141 */
wdenkc0218802003-03-27 12:09:35 +0000142
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900143 /*
144 * Assume bottom of RAM will generate good parity for the cache.
wdenkc0218802003-03-27 12:09:35 +0000145 */
146
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900147 /*
148 * Initialize the I-cache first,
wdenkc0218802003-03-27 12:09:35 +0000149 */
Paul Burtonca4e8332015-01-29 01:28:01 +0000150 blez t2, 1f
151 mtc0 zero, CP0_TAGLO
152 PTR_LI t0, INDEX_BASE
153 PTR_ADDU t1, t0, t2
154 /* clear tag to invalidate */
155 cache_loop t0, t1, t8, INDEX_STORE_TAG_I
156 /* fill once, so data field parity is correct */
157 PTR_LI t0, INDEX_BASE
158 cache_loop t0, t1, t8, FILL
159 /* invalidate again - prudent but not strictly neccessary */
160 PTR_LI t0, INDEX_BASE
161 cache_loop t0, t1, t8, INDEX_STORE_TAG_I
wdenkc0218802003-03-27 12:09:35 +0000162
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900163 /*
164 * then initialize D-cache.
wdenkc0218802003-03-27 12:09:35 +0000165 */
Paul Burtonca4e8332015-01-29 01:28:01 +00001661: blez t3, 3f
167 mtc0 zero, CP0_TAGLO
168 PTR_LI t0, INDEX_BASE
169 PTR_ADDU t1, t0, t3
170 /* clear all tags */
171 cache_loop t0, t1, t9, INDEX_STORE_TAG_D
172 /* load from each line (in cached space) */
173 PTR_LI t0, INDEX_BASE
1742: LONG_L zero, 0(t0)
175 PTR_ADDU t0, t9
176 bne t0, t1, 2b
177 /* clear all tags */
178 PTR_LI t0, INDEX_BASE
179 cache_loop t0, t1, t9, INDEX_STORE_TAG_D
wdenkc0218802003-03-27 12:09:35 +0000180
Paul Burtonca4e8332015-01-29 01:28:01 +00001813: jr ra
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900182 END(mips_cache_reset)
wdenkc0218802003-03-27 12:09:35 +0000183
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900184/*
185 * dcache_status - get cache status
186 *
187 * RETURNS: 0 - cache disabled; 1 - cache enabled
188 *
189 */
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900190LEAF(dcache_status)
Shinya Kuribayashid98e3482008-03-25 21:30:07 +0900191 mfc0 t0, CP0_CONFIG
192 li t1, CONF_CM_UNCACHED
193 andi t0, t0, CONF_CM_CMASK
194 move v0, zero
195 beq t0, t1, 2f
196 li v0, 1
1972: jr ra
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900198 END(dcache_status)
wdenkc0218802003-03-27 12:09:35 +0000199
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900200/*
201 * dcache_disable - disable cache
202 *
203 * RETURNS: N/A
204 *
205 */
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900206LEAF(dcache_disable)
wdenkc0218802003-03-27 12:09:35 +0000207 mfc0 t0, CP0_CONFIG
208 li t1, -8
209 and t0, t0, t1
210 ori t0, t0, CONF_CM_UNCACHED
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900211 mtc0 t0, CP0_CONFIG
Shinya Kuribayashi43c50922008-04-17 23:35:13 +0900212 jr ra
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900213 END(dcache_disable)
wdenkc0218802003-03-27 12:09:35 +0000214
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900215/*
216 * dcache_enable - enable cache
217 *
218 * RETURNS: N/A
219 *
220 */
Shinya Kuribayashiea638952008-05-03 13:51:28 +0900221LEAF(dcache_enable)
222 mfc0 t0, CP0_CONFIG
223 ori t0, CONF_CM_CMASK
224 xori t0, CONF_CM_CMASK
Daniel Schwierzeck979cfea2012-04-02 02:57:55 +0000225 ori t0, CONFIG_SYS_MIPS_CACHE_MODE
Shinya Kuribayashiea638952008-05-03 13:51:28 +0900226 mtc0 t0, CP0_CONFIG
227 jr ra
228 END(dcache_enable)