xref: /rk3399_rockchip-uboot/arch/nds32/lib/cache.c (revision 1a4596601fd395f3afb8f82f3f840c5e00bdd57a)
18d732840SMacpaul Lin /*
28d732840SMacpaul Lin  * Copyright (C) 2012 Andes Technology Corporation
38d732840SMacpaul Lin  * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
48d732840SMacpaul Lin  * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
58d732840SMacpaul Lin  *
6*1a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
78d732840SMacpaul Lin  */
88d732840SMacpaul Lin 
98d732840SMacpaul Lin #include <common.h>
108d732840SMacpaul Lin 
118d732840SMacpaul Lin static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
128d732840SMacpaul Lin {
138d732840SMacpaul Lin 	if (cache == ICACHE)
148d732840SMacpaul Lin 		return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
158d732840SMacpaul Lin 					>> ICM_CFG_OFF_ISZ) - 1);
168d732840SMacpaul Lin 	else
178d732840SMacpaul Lin 		return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
188d732840SMacpaul Lin 					>> DCM_CFG_OFF_DSZ) - 1);
198d732840SMacpaul Lin }
208d732840SMacpaul Lin 
218d732840SMacpaul Lin void flush_dcache_range(unsigned long start, unsigned long end)
228d732840SMacpaul Lin {
238d732840SMacpaul Lin 	unsigned long line_size;
248d732840SMacpaul Lin 
258d732840SMacpaul Lin 	line_size = CACHE_LINE_SIZE(DCACHE);
268d732840SMacpaul Lin 
278d732840SMacpaul Lin 	while (end > start) {
288d732840SMacpaul Lin 		asm volatile (
298d732840SMacpaul Lin 			"\n\tcctl %0, L1D_VA_WB"
308d732840SMacpaul Lin 			"\n\tcctl %0, L1D_VA_INVAL"
318d732840SMacpaul Lin 			:
328d732840SMacpaul Lin 			: "r" (start)
338d732840SMacpaul Lin 		);
348d732840SMacpaul Lin 		start += line_size;
358d732840SMacpaul Lin 	}
368d732840SMacpaul Lin }
378d732840SMacpaul Lin 
388d732840SMacpaul Lin void invalidate_icache_range(unsigned long start, unsigned long end)
398d732840SMacpaul Lin {
408d732840SMacpaul Lin 	unsigned long line_size;
418d732840SMacpaul Lin 
428d732840SMacpaul Lin 	line_size = CACHE_LINE_SIZE(ICACHE);
438d732840SMacpaul Lin 	while (end > start) {
448d732840SMacpaul Lin 		asm volatile (
458d732840SMacpaul Lin 			"\n\tcctl %0, L1I_VA_INVAL"
468d732840SMacpaul Lin 			:
478d732840SMacpaul Lin 			: "r"(start)
488d732840SMacpaul Lin 		);
498d732840SMacpaul Lin 		start += line_size;
508d732840SMacpaul Lin 	}
518d732840SMacpaul Lin }
528d732840SMacpaul Lin 
538d732840SMacpaul Lin void invalidate_dcache_range(unsigned long start, unsigned long end)
548d732840SMacpaul Lin {
558d732840SMacpaul Lin 	unsigned long line_size;
568d732840SMacpaul Lin 
578d732840SMacpaul Lin 	line_size = CACHE_LINE_SIZE(DCACHE);
588d732840SMacpaul Lin 	while (end > start) {
598d732840SMacpaul Lin 		asm volatile (
608d732840SMacpaul Lin 			"\n\tcctl %0, L1D_VA_INVAL"
618d732840SMacpaul Lin 			:
628d732840SMacpaul Lin 			: "r"(start)
638d732840SMacpaul Lin 		);
648d732840SMacpaul Lin 		start += line_size;
658d732840SMacpaul Lin 	}
668d732840SMacpaul Lin }
678d732840SMacpaul Lin 
688d732840SMacpaul Lin void flush_cache(unsigned long addr, unsigned long size)
698d732840SMacpaul Lin {
708d732840SMacpaul Lin 	flush_dcache_range(addr, addr + size);
718d732840SMacpaul Lin 	invalidate_icache_range(addr, addr + size);
728d732840SMacpaul Lin }
738d732840SMacpaul Lin 
748d732840SMacpaul Lin void icache_enable(void)
758d732840SMacpaul Lin {
768d732840SMacpaul Lin 	asm volatile (
778d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
788d732840SMacpaul Lin 		"ori	$p0, $p0, 0x01\n\t"
798d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
808d732840SMacpaul Lin 		"isb\n\t"
818d732840SMacpaul Lin 	);
828d732840SMacpaul Lin }
838d732840SMacpaul Lin 
848d732840SMacpaul Lin void icache_disable(void)
858d732840SMacpaul Lin {
868d732840SMacpaul Lin 	asm volatile (
878d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
888d732840SMacpaul Lin 		"li	$p1, ~0x01\n\t"
898d732840SMacpaul Lin 		"and	$p0, $p0, $p1\n\t"
908d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
918d732840SMacpaul Lin 		"isb\n\t"
928d732840SMacpaul Lin 	);
938d732840SMacpaul Lin }
948d732840SMacpaul Lin 
958d732840SMacpaul Lin int icache_status(void)
968d732840SMacpaul Lin {
978d732840SMacpaul Lin 	int ret;
988d732840SMacpaul Lin 
998d732840SMacpaul Lin 	asm volatile (
1008d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
1018d732840SMacpaul Lin 		"andi	%0,  $p0, 0x01\n\t"
1028d732840SMacpaul Lin 		: "=r" (ret)
1038d732840SMacpaul Lin 		:
1048d732840SMacpaul Lin 		: "memory"
1058d732840SMacpaul Lin 	);
1068d732840SMacpaul Lin 
1078d732840SMacpaul Lin 	return ret;
1088d732840SMacpaul Lin }
1098d732840SMacpaul Lin 
1108d732840SMacpaul Lin void dcache_enable(void)
1118d732840SMacpaul Lin {
1128d732840SMacpaul Lin 	asm volatile (
1138d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
1148d732840SMacpaul Lin 		"ori	$p0, $p0, 0x02\n\t"
1158d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
1168d732840SMacpaul Lin 		"isb\n\t"
1178d732840SMacpaul Lin 	);
1188d732840SMacpaul Lin }
1198d732840SMacpaul Lin 
1208d732840SMacpaul Lin void dcache_disable(void)
1218d732840SMacpaul Lin {
1228d732840SMacpaul Lin 	asm volatile (
1238d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
1248d732840SMacpaul Lin 		"li	$p1, ~0x02\n\t"
1258d732840SMacpaul Lin 		"and	$p0, $p0, $p1\n\t"
1268d732840SMacpaul Lin 		"mtsr	$p0, $mr8\n\t"
1278d732840SMacpaul Lin 		"isb\n\t"
1288d732840SMacpaul Lin 	);
1298d732840SMacpaul Lin }
1308d732840SMacpaul Lin 
1318d732840SMacpaul Lin int dcache_status(void)
1328d732840SMacpaul Lin {
1338d732840SMacpaul Lin 	int ret;
1348d732840SMacpaul Lin 
1358d732840SMacpaul Lin 	asm volatile (
1368d732840SMacpaul Lin 		"mfsr	$p0, $mr8\n\t"
1378d732840SMacpaul Lin 		"andi	%0, $p0, 0x02\n\t"
1388d732840SMacpaul Lin 		: "=r" (ret)
1398d732840SMacpaul Lin 		:
1408d732840SMacpaul Lin 		: "memory"
1418d732840SMacpaul Lin 	);
1428d732840SMacpaul Lin 
1438d732840SMacpaul Lin 	return ret;
1448d732840SMacpaul Lin }
145