xref: /rk3399_rockchip-uboot/arch/arm/cpu/arm926ejs/cache.c (revision c8d9ceaf061c5ea5c17ee9e95dbff563e41904c0)
12f3427ccSIlya Yanok /*
22f3427ccSIlya Yanok  * (C) Copyright 2011
32f3427ccSIlya Yanok  * Ilya Yanok, EmCraft Systems
42f3427ccSIlya Yanok  *
52f3427ccSIlya Yanok  * See file CREDITS for list of people who contributed to this
62f3427ccSIlya Yanok  * project.
72f3427ccSIlya Yanok  *
82f3427ccSIlya Yanok  * This program is free software; you can redistribute it and/or
92f3427ccSIlya Yanok  * modify it under the terms of the GNU General Public License as
102f3427ccSIlya Yanok  * published by the Free Software Foundation; either version 2 of
112f3427ccSIlya Yanok  * the License, or (at your option) any later version.
122f3427ccSIlya Yanok  *
132f3427ccSIlya Yanok  * This program is distributed in the hope that it will be useful,
142f3427ccSIlya Yanok  * but WITHOUT ANY WARRANTY; without even the implied warranty of
152f3427ccSIlya Yanok  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162f3427ccSIlya Yanok  * GNU General Public License for more details.
172f3427ccSIlya Yanok  *
182f3427ccSIlya Yanok  * You should have received a copy of the GNU General Public License
192f3427ccSIlya Yanok  * along with this program; if not, write to the Free Software
202f3427ccSIlya Yanok  * Foundation, Inc.
212f3427ccSIlya Yanok  */
222f3427ccSIlya Yanok #include <linux/types.h>
232f3427ccSIlya Yanok #include <common.h>
242f3427ccSIlya Yanok 
252f3427ccSIlya Yanok #ifndef CONFIG_SYS_DCACHE_OFF
26a4aaad70SMarek Vasut 
27a4aaad70SMarek Vasut #ifndef CONFIG_SYS_CACHELINE_SIZE
28a4aaad70SMarek Vasut #define CONFIG_SYS_CACHELINE_SIZE	32
29a4aaad70SMarek Vasut #endif
302f3427ccSIlya Yanok 
312f3427ccSIlya Yanok void invalidate_dcache_all(void)
322f3427ccSIlya Yanok {
33a4aaad70SMarek Vasut 	asm volatile("mcr p15, 0, %0, c7, c6, 0\n"::"r"(0));
34a4aaad70SMarek Vasut }
35a4aaad70SMarek Vasut 
36a4aaad70SMarek Vasut void flush_dcache_all(void)
37a4aaad70SMarek Vasut {
38a4aaad70SMarek Vasut 	asm volatile(
39a4aaad70SMarek Vasut 		"0:"
40a4aaad70SMarek Vasut 		"mrc p15, 0, r15, c7, c14, 3\n"
41a4aaad70SMarek Vasut 		"bne 0b\n"
42a4aaad70SMarek Vasut 		"mcr p15, 0, %0, c7, c10, 4\n"
43a4aaad70SMarek Vasut 		::"r"(0):"memory"
44a4aaad70SMarek Vasut 	);
45a4aaad70SMarek Vasut }
46a4aaad70SMarek Vasut 
47a4aaad70SMarek Vasut static int check_cache_range(unsigned long start, unsigned long stop)
48a4aaad70SMarek Vasut {
49a4aaad70SMarek Vasut 	int ok = 1;
50a4aaad70SMarek Vasut 
51a4aaad70SMarek Vasut 	if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
52a4aaad70SMarek Vasut 		ok = 0;
53a4aaad70SMarek Vasut 
54a4aaad70SMarek Vasut 	if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
55a4aaad70SMarek Vasut 		ok = 0;
56a4aaad70SMarek Vasut 
57a4aaad70SMarek Vasut 	if (!ok)
58*c8d9ceafSStefano Babic 		debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
59a4aaad70SMarek Vasut 			start, stop);
60a4aaad70SMarek Vasut 
61a4aaad70SMarek Vasut 	return ok;
622f3427ccSIlya Yanok }
632f3427ccSIlya Yanok 
642f3427ccSIlya Yanok void invalidate_dcache_range(unsigned long start, unsigned long stop)
652f3427ccSIlya Yanok {
66a4aaad70SMarek Vasut 	if (!check_cache_range(start, stop))
67a4aaad70SMarek Vasut 		return;
68a4aaad70SMarek Vasut 
69a4aaad70SMarek Vasut 	while (start < stop) {
70a4aaad70SMarek Vasut 		asm volatile("mcr p15, 0, %0, c7, c6, 1\n"::"r"(start));
71a4aaad70SMarek Vasut 		start += CONFIG_SYS_CACHELINE_SIZE;
72a4aaad70SMarek Vasut 	}
732f3427ccSIlya Yanok }
742f3427ccSIlya Yanok 
752f3427ccSIlya Yanok void flush_dcache_range(unsigned long start, unsigned long stop)
762f3427ccSIlya Yanok {
77a4aaad70SMarek Vasut 	if (!check_cache_range(start, stop))
78a4aaad70SMarek Vasut 		return;
79a4aaad70SMarek Vasut 
80a4aaad70SMarek Vasut 	while (start < stop) {
81a4aaad70SMarek Vasut 		asm volatile("mcr p15, 0, %0, c7, c14, 1\n"::"r"(start));
82a4aaad70SMarek Vasut 		start += CONFIG_SYS_CACHELINE_SIZE;
83a4aaad70SMarek Vasut 	}
84a4aaad70SMarek Vasut 
85a4aaad70SMarek Vasut 	asm("mcr p15, 0, %0, c7, c10, 4\n"::"r"(0));
86a4aaad70SMarek Vasut }
87a4aaad70SMarek Vasut 
88a4aaad70SMarek Vasut void flush_cache(unsigned long start, unsigned long size)
89a4aaad70SMarek Vasut {
90a4aaad70SMarek Vasut 	flush_dcache_range(start, start + size);
912f3427ccSIlya Yanok }
922f3427ccSIlya Yanok #else /* #ifndef CONFIG_SYS_DCACHE_OFF */
932f3427ccSIlya Yanok void invalidate_dcache_all(void)
942f3427ccSIlya Yanok {
952f3427ccSIlya Yanok }
962f3427ccSIlya Yanok 
972f3427ccSIlya Yanok void flush_dcache_all(void)
982f3427ccSIlya Yanok {
992f3427ccSIlya Yanok }
1002f3427ccSIlya Yanok 
1012f3427ccSIlya Yanok void invalidate_dcache_range(unsigned long start, unsigned long stop)
1022f3427ccSIlya Yanok {
1032f3427ccSIlya Yanok }
1042f3427ccSIlya Yanok 
1052f3427ccSIlya Yanok void flush_dcache_range(unsigned long start, unsigned long stop)
1062f3427ccSIlya Yanok {
1072f3427ccSIlya Yanok }
1082f3427ccSIlya Yanok 
1092f3427ccSIlya Yanok void flush_cache(unsigned long start, unsigned long size)
1102f3427ccSIlya Yanok {
1112f3427ccSIlya Yanok }
1122f3427ccSIlya Yanok #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
11367953027SMichael Walle 
11467953027SMichael Walle /*
11567953027SMichael Walle  * Stub implementations for l2 cache operations
11667953027SMichael Walle  */
11767953027SMichael Walle void __l2_cache_disable(void)
11867953027SMichael Walle {
11967953027SMichael Walle }
12067953027SMichael Walle void l2_cache_disable(void)
12167953027SMichael Walle         __attribute__((weak, alias("__l2_cache_disable")));
122