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