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