1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2023 Andes Technology Corporation
4  * Rick Chen, Andes Technology Corporation <rick@andestech.com>
5  */
6 
7 #include <asm/csr.h>
8 #include <asm/asm.h>
9 #include <common.h>
10 #include <cache.h>
11 #include <cpu_func.h>
12 #include <dm.h>
13 #include <dm/uclass-internal.h>
14 #include <asm/arch-andes/csr.h>
15 
16 #ifdef CONFIG_V5L2_CACHE
enable_caches(void)17 void enable_caches(void)
18 {
19 	struct udevice *dev;
20 	int ret;
21 
22 	ret = uclass_get_device_by_driver(UCLASS_CACHE,
23 					  DM_DRIVER_GET(v5l2_cache),
24 					  &dev);
25 	if (ret) {
26 		log_debug("Cannot enable v5l2 cache\n");
27 	} else {
28 		ret = cache_enable(dev);
29 		if (ret)
30 			log_debug("v5l2 cache enable failed\n");
31 	}
32 }
33 
cache_ops(int (* ops)(struct udevice * dev))34 static void cache_ops(int (*ops)(struct udevice *dev))
35 {
36 	struct udevice *dev = NULL;
37 
38 	uclass_find_first_device(UCLASS_CACHE, &dev);
39 
40 	if (dev)
41 		ops(dev);
42 }
43 #endif
44 
flush_dcache_all(void)45 void flush_dcache_all(void)
46 {
47 #if CONFIG_IS_ENABLED(RISCV_MMODE)
48 	csr_write(CSR_MCCTLCOMMAND, CCTL_L1D_WBINVAL_ALL);
49 #endif
50 }
51 
flush_dcache_range(unsigned long start,unsigned long end)52 void flush_dcache_range(unsigned long start, unsigned long end)
53 {
54 	flush_dcache_all();
55 }
56 
invalidate_dcache_range(unsigned long start,unsigned long end)57 void invalidate_dcache_range(unsigned long start, unsigned long end)
58 {
59 	flush_dcache_all();
60 }
61 
icache_enable(void)62 void icache_enable(void)
63 {
64 #if CONFIG_IS_ENABLED(RISCV_MMODE)
65 	asm volatile("csrsi %0, 0x1" :: "i"(CSR_MCACHE_CTL));
66 #endif
67 }
68 
icache_disable(void)69 void icache_disable(void)
70 {
71 #if CONFIG_IS_ENABLED(RISCV_MMODE)
72 	asm volatile("csrci %0, 0x1" :: "i"(CSR_MCACHE_CTL));
73 #endif
74 }
75 
dcache_enable(void)76 void dcache_enable(void)
77 {
78 #if CONFIG_IS_ENABLED(RISCV_MMODE)
79 	asm volatile("csrsi %0, 0x2" :: "i"(CSR_MCACHE_CTL));
80 #endif
81 
82 #ifdef CONFIG_V5L2_CACHE
83 	cache_ops(cache_enable);
84 #endif
85 }
86 
dcache_disable(void)87 void dcache_disable(void)
88 {
89 #if CONFIG_IS_ENABLED(RISCV_MMODE)
90 	asm volatile("csrci %0, 0x2" :: "i"(CSR_MCACHE_CTL));
91 #endif
92 
93 #ifdef CONFIG_V5L2_CACHE
94 	cache_ops(cache_disable);
95 #endif
96 }
97 
icache_status(void)98 int icache_status(void)
99 {
100 	int ret = 0;
101 
102 #if CONFIG_IS_ENABLED(RISCV_MMODE)
103 	asm volatile (
104 		"csrr t1, %1\n\t"
105 		"andi %0, t1, 0x01\n\t"
106 		: "=r" (ret)
107 		: "i"(CSR_MCACHE_CTL)
108 		: "memory"
109 	);
110 #endif
111 
112 	return !!ret;
113 }
114 
dcache_status(void)115 int dcache_status(void)
116 {
117 	int ret = 0;
118 
119 #if CONFIG_IS_ENABLED(RISCV_MMODE)
120 	asm volatile (
121 		"csrr t1, %1\n\t"
122 		"andi %0, t1, 0x02\n\t"
123 		: "=r" (ret)
124 		: "i" (CSR_MCACHE_CTL)
125 		: "memory"
126 	);
127 #endif
128 
129 	return !!ret;
130 }
131