]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/mips/cpu/mips64/cache.S
Merge remote-tracking branch 'u-boot-ti/master'
[karo-tx-uboot.git] / arch / mips / cpu / mips64 / cache.S
1 /*
2  *  Cache-handling routined for MIPS CPUs
3  *
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
25 #include <asm-offsets.h>
26 #include <config.h>
27 #include <asm/asm.h>
28 #include <asm/regdef.h>
29 #include <asm/mipsregs.h>
30 #include <asm/addrspace.h>
31 #include <asm/cacheops.h>
32
33 #define RA              t9
34
35 /*
36  * 16kB is the maximum size of instruction and data caches on MIPS 4K,
37  * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
38  *
39  * Note that the above size is the maximum size of primary cache. U-Boot
40  * doesn't have L2 cache support for now.
41  */
42 #define MIPS_MAX_CACHE_SIZE     0x10000
43
44 #define INDEX_BASE      CKSEG0
45
46         .macro  cache_op op addr
47         .set    push
48         .set    noreorder
49         .set    mips3
50         cache   \op, 0(\addr)
51         .set    pop
52         .endm
53
54         .macro  f_fill64 dst, offset, val
55         LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
56         LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
57         LONG_S  \val, (\offset +  2 * LONGSIZE)(\dst)
58         LONG_S  \val, (\offset +  3 * LONGSIZE)(\dst)
59         LONG_S  \val, (\offset +  4 * LONGSIZE)(\dst)
60         LONG_S  \val, (\offset +  5 * LONGSIZE)(\dst)
61         LONG_S  \val, (\offset +  6 * LONGSIZE)(\dst)
62         LONG_S  \val, (\offset +  7 * LONGSIZE)(\dst)
63 #if LONGSIZE == 4
64         LONG_S  \val, (\offset +  8 * LONGSIZE)(\dst)
65         LONG_S  \val, (\offset +  9 * LONGSIZE)(\dst)
66         LONG_S  \val, (\offset + 10 * LONGSIZE)(\dst)
67         LONG_S  \val, (\offset + 11 * LONGSIZE)(\dst)
68         LONG_S  \val, (\offset + 12 * LONGSIZE)(\dst)
69         LONG_S  \val, (\offset + 13 * LONGSIZE)(\dst)
70         LONG_S  \val, (\offset + 14 * LONGSIZE)(\dst)
71         LONG_S  \val, (\offset + 15 * LONGSIZE)(\dst)
72 #endif
73         .endm
74
75 /*
76  * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
77  */
78 LEAF(mips_init_icache)
79         blez            a1, 9f
80         mtc0            zero, CP0_TAGLO
81         /* clear tag to invalidate */
82         PTR_LI          t0, INDEX_BASE
83         PTR_ADDU        t1, t0, a1
84 1:      cache_op        INDEX_STORE_TAG_I t0
85         PTR_ADDU        t0, a2
86         bne             t0, t1, 1b
87         /* fill once, so data field parity is correct */
88         PTR_LI          t0, INDEX_BASE
89 2:      cache_op        FILL t0
90         PTR_ADDU        t0, a2
91         bne             t0, t1, 2b
92         /* invalidate again - prudent but not strictly neccessary */
93         PTR_LI          t0, INDEX_BASE
94 1:      cache_op        INDEX_STORE_TAG_I t0
95         PTR_ADDU        t0, a2
96         bne             t0, t1, 1b
97 9:      jr              ra
98         END(mips_init_icache)
99
100 /*
101  * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
102  */
103 LEAF(mips_init_dcache)
104         blez            a1, 9f
105         mtc0            zero, CP0_TAGLO
106         /* clear all tags */
107         PTR_LI          t0, INDEX_BASE
108         PTR_ADDU        t1, t0, a1
109 1:      cache_op        INDEX_STORE_TAG_D t0
110         PTR_ADDU        t0, a2
111         bne             t0, t1, 1b
112         /* load from each line (in cached space) */
113         PTR_LI          t0, INDEX_BASE
114 2:      LONG_L          zero, 0(t0)
115         PTR_ADDU        t0, a2
116         bne             t0, t1, 2b
117         /* clear all tags */
118         PTR_LI          t0, INDEX_BASE
119 1:      cache_op        INDEX_STORE_TAG_D t0
120         PTR_ADDU        t0, a2
121         bne             t0, t1, 1b
122 9:      jr              ra
123         END(mips_init_dcache)
124
125 /*
126  * mips_cache_reset - low level initialisation of the primary caches
127  *
128  * This routine initialises the primary caches to ensure that they have good
129  * parity.  It must be called by the ROM before any cached locations are used
130  * to prevent the possibility of data with bad parity being written to memory.
131  *
132  * To initialise the instruction cache it is essential that a source of data
133  * with good parity is available. This routine will initialise an area of
134  * memory starting at location zero to be used as a source of parity.
135  *
136  * RETURNS: N/A
137  *
138  */
139 NESTED(mips_cache_reset, 0, ra)
140         move    RA, ra
141         li      t2, CONFIG_SYS_ICACHE_SIZE
142         li      t3, CONFIG_SYS_DCACHE_SIZE
143         li      t8, CONFIG_SYS_CACHELINE_SIZE
144
145         li      v0, MIPS_MAX_CACHE_SIZE
146
147         /*
148          * Now clear that much memory starting from zero.
149          */
150         PTR_LI          a0, CKSEG1
151         PTR_ADDU        a1, a0, v0
152 2:      PTR_ADDIU       a0, 64
153         f_fill64        a0, -64, zero
154         bne             a0, a1, 2b
155
156         /*
157          * The caches are probably in an indeterminate state,
158          * so we force good parity into them by doing an
159          * invalidate, load/fill, invalidate for each line.
160          */
161
162         /*
163          * Assume bottom of RAM will generate good parity for the cache.
164          */
165
166         /*
167          * Initialize the I-cache first,
168          */
169         move    a1, t2
170         move    a2, t8
171         PTR_LA  v1, mips_init_icache
172         jalr    v1
173
174         /*
175          * then initialize D-cache.
176          */
177         move    a1, t3
178         move    a2, t8
179         PTR_LA  v1, mips_init_dcache
180         jalr    v1
181
182         jr      RA
183         END(mips_cache_reset)
184
185 /*
186  * dcache_status - get cache status
187  *
188  * RETURNS: 0 - cache disabled; 1 - cache enabled
189  *
190  */
191 LEAF(dcache_status)
192         mfc0    t0, CP0_CONFIG
193         li      t1, CONF_CM_UNCACHED
194         andi    t0, t0, CONF_CM_CMASK
195         move    v0, zero
196         beq     t0, t1, 2f
197         li      v0, 1
198 2:      jr      ra
199         END(dcache_status)
200
201 /*
202  * dcache_disable - disable cache
203  *
204  * RETURNS: N/A
205  *
206  */
207 LEAF(dcache_disable)
208         mfc0    t0, CP0_CONFIG
209         li      t1, -8
210         and     t0, t0, t1
211         ori     t0, t0, CONF_CM_UNCACHED
212         mtc0    t0, CP0_CONFIG
213         jr      ra
214         END(dcache_disable)
215
216 /*
217  * dcache_enable - enable cache
218  *
219  * RETURNS: N/A
220  *
221  */
222 LEAF(dcache_enable)
223         mfc0    t0, CP0_CONFIG
224         ori     t0, CONF_CM_CMASK
225         xori    t0, CONF_CM_CMASK
226         ori     t0, CONF_CM_CACHABLE_NONCOHERENT
227         mtc0    t0, CP0_CONFIG
228         jr      ra
229         END(dcache_enable)