]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/openrisc/cpu/cache.c
socfpga: Move board/socfpga_cyclone5 to board/socfpga
[karo-tx-uboot.git] / arch / openrisc / cpu / cache.c
1 /*
2  * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
3  * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA
19  */
20
21 #include <common.h>
22 #include <asm/system.h>
23
24 void flush_dcache_range(unsigned long addr, unsigned long stop)
25 {
26         ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
27
28         while (addr < stop) {
29                 mtspr(SPR_DCBFR, addr);
30                 addr += block_size;
31         }
32 }
33
34 void invalidate_dcache_range(unsigned long addr, unsigned long stop)
35 {
36         ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
37
38         while (addr < stop) {
39                 mtspr(SPR_DCBIR, addr);
40                 addr += block_size;
41         }
42 }
43
44 static void invalidate_icache_range(unsigned long addr, unsigned long stop)
45 {
46         ulong block_size = (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16;
47
48         while (addr < stop) {
49                 mtspr(SPR_ICBIR, addr);
50                 addr += block_size;
51         }
52 }
53
54 void flush_cache(unsigned long addr, unsigned long size)
55 {
56         flush_dcache_range(addr, addr + size);
57         invalidate_icache_range(addr, addr + size);
58 }
59
60 int icache_status(void)
61 {
62         return mfspr(SPR_SR) & SPR_SR_ICE;
63 }
64
65 int checkicache(void)
66 {
67         unsigned long iccfgr;
68         unsigned long cache_set_size;
69         unsigned long cache_ways;
70         unsigned long cache_block_size;
71
72         iccfgr = mfspr(SPR_ICCFGR);
73         cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
74         cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
75         cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
76
77         return cache_set_size * cache_ways * cache_block_size;
78 }
79
80 int dcache_status(void)
81 {
82         return mfspr(SPR_SR) & SPR_SR_DCE;
83 }
84
85 int checkdcache(void)
86 {
87         unsigned long dccfgr;
88         unsigned long cache_set_size;
89         unsigned long cache_ways;
90         unsigned long cache_block_size;
91
92         dccfgr = mfspr(SPR_DCCFGR);
93         cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
94         cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
95         cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
96
97         return cache_set_size * cache_ways * cache_block_size;
98 }
99
100 void dcache_enable(void)
101 {
102         mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
103         asm volatile("l.nop");
104         asm volatile("l.nop");
105         asm volatile("l.nop");
106         asm volatile("l.nop");
107         asm volatile("l.nop");
108         asm volatile("l.nop");
109         asm volatile("l.nop");
110         asm volatile("l.nop");
111 }
112
113 void dcache_disable(void)
114 {
115         mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
116 }
117
118 void icache_enable(void)
119 {
120         mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
121         asm volatile("l.nop");
122         asm volatile("l.nop");
123         asm volatile("l.nop");
124         asm volatile("l.nop");
125         asm volatile("l.nop");
126         asm volatile("l.nop");
127         asm volatile("l.nop");
128         asm volatile("l.nop");
129 }
130
131 void icache_disable(void)
132 {
133         mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
134 }
135
136 int cache_init(void)
137 {
138         if (mfspr(SPR_UPR) & SPR_UPR_ICP) {
139                 icache_disable();
140                 invalidate_icache_range(0, checkicache());
141                 icache_enable();
142         }
143
144         if (mfspr(SPR_UPR) & SPR_UPR_DCP) {
145                 dcache_disable();
146                 invalidate_dcache_range(0, checkdcache());
147                 dcache_enable();
148         }
149
150         return 0;
151 }