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