xref: /openbmc/u-boot/arch/nds32/lib/cache.c (revision e9c847c3)
1 /*
2  * Copyright (C) 2012 Andes Technology Corporation
3  * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
4  * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 
11 static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
12 {
13 	if (cache == ICACHE)
14 		return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
15 					>> ICM_CFG_OFF_ISZ) - 1);
16 	else
17 		return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
18 					>> DCM_CFG_OFF_DSZ) - 1);
19 }
20 
21 void flush_dcache_range(unsigned long start, unsigned long end)
22 {
23 	unsigned long line_size;
24 
25 	line_size = CACHE_LINE_SIZE(DCACHE);
26 
27 	while (end > start) {
28 		asm volatile (
29 			"\n\tcctl %0, L1D_VA_WB"
30 			"\n\tcctl %0, L1D_VA_INVAL"
31 			:
32 			: "r" (start)
33 		);
34 		start += line_size;
35 	}
36 }
37 
38 void invalidate_icache_range(unsigned long start, unsigned long end)
39 {
40 	unsigned long line_size;
41 
42 	line_size = CACHE_LINE_SIZE(ICACHE);
43 	while (end > start) {
44 		asm volatile (
45 			"\n\tcctl %0, L1I_VA_INVAL"
46 			:
47 			: "r"(start)
48 		);
49 		start += line_size;
50 	}
51 }
52 
53 void invalidate_dcache_range(unsigned long start, unsigned long end)
54 {
55 	unsigned long line_size;
56 
57 	line_size = CACHE_LINE_SIZE(DCACHE);
58 	while (end > start) {
59 		asm volatile (
60 			"\n\tcctl %0, L1D_VA_INVAL"
61 			:
62 			: "r"(start)
63 		);
64 		start += line_size;
65 	}
66 }
67 
68 void flush_cache(unsigned long addr, unsigned long size)
69 {
70 	flush_dcache_range(addr, addr + size);
71 	invalidate_icache_range(addr, addr + size);
72 }
73 
74 void icache_enable(void)
75 {
76 	asm volatile (
77 		"mfsr	$p0, $mr8\n\t"
78 		"ori	$p0, $p0, 0x01\n\t"
79 		"mtsr	$p0, $mr8\n\t"
80 		"isb\n\t"
81 	);
82 }
83 
84 void icache_disable(void)
85 {
86 	asm volatile (
87 		"mfsr	$p0, $mr8\n\t"
88 		"li	$p1, ~0x01\n\t"
89 		"and	$p0, $p0, $p1\n\t"
90 		"mtsr	$p0, $mr8\n\t"
91 		"isb\n\t"
92 	);
93 }
94 
95 int icache_status(void)
96 {
97 	int ret;
98 
99 	asm volatile (
100 		"mfsr	$p0, $mr8\n\t"
101 		"andi	%0,  $p0, 0x01\n\t"
102 		: "=r" (ret)
103 		:
104 		: "memory"
105 	);
106 
107 	return ret;
108 }
109 
110 void dcache_enable(void)
111 {
112 	asm volatile (
113 		"mfsr	$p0, $mr8\n\t"
114 		"ori	$p0, $p0, 0x02\n\t"
115 		"mtsr	$p0, $mr8\n\t"
116 		"isb\n\t"
117 	);
118 }
119 
120 void dcache_disable(void)
121 {
122 	asm volatile (
123 		"mfsr	$p0, $mr8\n\t"
124 		"li	$p1, ~0x02\n\t"
125 		"and	$p0, $p0, $p1\n\t"
126 		"mtsr	$p0, $mr8\n\t"
127 		"isb\n\t"
128 	);
129 }
130 
131 int dcache_status(void)
132 {
133 	int ret;
134 
135 	asm volatile (
136 		"mfsr	$p0, $mr8\n\t"
137 		"andi	%0, $p0, 0x02\n\t"
138 		: "=r" (ret)
139 		:
140 		: "memory"
141 	);
142 
143 	return ret;
144 }
145