18f0fec74SPeter Tyser /* 28f0fec74SPeter Tyser * (C) Copyright 2007 38f0fec74SPeter Tyser * Nobuhiro Iwamatsu <iwamatsu@nigauri.org> 48f0fec74SPeter Tyser * 58f0fec74SPeter Tyser * See file CREDITS for list of people who contributed to this 68f0fec74SPeter Tyser * project. 78f0fec74SPeter Tyser * 88f0fec74SPeter Tyser * This program is free software; you can redistribute it and/or 98f0fec74SPeter Tyser * modify it under the terms of the GNU General Public License as 108f0fec74SPeter Tyser * published by the Free Software Foundation; either version 2 of 118f0fec74SPeter Tyser * the License, or (at your option) any later version. 128f0fec74SPeter Tyser * 138f0fec74SPeter Tyser * This program is distributed in the hope that it will be useful, 148f0fec74SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 158f0fec74SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 168f0fec74SPeter Tyser * GNU General Public License for more details. 178f0fec74SPeter Tyser * 188f0fec74SPeter Tyser * You should have received a copy of the GNU General Public License 198f0fec74SPeter Tyser * along with this program; if not, write to the Free Software 208f0fec74SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 218f0fec74SPeter Tyser * MA 02111-1307 USA 228f0fec74SPeter Tyser */ 238f0fec74SPeter Tyser 248f0fec74SPeter Tyser #include <common.h> 258f0fec74SPeter Tyser #include <command.h> 268f0fec74SPeter Tyser #include <asm/processor.h> 278f0fec74SPeter Tyser #include <asm/io.h> 288f0fec74SPeter Tyser 298f0fec74SPeter Tyser /* 308f0fec74SPeter Tyser * Jump to P2 area. 318f0fec74SPeter Tyser * When handling TLB or caches, we need to do it from P2 area. 328f0fec74SPeter Tyser */ 338f0fec74SPeter Tyser #define jump_to_P2() \ 348f0fec74SPeter Tyser do { \ 358f0fec74SPeter Tyser unsigned long __dummy; \ 368f0fec74SPeter Tyser __asm__ __volatile__( \ 378f0fec74SPeter Tyser "mov.l 1f, %0\n\t" \ 388f0fec74SPeter Tyser "or %1, %0\n\t" \ 398f0fec74SPeter Tyser "jmp @%0\n\t" \ 408f0fec74SPeter Tyser " nop\n\t" \ 418f0fec74SPeter Tyser ".balign 4\n" \ 428f0fec74SPeter Tyser "1: .long 2f\n" \ 438f0fec74SPeter Tyser "2:" \ 448f0fec74SPeter Tyser : "=&r" (__dummy) \ 458f0fec74SPeter Tyser : "r" (0x20000000)); \ 468f0fec74SPeter Tyser } while (0) 478f0fec74SPeter Tyser 488f0fec74SPeter Tyser /* 498f0fec74SPeter Tyser * Back to P1 area. 508f0fec74SPeter Tyser */ 518f0fec74SPeter Tyser #define back_to_P1() \ 528f0fec74SPeter Tyser do { \ 538f0fec74SPeter Tyser unsigned long __dummy; \ 548f0fec74SPeter Tyser __asm__ __volatile__( \ 558f0fec74SPeter Tyser "nop;nop;nop;nop;nop;nop;nop\n\t" \ 568f0fec74SPeter Tyser "mov.l 1f, %0\n\t" \ 578f0fec74SPeter Tyser "jmp @%0\n\t" \ 588f0fec74SPeter Tyser " nop\n\t" \ 598f0fec74SPeter Tyser ".balign 4\n" \ 608f0fec74SPeter Tyser "1: .long 2f\n" \ 618f0fec74SPeter Tyser "2:" \ 628f0fec74SPeter Tyser : "=&r" (__dummy)); \ 638f0fec74SPeter Tyser } while (0) 648f0fec74SPeter Tyser 658f0fec74SPeter Tyser #define CACHE_VALID 1 668f0fec74SPeter Tyser #define CACHE_UPDATED 2 678f0fec74SPeter Tyser 688f0fec74SPeter Tyser static inline void cache_wback_all(void) 698f0fec74SPeter Tyser { 708f0fec74SPeter Tyser unsigned long addr, data, i, j; 718f0fec74SPeter Tyser 728f0fec74SPeter Tyser jump_to_P2(); 738f0fec74SPeter Tyser for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++){ 748f0fec74SPeter Tyser for (j = 0; j < CACHE_OC_NUM_WAYS; j++) { 758f0fec74SPeter Tyser addr = CACHE_OC_ADDRESS_ARRAY | (j << CACHE_OC_WAY_SHIFT) 768f0fec74SPeter Tyser | (i << CACHE_OC_ENTRY_SHIFT); 778f0fec74SPeter Tyser data = inl(addr); 788f0fec74SPeter Tyser if (data & CACHE_UPDATED) { 798f0fec74SPeter Tyser data &= ~CACHE_UPDATED; 808f0fec74SPeter Tyser outl(data, addr); 818f0fec74SPeter Tyser } 828f0fec74SPeter Tyser } 838f0fec74SPeter Tyser } 848f0fec74SPeter Tyser back_to_P1(); 858f0fec74SPeter Tyser } 868f0fec74SPeter Tyser 878f0fec74SPeter Tyser 888f0fec74SPeter Tyser #define CACHE_ENABLE 0 898f0fec74SPeter Tyser #define CACHE_DISABLE 1 908f0fec74SPeter Tyser 918f0fec74SPeter Tyser int cache_control(unsigned int cmd) 928f0fec74SPeter Tyser { 938f0fec74SPeter Tyser unsigned long ccr; 948f0fec74SPeter Tyser 958f0fec74SPeter Tyser jump_to_P2(); 968f0fec74SPeter Tyser ccr = inl(CCR); 978f0fec74SPeter Tyser 988f0fec74SPeter Tyser if (ccr & CCR_CACHE_ENABLE) 998f0fec74SPeter Tyser cache_wback_all(); 1008f0fec74SPeter Tyser 1018f0fec74SPeter Tyser if (cmd == CACHE_DISABLE) 1028f0fec74SPeter Tyser outl(CCR_CACHE_STOP, CCR); 1038f0fec74SPeter Tyser else 1048f0fec74SPeter Tyser outl(CCR_CACHE_INIT, CCR); 1058f0fec74SPeter Tyser back_to_P1(); 1068f0fec74SPeter Tyser 1078f0fec74SPeter Tyser return 0; 1088f0fec74SPeter Tyser } 109*17210643SMike Frysinger 110*17210643SMike Frysinger void dcache_wback_range(u32 start, u32 end) 111*17210643SMike Frysinger { 112*17210643SMike Frysinger u32 v; 113*17210643SMike Frysinger 114*17210643SMike Frysinger start &= ~(L1_CACHE_BYTES - 1); 115*17210643SMike Frysinger for (v = start; v < end; v += L1_CACHE_BYTES) { 116*17210643SMike Frysinger asm volatile ("ocbwb %0" : /* no output */ 117*17210643SMike Frysinger : "m" (__m(v))); 118*17210643SMike Frysinger } 119*17210643SMike Frysinger } 120*17210643SMike Frysinger 121*17210643SMike Frysinger void dcache_invalid_range(u32 start, u32 end) 122*17210643SMike Frysinger { 123*17210643SMike Frysinger u32 v; 124*17210643SMike Frysinger 125*17210643SMike Frysinger start &= ~(L1_CACHE_BYTES - 1); 126*17210643SMike Frysinger for (v = start; v < end; v += L1_CACHE_BYTES) { 127*17210643SMike Frysinger asm volatile ("ocbi %0" : /* no output */ 128*17210643SMike Frysinger : "m" (__m(v))); 129*17210643SMike Frysinger } 130*17210643SMike Frysinger } 131