blob: fe5b704fb06136a85e0b7994955f138e236690e9 [file] [log] [blame]
Stefan Kristiansson272f84b2011-11-26 19:04:51 +00001/*
2 * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
3 * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Stefan Kristiansson272f84b2011-11-26 19:04:51 +00006 */
7
8#include <common.h>
9#include <asm/system.h>
10
11void 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
21void 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
31static 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
41void 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
47int icache_status(void)
48{
49 return mfspr(SPR_SR) & SPR_SR_ICE;
50}
51
52int 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
67int dcache_status(void)
68{
69 return mfspr(SPR_SR) & SPR_SR_DCE;
70}
71
72int 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
87void 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
100void dcache_disable(void)
101{
102 mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
103}
104
105void 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
118void icache_disable(void)
119{
120 mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
121}
122
123int 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}