]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/openrisc/cpu/cache.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[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  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <asm/system.h>
10
11 void flush_dcache_range(unsigned long addr, unsigned long stop)
12 {
13         ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
14
15         while (addr < stop) {
16                 mtspr(SPR_DCBFR, addr);
17                 addr += block_size;
18         }
19 }
20
21 void invalidate_dcache_range(unsigned long addr, unsigned long stop)
22 {
23         ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
24
25         while (addr < stop) {
26                 mtspr(SPR_DCBIR, addr);
27                 addr += block_size;
28         }
29 }
30
31 static void invalidate_icache_range(unsigned long addr, unsigned long stop)
32 {
33         ulong block_size = (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16;
34
35         while (addr < stop) {
36                 mtspr(SPR_ICBIR, addr);
37                 addr += block_size;
38         }
39 }
40
41 void flush_cache(unsigned long addr, unsigned long size)
42 {
43         flush_dcache_range(addr, addr + size);
44         invalidate_icache_range(addr, addr + size);
45 }
46
47 int icache_status(void)
48 {
49         return mfspr(SPR_SR) & SPR_SR_ICE;
50 }
51
52 int checkicache(void)
53 {
54         unsigned long iccfgr;
55         unsigned long cache_set_size;
56         unsigned long cache_ways;
57         unsigned long cache_block_size;
58
59         iccfgr = mfspr(SPR_ICCFGR);
60         cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
61         cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
62         cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
63
64         return cache_set_size * cache_ways * cache_block_size;
65 }
66
67 int dcache_status(void)
68 {
69         return mfspr(SPR_SR) & SPR_SR_DCE;
70 }
71
72 int checkdcache(void)
73 {
74         unsigned long dccfgr;
75         unsigned long cache_set_size;
76         unsigned long cache_ways;
77         unsigned long cache_block_size;
78
79         dccfgr = mfspr(SPR_DCCFGR);
80         cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
81         cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
82         cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
83
84         return cache_set_size * cache_ways * cache_block_size;
85 }
86
87 void dcache_enable(void)
88 {
89         mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
90         asm volatile("l.nop");
91         asm volatile("l.nop");
92         asm volatile("l.nop");
93         asm volatile("l.nop");
94         asm volatile("l.nop");
95         asm volatile("l.nop");
96         asm volatile("l.nop");
97         asm volatile("l.nop");
98 }
99
100 void dcache_disable(void)
101 {
102         mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
103 }
104
105 void icache_enable(void)
106 {
107         mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
108         asm volatile("l.nop");
109         asm volatile("l.nop");
110         asm volatile("l.nop");
111         asm volatile("l.nop");
112         asm volatile("l.nop");
113         asm volatile("l.nop");
114         asm volatile("l.nop");
115         asm volatile("l.nop");
116 }
117
118 void icache_disable(void)
119 {
120         mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
121 }
122
123 int cache_init(void)
124 {
125         if (mfspr(SPR_UPR) & SPR_UPR_ICP) {
126                 icache_disable();
127                 invalidate_icache_range(0, checkicache());
128                 icache_enable();
129         }
130
131         if (mfspr(SPR_UPR) & SPR_UPR_DCP) {
132                 dcache_disable();
133                 invalidate_dcache_range(0, checkdcache());
134                 dcache_enable();
135         }
136
137         return 0;
138 }