blob: 64dfad026324fc573d0b4a17965792826acec3e6 [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 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +020025#include <asm-offsets.h>
wdenkc0218802003-03-27 12:09:35 +000026#include <config.h>
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +090027#include <asm/asm.h>
wdenkc0218802003-03-27 12:09:35 +000028#include <asm/regdef.h>
29#include <asm/mipsregs.h>
30#include <asm/addrspace.h>
31#include <asm/cacheops.h>
32
Daniel Schwierzeck979cfea2012-04-02 02:57:55 +000033#ifndef CONFIG_SYS_MIPS_CACHE_MODE
34#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
35#endif
36
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090037#define RA t8
38
Shinya Kuribayashi373b16f2008-03-25 21:30:07 +090039/*
40 * 16kB is the maximum size of instruction and data caches on MIPS 4K,
41 * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
42 *
43 * Note that the above size is the maximum size of primary cache. U-Boot
44 * doesn't have L2 cache support for now.
45 */
46#define MIPS_MAX_CACHE_SIZE 0x10000
wdenkc0218802003-03-27 12:09:35 +000047
Shinya Kuribayashi7daf2eb2008-06-05 22:29:00 +090048#define INDEX_BASE CKSEG0
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090049
50 .macro cache_op op addr
51 .set push
52 .set noreorder
53 .set mips3
54 cache \op, 0(\addr)
55 .set pop
56 .endm
57
Shinya Kuribayashi18988402008-03-25 21:30:06 +090058 .macro f_fill64 dst, offset, val
59 LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
60 LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
61 LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
62 LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
63 LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
64 LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
65 LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
66 LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
67#if LONGSIZE == 4
68 LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
69 LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
70 LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
71 LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
72 LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
73 LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
74 LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
75 LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
76#endif
77 .endm
78
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090079/*
80 * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
81 */
82LEAF(mips_init_icache)
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +090083 blez a1, 9f
84 mtc0 zero, CP0_TAGLO
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090085 /* clear tag to invalidate */
86 PTR_LI t0, INDEX_BASE
87 PTR_ADDU t1, t0, a1
Zhi-zhou Zhangcb0a6a12012-10-16 15:02:08 +0200881: cache_op INDEX_STORE_TAG_I t0
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090089 PTR_ADDU t0, a2
90 bne t0, t1, 1b
91 /* fill once, so data field parity is correct */
92 PTR_LI t0, INDEX_BASE
Zhi-zhou Zhangcb0a6a12012-10-16 15:02:08 +0200932: cache_op FILL t0
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090094 PTR_ADDU t0, a2
95 bne t0, t1, 2b
96 /* invalidate again - prudent but not strictly neccessary */
97 PTR_LI t0, INDEX_BASE
Zhi-zhou Zhangcb0a6a12012-10-16 15:02:08 +0200981: cache_op INDEX_STORE_TAG_I t0
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +090099 PTR_ADDU t0, a2
100 bne t0, t1, 1b
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +09001019: jr ra
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900102 END(mips_init_icache)
103
104/*
105 * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
106 */
107LEAF(mips_init_dcache)
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900108 blez a1, 9f
109 mtc0 zero, CP0_TAGLO
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900110 /* clear all tags */
111 PTR_LI t0, INDEX_BASE
112 PTR_ADDU t1, t0, a1
Zhi-zhou Zhangcb0a6a12012-10-16 15:02:08 +02001131: cache_op INDEX_STORE_TAG_D t0
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900114 PTR_ADDU t0, a2
115 bne t0, t1, 1b
116 /* load from each line (in cached space) */
117 PTR_LI t0, INDEX_BASE
1182: LONG_L zero, 0(t0)
119 PTR_ADDU t0, a2
120 bne t0, t1, 2b
121 /* clear all tags */
122 PTR_LI t0, INDEX_BASE
Zhi-zhou Zhangcb0a6a12012-10-16 15:02:08 +02001231: cache_op INDEX_STORE_TAG_D t0
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900124 PTR_ADDU t0, a2
125 bne t0, t1, 1b
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +09001269: jr ra
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900127 END(mips_init_dcache)
128
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900129/*
130 * mips_cache_reset - low level initialisation of the primary caches
131 *
132 * This routine initialises the primary caches to ensure that they have good
133 * parity. It must be called by the ROM before any cached locations are used
134 * to prevent the possibility of data with bad parity being written to memory.
135 *
136 * To initialise the instruction cache it is essential that a source of data
137 * with good parity is available. This routine will initialise an area of
138 * memory starting at location zero to be used as a source of parity.
139 *
140 * RETURNS: N/A
141 *
142 */
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900143NESTED(mips_cache_reset, 0, ra)
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900144 move RA, ra
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200145 li t2, CONFIG_SYS_ICACHE_SIZE
146 li t3, CONFIG_SYS_DCACHE_SIZE
147 li t4, CONFIG_SYS_CACHELINE_SIZE
wdenkc0218802003-03-27 12:09:35 +0000148 move t5, t4
149
wdenkc0218802003-03-27 12:09:35 +0000150 li v0, MIPS_MAX_CACHE_SIZE
151
Shinya Kuribayashi18988402008-03-25 21:30:06 +0900152 /*
153 * Now clear that much memory starting from zero.
wdenkc0218802003-03-27 12:09:35 +0000154 */
Shinya Kuribayashi7daf2eb2008-06-05 22:29:00 +0900155 PTR_LI a0, CKSEG1
Shinya Kuribayashi18988402008-03-25 21:30:06 +0900156 PTR_ADDU a1, a0, v0
1572: PTR_ADDIU a0, 64
158 f_fill64 a0, -64, zero
159 bne a0, a1, 2b
wdenk8bde7f72003-06-27 21:31:46 +0000160
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900161 /*
162 * The caches are probably in an indeterminate state,
163 * so we force good parity into them by doing an
164 * invalidate, load/fill, invalidate for each line.
165 */
wdenkc0218802003-03-27 12:09:35 +0000166
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900167 /*
168 * Assume bottom of RAM will generate good parity for the cache.
wdenkc0218802003-03-27 12:09:35 +0000169 */
170
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900171 /*
172 * Initialize the I-cache first,
wdenkc0218802003-03-27 12:09:35 +0000173 */
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900174 move a1, t2
175 move a2, t4
Shinya Kuribayashi49387db2008-05-06 13:22:52 +0900176 PTR_LA t7, mips_init_icache
177 jalr t7
wdenkc0218802003-03-27 12:09:35 +0000178
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900179 /*
180 * then initialize D-cache.
wdenkc0218802003-03-27 12:09:35 +0000181 */
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900182 move a1, t3
183 move a2, t5
Shinya Kuribayashi49387db2008-05-06 13:22:52 +0900184 PTR_LA t7, mips_init_dcache
185 jalr t7
wdenkc0218802003-03-27 12:09:35 +0000186
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900187 jr RA
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900188 END(mips_cache_reset)
wdenkc0218802003-03-27 12:09:35 +0000189
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900190/*
191 * dcache_status - get cache status
192 *
193 * RETURNS: 0 - cache disabled; 1 - cache enabled
194 *
195 */
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900196LEAF(dcache_status)
Shinya Kuribayashid98e3482008-03-25 21:30:07 +0900197 mfc0 t0, CP0_CONFIG
198 li t1, CONF_CM_UNCACHED
199 andi t0, t0, CONF_CM_CMASK
200 move v0, zero
201 beq t0, t1, 2f
202 li v0, 1
2032: jr ra
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900204 END(dcache_status)
wdenkc0218802003-03-27 12:09:35 +0000205
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900206/*
207 * dcache_disable - disable cache
208 *
209 * RETURNS: N/A
210 *
211 */
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900212LEAF(dcache_disable)
wdenkc0218802003-03-27 12:09:35 +0000213 mfc0 t0, CP0_CONFIG
214 li t1, -8
215 and t0, t0, t1
216 ori t0, t0, CONF_CM_UNCACHED
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900217 mtc0 t0, CP0_CONFIG
Shinya Kuribayashi43c50922008-04-17 23:35:13 +0900218 jr ra
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900219 END(dcache_disable)
wdenkc0218802003-03-27 12:09:35 +0000220
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900221/*
222 * dcache_enable - enable cache
223 *
224 * RETURNS: N/A
225 *
226 */
Shinya Kuribayashiea638952008-05-03 13:51:28 +0900227LEAF(dcache_enable)
228 mfc0 t0, CP0_CONFIG
229 ori t0, CONF_CM_CMASK
230 xori t0, CONF_CM_CMASK
Daniel Schwierzeck979cfea2012-04-02 02:57:55 +0000231 ori t0, CONFIG_SYS_MIPS_CACHE_MODE
Shinya Kuribayashiea638952008-05-03 13:51:28 +0900232 mtc0 t0, CP0_CONFIG
233 jr ra
234 END(dcache_enable)