]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/mips/lib/cache_init.S
karo: fdt: fix panel-dpi support
[karo-tx-uboot.git] / arch / mips / lib / cache_init.S
1 /*
2  *  Cache-handling routined for MIPS CPUs
3  *
4  *  Copyright (c) 2003  Wolfgang Denk <wd@denx.de>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <asm-offsets.h>
10 #include <config.h>
11 #include <asm/asm.h>
12 #include <asm/regdef.h>
13 #include <asm/mipsregs.h>
14 #include <asm/addrspace.h>
15 #include <asm/cacheops.h>
16
17 #ifndef CONFIG_SYS_MIPS_CACHE_MODE
18 #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
19 #endif
20
21 #define INDEX_BASE      CKSEG0
22
23         .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
44         .macro cache_loop       curr, end, line_sz, op
45 10:     cache           \op, 0(\curr)
46         PTR_ADDU        \curr, \curr, \line_sz
47         bne             \curr, \end, 10b
48         .endm
49
50         .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
84 10:
85         .set    pop
86         .endm
87 /*
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  */
101 LEAF(mips_cache_reset)
102 #ifdef CONFIG_SYS_ICACHE_SIZE
103         li      t2, CONFIG_SYS_ICACHE_SIZE
104         li      t8, CONFIG_SYS_CACHELINE_SIZE
105 #else
106         l1_info t2, t8, MIPS_CONF1_IA_SHIFT
107 #endif
108
109 #ifdef CONFIG_SYS_DCACHE_SIZE
110         li      t3, CONFIG_SYS_DCACHE_SIZE
111         li      t9, CONFIG_SYS_CACHELINE_SIZE
112 #else
113         l1_info t3, t9, MIPS_CONF1_DA_SHIFT
114 #endif
115
116 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
117
118         /* Determine the largest L1 cache size */
119 #if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE)
120 #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE
121         li      v0, CONFIG_SYS_ICACHE_SIZE
122 #else
123         li      v0, CONFIG_SYS_DCACHE_SIZE
124 #endif
125 #else
126         move    v0, t2
127         sltu    t1, t2, t3
128         movn    v0, t3, t1
129 #endif
130         /*
131          * Now clear that much memory starting from zero.
132          */
133         PTR_LI          a0, CKSEG1
134         PTR_ADDU        a1, a0, v0
135 2:      PTR_ADDIU       a0, 64
136         f_fill64        a0, -64, zero
137         bne             a0, a1, 2b
138
139 #endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */
140
141         /*
142          * The TagLo registers used depend upon the CPU implementation, but the
143          * architecture requires that it is safe for software to write to both
144          * TagLo selects 0 & 2 covering supported cases.
145          */
146         mtc0            zero, CP0_TAGLO
147         mtc0            zero, CP0_TAGLO, 2
148
149         /*
150          * The caches are probably in an indeterminate state, so we force good
151          * parity into them by doing an invalidate for each line. If
152          * CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD is set then we'll proceed to
153          * perform a load/fill & a further invalidate for each line, assuming
154          * that the bottom of RAM (having just been cleared) will generate good
155          * parity for the cache.
156          */
157
158         /*
159          * Initialize the I-cache first,
160          */
161         blez            t2, 1f
162         PTR_LI          t0, INDEX_BASE
163         PTR_ADDU        t1, t0, t2
164         /* clear tag to invalidate */
165         cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
166 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
167         /* fill once, so data field parity is correct */
168         PTR_LI          t0, INDEX_BASE
169         cache_loop      t0, t1, t8, FILL
170         /* invalidate again - prudent but not strictly neccessary */
171         PTR_LI          t0, INDEX_BASE
172         cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
173 #endif
174
175         /*
176          * then initialize D-cache.
177          */
178 1:      blez            t3, 3f
179         PTR_LI          t0, INDEX_BASE
180         PTR_ADDU        t1, t0, t3
181         /* clear all tags */
182         cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
183 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
184         /* load from each line (in cached space) */
185         PTR_LI          t0, INDEX_BASE
186 2:      LONG_L          zero, 0(t0)
187         PTR_ADDU        t0, t9
188         bne             t0, t1, 2b
189         /* clear all tags */
190         PTR_LI          t0, INDEX_BASE
191         cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
192 #endif
193
194 3:      jr      ra
195         END(mips_cache_reset)
196
197 /*
198  * dcache_status - get cache status
199  *
200  * RETURNS: 0 - cache disabled; 1 - cache enabled
201  *
202  */
203 LEAF(dcache_status)
204         mfc0    t0, CP0_CONFIG
205         li      t1, CONF_CM_UNCACHED
206         andi    t0, t0, CONF_CM_CMASK
207         move    v0, zero
208         beq     t0, t1, 2f
209         li      v0, 1
210 2:      jr      ra
211         END(dcache_status)
212
213 /*
214  * dcache_disable - disable cache
215  *
216  * RETURNS: N/A
217  *
218  */
219 LEAF(dcache_disable)
220         mfc0    t0, CP0_CONFIG
221         li      t1, -8
222         and     t0, t0, t1
223         ori     t0, t0, CONF_CM_UNCACHED
224         mtc0    t0, CP0_CONFIG
225         jr      ra
226         END(dcache_disable)
227
228 /*
229  * dcache_enable - enable cache
230  *
231  * RETURNS: N/A
232  *
233  */
234 LEAF(dcache_enable)
235         mfc0    t0, CP0_CONFIG
236         ori     t0, CONF_CM_CMASK
237         xori    t0, CONF_CM_CMASK
238         ori     t0, CONFIG_SYS_MIPS_CACHE_MODE
239         mtc0    t0, CP0_CONFIG
240         jr      ra
241         END(dcache_enable)