1 #ifndef _METAG_L2CACHE_H 2 #define _METAG_L2CACHE_H 3 4 #ifdef CONFIG_METAG_L2C 5 6 #include <asm/global_lock.h> 7 #include <asm/io.h> 8 9 /* 10 * Store the last known value of pfenable (we don't want prefetch enabled while 11 * L2 is off). 12 */ 13 extern int l2c_pfenable; 14 15 /* defined in arch/metag/drivers/core-sysfs.c */ 16 extern struct sysdev_class cache_sysclass; 17 18 static inline void wr_fence(void); 19 20 /* 21 * Functions for reading of L2 cache configuration. 22 */ 23 24 /* Get raw L2 config register (CORE_CONFIG3) */ meta_l2c_config(void)25static inline unsigned int meta_l2c_config(void) 26 { 27 const unsigned int *corecfg3 = (const unsigned int *)METAC_CORE_CONFIG3; 28 return *corecfg3; 29 } 30 31 /* Get whether the L2 is present */ meta_l2c_is_present(void)32static inline int meta_l2c_is_present(void) 33 { 34 return meta_l2c_config() & METAC_CORECFG3_L2C_HAVE_L2C_BIT; 35 } 36 37 /* Get whether the L2 is configured for write-back instead of write-through */ meta_l2c_is_writeback(void)38static inline int meta_l2c_is_writeback(void) 39 { 40 return meta_l2c_config() & METAC_CORECFG3_L2C_MODE_BIT; 41 } 42 43 /* Get whether the L2 is unified instead of separated code/data */ meta_l2c_is_unified(void)44static inline int meta_l2c_is_unified(void) 45 { 46 return meta_l2c_config() & METAC_CORECFG3_L2C_UNIFIED_BIT; 47 } 48 49 /* Get the L2 cache size in bytes */ meta_l2c_size(void)50static inline unsigned int meta_l2c_size(void) 51 { 52 unsigned int size_s; 53 if (!meta_l2c_is_present()) 54 return 0; 55 size_s = (meta_l2c_config() & METAC_CORECFG3_L2C_SIZE_BITS) 56 >> METAC_CORECFG3_L2C_SIZE_S; 57 /* L2CSIZE is in KiB */ 58 return 1024 << size_s; 59 } 60 61 /* Get the number of ways in the L2 cache */ meta_l2c_ways(void)62static inline unsigned int meta_l2c_ways(void) 63 { 64 unsigned int ways_s; 65 if (!meta_l2c_is_present()) 66 return 0; 67 ways_s = (meta_l2c_config() & METAC_CORECFG3_L2C_NUM_WAYS_BITS) 68 >> METAC_CORECFG3_L2C_NUM_WAYS_S; 69 return 0x1 << ways_s; 70 } 71 72 /* Get the line size of the L2 cache */ meta_l2c_linesize(void)73static inline unsigned int meta_l2c_linesize(void) 74 { 75 unsigned int line_size; 76 if (!meta_l2c_is_present()) 77 return 0; 78 line_size = (meta_l2c_config() & METAC_CORECFG3_L2C_LINE_SIZE_BITS) 79 >> METAC_CORECFG3_L2C_LINE_SIZE_S; 80 switch (line_size) { 81 case METAC_CORECFG3_L2C_LINE_SIZE_64B: 82 return 64; 83 default: 84 return 0; 85 } 86 } 87 88 /* Get the revision ID of the L2 cache */ meta_l2c_revision(void)89static inline unsigned int meta_l2c_revision(void) 90 { 91 return (meta_l2c_config() & METAC_CORECFG3_L2C_REV_ID_BITS) 92 >> METAC_CORECFG3_L2C_REV_ID_S; 93 } 94 95 96 /* 97 * Start an initialisation of the L2 cachelines and wait for completion. 98 * This should only be done in a LOCK1 or LOCK2 critical section while the L2 99 * is disabled. 100 */ _meta_l2c_init(void)101static inline void _meta_l2c_init(void) 102 { 103 metag_out32(SYSC_L2C_INIT_INIT, SYSC_L2C_INIT); 104 while (metag_in32(SYSC_L2C_INIT) == SYSC_L2C_INIT_IN_PROGRESS) 105 /* do nothing */; 106 } 107 108 /* 109 * Start a writeback of dirty L2 cachelines and wait for completion. 110 * This should only be done in a LOCK1 or LOCK2 critical section. 111 */ _meta_l2c_purge(void)112static inline void _meta_l2c_purge(void) 113 { 114 metag_out32(SYSC_L2C_PURGE_PURGE, SYSC_L2C_PURGE); 115 while (metag_in32(SYSC_L2C_PURGE) == SYSC_L2C_PURGE_IN_PROGRESS) 116 /* do nothing */; 117 } 118 119 /* Set whether the L2 cache is enabled. */ _meta_l2c_enable(int enabled)120static inline void _meta_l2c_enable(int enabled) 121 { 122 unsigned int enable; 123 124 enable = metag_in32(SYSC_L2C_ENABLE); 125 if (enabled) 126 enable |= SYSC_L2C_ENABLE_ENABLE_BIT; 127 else 128 enable &= ~SYSC_L2C_ENABLE_ENABLE_BIT; 129 metag_out32(enable, SYSC_L2C_ENABLE); 130 } 131 132 /* Set whether the L2 cache prefetch is enabled. */ _meta_l2c_pf_enable(int pfenabled)133static inline void _meta_l2c_pf_enable(int pfenabled) 134 { 135 unsigned int enable; 136 137 enable = metag_in32(SYSC_L2C_ENABLE); 138 if (pfenabled) 139 enable |= SYSC_L2C_ENABLE_PFENABLE_BIT; 140 else 141 enable &= ~SYSC_L2C_ENABLE_PFENABLE_BIT; 142 metag_out32(enable, SYSC_L2C_ENABLE); 143 } 144 145 /* Return whether the L2 cache is enabled */ _meta_l2c_is_enabled(void)146static inline int _meta_l2c_is_enabled(void) 147 { 148 return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_ENABLE_BIT; 149 } 150 151 /* Return whether the L2 cache prefetch is enabled */ _meta_l2c_pf_is_enabled(void)152static inline int _meta_l2c_pf_is_enabled(void) 153 { 154 return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_PFENABLE_BIT; 155 } 156 157 158 /* Return whether the L2 cache is enabled */ meta_l2c_is_enabled(void)159static inline int meta_l2c_is_enabled(void) 160 { 161 int en; 162 163 /* 164 * There is no need to lock at the moment, as the enable bit is never 165 * intermediately changed, so we will never see an intermediate result. 166 */ 167 en = _meta_l2c_is_enabled(); 168 169 return en; 170 } 171 172 /* 173 * Ensure the L2 cache is disabled. 174 * Return whether the L2 was previously disabled. 175 */ 176 int meta_l2c_disable(void); 177 178 /* 179 * Ensure the L2 cache is enabled. 180 * Return whether the L2 was previously enabled. 181 */ 182 int meta_l2c_enable(void); 183 184 /* Return whether the L2 cache prefetch is enabled */ meta_l2c_pf_is_enabled(void)185static inline int meta_l2c_pf_is_enabled(void) 186 { 187 return l2c_pfenable; 188 } 189 190 /* 191 * Set whether the L2 cache prefetch is enabled. 192 * Return whether the L2 prefetch was previously enabled. 193 */ 194 int meta_l2c_pf_enable(int pfenable); 195 196 /* 197 * Flush the L2 cache. 198 * Return 1 if the L2 is disabled. 199 */ 200 int meta_l2c_flush(void); 201 202 /* 203 * Write back all dirty cache lines in the L2 cache. 204 * Return 1 if the L2 is disabled or there isn't any writeback. 205 */ meta_l2c_writeback(void)206static inline int meta_l2c_writeback(void) 207 { 208 unsigned long flags; 209 int en; 210 211 /* no need to purge if it's not a writeback cache */ 212 if (!meta_l2c_is_writeback()) 213 return 1; 214 215 /* 216 * Purge only works if the L2 is enabled, and involves reading back to 217 * detect completion, so keep this operation atomic with other threads. 218 */ 219 __global_lock1(flags); 220 en = meta_l2c_is_enabled(); 221 if (likely(en)) { 222 wr_fence(); 223 _meta_l2c_purge(); 224 } 225 __global_unlock1(flags); 226 227 return !en; 228 } 229 230 #else /* CONFIG_METAG_L2C */ 231 232 #define meta_l2c_config() 0 233 #define meta_l2c_is_present() 0 234 #define meta_l2c_is_writeback() 0 235 #define meta_l2c_is_unified() 0 236 #define meta_l2c_size() 0 237 #define meta_l2c_ways() 0 238 #define meta_l2c_linesize() 0 239 #define meta_l2c_revision() 0 240 241 #define meta_l2c_is_enabled() 0 242 #define _meta_l2c_pf_is_enabled() 0 243 #define meta_l2c_pf_is_enabled() 0 244 #define meta_l2c_disable() 1 245 #define meta_l2c_enable() 0 246 #define meta_l2c_pf_enable(X) 0 meta_l2c_flush(void)247static inline int meta_l2c_flush(void) 248 { 249 return 1; 250 } meta_l2c_writeback(void)251static inline int meta_l2c_writeback(void) 252 { 253 return 1; 254 } 255 256 #endif /* CONFIG_METAG_L2C */ 257 258 #endif /* _METAG_L2CACHE_H */ 259