xref: /rk3399_rockchip-uboot/arch/nds32/lib/cache.c (revision 8d732840ba1cd4d41c12242ba07f1cf58b6429bf)
1*8d732840SMacpaul Lin /*
2*8d732840SMacpaul Lin  * Copyright (C) 2012 Andes Technology Corporation
3*8d732840SMacpaul Lin  * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
4*8d732840SMacpaul Lin  * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
5*8d732840SMacpaul Lin  *
6*8d732840SMacpaul Lin  * This program is free software; you can redistribute it and/or modify
7*8d732840SMacpaul Lin  * it under the terms of the GNU General Public License as published by
8*8d732840SMacpaul Lin  * the Free Software Foundation; either version 2 of the License, or
9*8d732840SMacpaul Lin  * (at your option) any later version.
10*8d732840SMacpaul Lin  *
11*8d732840SMacpaul Lin  * This program is distributed in the hope that it will be useful,
12*8d732840SMacpaul Lin  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*8d732840SMacpaul Lin  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
14*8d732840SMacpaul Lin  * GNU General Public License for more details.
15*8d732840SMacpaul Lin  *
16*8d732840SMacpaul Lin  * You should have received a copy of the GNU General Public License
17*8d732840SMacpaul Lin  * along with this program; if not, write to the Free Software
18*8d732840SMacpaul Lin  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
19*8d732840SMacpaul Lin  *
20*8d732840SMacpaul Lin  */
21*8d732840SMacpaul Lin 
22*8d732840SMacpaul Lin #include <common.h>
23*8d732840SMacpaul Lin 
24*8d732840SMacpaul Lin static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
25*8d732840SMacpaul Lin {
26*8d732840SMacpaul Lin 	if (cache == ICACHE)
27*8d732840SMacpaul Lin 		return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
28*8d732840SMacpaul Lin 					>> ICM_CFG_OFF_ISZ) - 1);
29*8d732840SMacpaul Lin 	else
30*8d732840SMacpaul Lin 		return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
31*8d732840SMacpaul Lin 					>> DCM_CFG_OFF_DSZ) - 1);
32*8d732840SMacpaul Lin }
33*8d732840SMacpaul Lin 
34*8d732840SMacpaul Lin void flush_dcache_range(unsigned long start, unsigned long end)
35*8d732840SMacpaul Lin {
36*8d732840SMacpaul Lin 	unsigned long line_size;
37*8d732840SMacpaul Lin 
38*8d732840SMacpaul Lin 	line_size = CACHE_LINE_SIZE(DCACHE);
39*8d732840SMacpaul Lin 
40*8d732840SMacpaul Lin 	while (end > start) {
41*8d732840SMacpaul Lin 		asm volatile (
42*8d732840SMacpaul Lin 			"\n\tcctl %0, L1D_VA_WB"
43*8d732840SMacpaul Lin 			"\n\tcctl %0, L1D_VA_INVAL"
44*8d732840SMacpaul Lin 			:
45*8d732840SMacpaul Lin 			: "r" (start)
46*8d732840SMacpaul Lin 		);
47*8d732840SMacpaul Lin 		start += line_size;
48*8d732840SMacpaul Lin 	}
49*8d732840SMacpaul Lin }
50*8d732840SMacpaul Lin 
51*8d732840SMacpaul Lin void invalidate_icache_range(unsigned long start, unsigned long end)
52*8d732840SMacpaul Lin {
53*8d732840SMacpaul Lin 	unsigned long line_size;
54*8d732840SMacpaul Lin 
55*8d732840SMacpaul Lin 	line_size = CACHE_LINE_SIZE(ICACHE);
56*8d732840SMacpaul Lin 	while (end > start) {
57*8d732840SMacpaul Lin 		asm volatile (
58*8d732840SMacpaul Lin 			"\n\tcctl %0, L1I_VA_INVAL"
59*8d732840SMacpaul Lin 			:
60*8d732840SMacpaul Lin 			: "r"(start)
61*8d732840SMacpaul Lin 		);
62*8d732840SMacpaul Lin 		start += line_size;
63*8d732840SMacpaul Lin 	}
64*8d732840SMacpaul Lin }
65*8d732840SMacpaul Lin 
66*8d732840SMacpaul Lin void invalidate_dcache_range(unsigned long start, unsigned long end)
67*8d732840SMacpaul Lin {
68*8d732840SMacpaul Lin 	unsigned long line_size;
69*8d732840SMacpaul Lin 
70*8d732840SMacpaul Lin 	line_size = CACHE_LINE_SIZE(DCACHE);
71*8d732840SMacpaul Lin 	while (end > start) {
72*8d732840SMacpaul Lin 		asm volatile (
73*8d732840SMacpaul Lin 			"\n\tcctl %0, L1D_VA_INVAL"
74*8d732840SMacpaul Lin 			:
75*8d732840SMacpaul Lin 			: "r"(start)
76*8d732840SMacpaul Lin 		);
77*8d732840SMacpaul Lin 		start += line_size;
78*8d732840SMacpaul Lin 	}
79*8d732840SMacpaul Lin }
80*8d732840SMacpaul Lin 
81*8d732840SMacpaul Lin void flush_cache(unsigned long addr, unsigned long size)
82*8d732840SMacpaul Lin {
83*8d732840SMacpaul Lin 	flush_dcache_range(addr, addr + size);
84*8d732840SMacpaul Lin 	invalidate_icache_range(addr, addr + size);
85*8d732840SMacpaul Lin }
86*8d732840SMacpaul Lin 
87*8d732840SMacpaul Lin void icache_enable(void)
88*8d732840SMacpaul Lin {
89*8d732840SMacpaul Lin 	asm volatile (
90*8d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
91*8d732840SMacpaul Lin 		"ori	$p0, $p0, 0x01\n\t"
92*8d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
93*8d732840SMacpaul Lin 		"isb\n\t"
94*8d732840SMacpaul Lin 	);
95*8d732840SMacpaul Lin }
96*8d732840SMacpaul Lin 
97*8d732840SMacpaul Lin void icache_disable(void)
98*8d732840SMacpaul Lin {
99*8d732840SMacpaul Lin 	asm volatile (
100*8d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
101*8d732840SMacpaul Lin 		"li	$p1, ~0x01\n\t"
102*8d732840SMacpaul Lin 		"and	$p0, $p0, $p1\n\t"
103*8d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
104*8d732840SMacpaul Lin 		"isb\n\t"
105*8d732840SMacpaul Lin 	);
106*8d732840SMacpaul Lin }
107*8d732840SMacpaul Lin 
108*8d732840SMacpaul Lin int icache_status(void)
109*8d732840SMacpaul Lin {
110*8d732840SMacpaul Lin 	int ret;
111*8d732840SMacpaul Lin 
112*8d732840SMacpaul Lin 	asm volatile (
113*8d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
114*8d732840SMacpaul Lin 		"andi	%0,  $p0, 0x01\n\t"
115*8d732840SMacpaul Lin 		: "=r" (ret)
116*8d732840SMacpaul Lin 		:
117*8d732840SMacpaul Lin 		: "memory"
118*8d732840SMacpaul Lin 	);
119*8d732840SMacpaul Lin 
120*8d732840SMacpaul Lin 	return ret;
121*8d732840SMacpaul Lin }
122*8d732840SMacpaul Lin 
123*8d732840SMacpaul Lin void dcache_enable(void)
124*8d732840SMacpaul Lin {
125*8d732840SMacpaul Lin 	asm volatile (
126*8d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
127*8d732840SMacpaul Lin 		"ori	$p0, $p0, 0x02\n\t"
128*8d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
129*8d732840SMacpaul Lin 		"isb\n\t"
130*8d732840SMacpaul Lin 	);
131*8d732840SMacpaul Lin }
132*8d732840SMacpaul Lin 
133*8d732840SMacpaul Lin void dcache_disable(void)
134*8d732840SMacpaul Lin {
135*8d732840SMacpaul Lin 	asm volatile (
136*8d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
137*8d732840SMacpaul Lin 		"li	$p1, ~0x02\n\t"
138*8d732840SMacpaul Lin 		"and	$p0, $p0, $p1\n\t"
139*8d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
140*8d732840SMacpaul Lin 		"isb\n\t"
141*8d732840SMacpaul Lin 	);
142*8d732840SMacpaul Lin }
143*8d732840SMacpaul Lin 
144*8d732840SMacpaul Lin int dcache_status(void)
145*8d732840SMacpaul Lin {
146*8d732840SMacpaul Lin 	int ret;
147*8d732840SMacpaul Lin 
148*8d732840SMacpaul Lin 	asm volatile (
149*8d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
150*8d732840SMacpaul Lin 		"andi	%0, $p0, 0x02\n\t"
151*8d732840SMacpaul Lin 		: "=r" (ret)
152*8d732840SMacpaul Lin 		:
153*8d732840SMacpaul Lin 		: "memory"
154*8d732840SMacpaul Lin 	);
155*8d732840SMacpaul Lin 
156*8d732840SMacpaul Lin 	return ret;
157*8d732840SMacpaul Lin }
158