1 /* 2 * (C) Copyright 2011 3 * Ilya Yanok, EmCraft Systems 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #include <linux/types.h> 8 #include <common.h> 9 10 #ifndef CONFIG_SYS_DCACHE_OFF 11 12 #ifndef CONFIG_SYS_CACHELINE_SIZE 13 #define CONFIG_SYS_CACHELINE_SIZE 32 14 #endif 15 16 void invalidate_dcache_all(void) 17 { 18 asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0)); 19 } 20 21 void flush_dcache_all(void) 22 { 23 asm volatile( 24 "0:" 25 "mrc p15, 0, r15, c7, c14, 3\n" 26 "bne 0b\n" 27 "mcr p15, 0, %0, c7, c10, 4\n" 28 : : "r"(0) : "memory" 29 ); 30 } 31 32 static int check_cache_range(unsigned long start, unsigned long stop) 33 { 34 int ok = 1; 35 36 if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) 37 ok = 0; 38 39 if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) 40 ok = 0; 41 42 if (!ok) 43 debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", 44 start, stop); 45 46 return ok; 47 } 48 49 void invalidate_dcache_range(unsigned long start, unsigned long stop) 50 { 51 if (!check_cache_range(start, stop)) 52 return; 53 54 while (start < stop) { 55 asm volatile("mcr p15, 0, %0, c7, c6, 1\n" : : "r"(start)); 56 start += CONFIG_SYS_CACHELINE_SIZE; 57 } 58 } 59 60 void flush_dcache_range(unsigned long start, unsigned long stop) 61 { 62 if (!check_cache_range(start, stop)) 63 return; 64 65 while (start < stop) { 66 asm volatile("mcr p15, 0, %0, c7, c14, 1\n" : : "r"(start)); 67 start += CONFIG_SYS_CACHELINE_SIZE; 68 } 69 70 asm volatile("mcr p15, 0, %0, c7, c10, 4\n" : : "r"(0)); 71 } 72 #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ 73 void invalidate_dcache_all(void) 74 { 75 } 76 77 void flush_dcache_all(void) 78 { 79 } 80 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ 81 82 /* 83 * Stub implementations for l2 cache operations 84 */ 85 86 __weak void l2_cache_disable(void) {} 87 88 #if defined CONFIG_SYS_THUMB_BUILD 89 __weak void invalidate_l2_cache(void) {} 90 #endif 91