1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2017 Andes Technology Corporation
4 * Rick Chen, Andes Technology Corporation <rick@andestech.com>
5 */
6
7 #include <common.h>
8 #include <cpu_func.h>
9 #include <dm.h>
10 #include <asm/cache.h>
11 #include <dm/uclass-internal.h>
12 #include <cache.h>
13 #include <asm/csr.h>
14
15 #ifdef CONFIG_RISCV_NDS_CACHE
16 #if CONFIG_IS_ENABLED(RISCV_MMODE)
17 /* mcctlcommand */
18 #define CCTL_REG_MCCTLCOMMAND_NUM 0x7cc
19
20 /* D-cache operation */
21 #define CCTL_L1D_WBINVAL_ALL 6
22 #endif
23 #endif
24
25 #ifdef CONFIG_V5L2_CACHE
_cache_enable(void)26 static void _cache_enable(void)
27 {
28 struct udevice *dev = NULL;
29
30 uclass_find_first_device(UCLASS_CACHE, &dev);
31
32 if (dev)
33 cache_enable(dev);
34 }
35
_cache_disable(void)36 static void _cache_disable(void)
37 {
38 struct udevice *dev = NULL;
39
40 uclass_find_first_device(UCLASS_CACHE, &dev);
41
42 if (dev)
43 cache_disable(dev);
44 }
45 #endif
46
flush_dcache_all(void)47 void flush_dcache_all(void)
48 {
49 #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
50 #ifdef CONFIG_RISCV_NDS_CACHE
51 #if CONFIG_IS_ENABLED(RISCV_MMODE)
52 csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
53 #endif
54 #endif
55 #endif
56 }
57
flush_dcache_range(unsigned long start,unsigned long end)58 void flush_dcache_range(unsigned long start, unsigned long end)
59 {
60 flush_dcache_all();
61 }
62
invalidate_dcache_range(unsigned long start,unsigned long end)63 void invalidate_dcache_range(unsigned long start, unsigned long end)
64 {
65 flush_dcache_all();
66 }
67
icache_enable(void)68 void icache_enable(void)
69 {
70 #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
71 #ifdef CONFIG_RISCV_NDS_CACHE
72 #if CONFIG_IS_ENABLED(RISCV_MMODE)
73 asm volatile (
74 "csrr t1, mcache_ctl\n\t"
75 "ori t0, t1, 0x1\n\t"
76 "csrw mcache_ctl, t0\n\t"
77 );
78 #endif
79 #endif
80 #endif
81 }
82
icache_disable(void)83 void icache_disable(void)
84 {
85 #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
86 #ifdef CONFIG_RISCV_NDS_CACHE
87 #if CONFIG_IS_ENABLED(RISCV_MMODE)
88 asm volatile (
89 "fence.i\n\t"
90 "csrr t1, mcache_ctl\n\t"
91 "andi t0, t1, ~0x1\n\t"
92 "csrw mcache_ctl, t0\n\t"
93 );
94 #endif
95 #endif
96 #endif
97 }
98
dcache_enable(void)99 void dcache_enable(void)
100 {
101 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
102 #ifdef CONFIG_RISCV_NDS_CACHE
103 #if CONFIG_IS_ENABLED(RISCV_MMODE)
104 asm volatile (
105 "csrr t1, mcache_ctl\n\t"
106 "ori t0, t1, 0x2\n\t"
107 "csrw mcache_ctl, t0\n\t"
108 );
109 #endif
110 #ifdef CONFIG_V5L2_CACHE
111 _cache_enable();
112 #endif
113 #endif
114 #endif
115 }
116
dcache_disable(void)117 void dcache_disable(void)
118 {
119 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
120 #ifdef CONFIG_RISCV_NDS_CACHE
121 #if CONFIG_IS_ENABLED(RISCV_MMODE)
122 csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
123 asm volatile (
124 "csrr t1, mcache_ctl\n\t"
125 "andi t0, t1, ~0x2\n\t"
126 "csrw mcache_ctl, t0\n\t"
127 );
128 #endif
129 #ifdef CONFIG_V5L2_CACHE
130 _cache_disable();
131 #endif
132 #endif
133 #endif
134 }
135
icache_status(void)136 int icache_status(void)
137 {
138 int ret = 0;
139
140 #ifdef CONFIG_RISCV_NDS_CACHE
141 #if CONFIG_IS_ENABLED(RISCV_MMODE)
142 asm volatile (
143 "csrr t1, mcache_ctl\n\t"
144 "andi %0, t1, 0x01\n\t"
145 : "=r" (ret)
146 :
147 : "memory"
148 );
149 #endif
150 #endif
151
152 return ret;
153 }
154
dcache_status(void)155 int dcache_status(void)
156 {
157 int ret = 0;
158
159 #ifdef CONFIG_RISCV_NDS_CACHE
160 #if CONFIG_IS_ENABLED(RISCV_MMODE)
161 asm volatile (
162 "csrr t1, mcache_ctl\n\t"
163 "andi %0, t1, 0x02\n\t"
164 : "=r" (ret)
165 :
166 : "memory"
167 );
168 #endif
169 #endif
170
171 return ret;
172 }
173