1 /* 2 * (C) Copyright 2007 3 * Nobuhiro Iwamatsu <iwamatsu@nigauri.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <command.h> 10 #include <asm/io.h> 11 #include <asm/processor.h> 12 #include <asm/system.h> 13 14 #define CACHE_VALID 1 15 #define CACHE_UPDATED 2 16 17 static inline void cache_wback_all(void) 18 { 19 unsigned long addr, data, i, j; 20 21 jump_to_P2(); 22 for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++){ 23 for (j = 0; j < CACHE_OC_NUM_WAYS; j++) { 24 addr = CACHE_OC_ADDRESS_ARRAY | (j << CACHE_OC_WAY_SHIFT) 25 | (i << CACHE_OC_ENTRY_SHIFT); 26 data = inl(addr); 27 if (data & CACHE_UPDATED) { 28 data &= ~CACHE_UPDATED; 29 outl(data, addr); 30 } 31 } 32 } 33 back_to_P1(); 34 } 35 36 37 #define CACHE_ENABLE 0 38 #define CACHE_DISABLE 1 39 40 int cache_control(unsigned int cmd) 41 { 42 unsigned long ccr; 43 44 jump_to_P2(); 45 ccr = inl(CCR); 46 47 if (ccr & CCR_CACHE_ENABLE) 48 cache_wback_all(); 49 50 if (cmd == CACHE_DISABLE) 51 outl(CCR_CACHE_STOP, CCR); 52 else 53 outl(CCR_CACHE_INIT, CCR); 54 back_to_P1(); 55 56 return 0; 57 } 58 59 void flush_dcache_range(unsigned long start, unsigned long end) 60 { 61 u32 v; 62 63 start &= ~(L1_CACHE_BYTES - 1); 64 for (v = start; v < end; v += L1_CACHE_BYTES) { 65 asm volatile ("ocbp %0" : /* no output */ 66 : "m" (__m(v))); 67 } 68 } 69 70 void invalidate_dcache_range(unsigned long start, unsigned long end) 71 { 72 u32 v; 73 74 start &= ~(L1_CACHE_BYTES - 1); 75 for (v = start; v < end; v += L1_CACHE_BYTES) { 76 asm volatile ("ocbi %0" : /* no output */ 77 : "m" (__m(v))); 78 } 79 } 80