18f0fec74SPeter Tyser /* 28f0fec74SPeter Tyser * (C) Copyright 2007 38f0fec74SPeter Tyser * Nobuhiro Iwamatsu <iwamatsu@nigauri.org> 48f0fec74SPeter Tyser * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 68f0fec74SPeter Tyser */ 78f0fec74SPeter Tyser 88f0fec74SPeter Tyser #include <common.h> 98f0fec74SPeter Tyser #include <command.h> 108f0fec74SPeter Tyser #include <asm/processor.h> 118f0fec74SPeter Tyser #include <asm/io.h> 128f0fec74SPeter Tyser 138f0fec74SPeter Tyser /* 148f0fec74SPeter Tyser * Jump to P2 area. 158f0fec74SPeter Tyser * When handling TLB or caches, we need to do it from P2 area. 168f0fec74SPeter Tyser */ 178f0fec74SPeter Tyser #define jump_to_P2() \ 188f0fec74SPeter Tyser do { \ 198f0fec74SPeter Tyser unsigned long __dummy; \ 208f0fec74SPeter Tyser __asm__ __volatile__( \ 218f0fec74SPeter Tyser "mov.l 1f, %0\n\t" \ 228f0fec74SPeter Tyser "or %1, %0\n\t" \ 238f0fec74SPeter Tyser "jmp @%0\n\t" \ 248f0fec74SPeter Tyser " nop\n\t" \ 258f0fec74SPeter Tyser ".balign 4\n" \ 268f0fec74SPeter Tyser "1: .long 2f\n" \ 278f0fec74SPeter Tyser "2:" \ 288f0fec74SPeter Tyser : "=&r" (__dummy) \ 298f0fec74SPeter Tyser : "r" (0x20000000)); \ 308f0fec74SPeter Tyser } while (0) 318f0fec74SPeter Tyser 328f0fec74SPeter Tyser /* 338f0fec74SPeter Tyser * Back to P1 area. 348f0fec74SPeter Tyser */ 358f0fec74SPeter Tyser #define back_to_P1() \ 368f0fec74SPeter Tyser do { \ 378f0fec74SPeter Tyser unsigned long __dummy; \ 388f0fec74SPeter Tyser __asm__ __volatile__( \ 398f0fec74SPeter Tyser "nop;nop;nop;nop;nop;nop;nop\n\t" \ 408f0fec74SPeter Tyser "mov.l 1f, %0\n\t" \ 418f0fec74SPeter Tyser "jmp @%0\n\t" \ 428f0fec74SPeter Tyser " nop\n\t" \ 438f0fec74SPeter Tyser ".balign 4\n" \ 448f0fec74SPeter Tyser "1: .long 2f\n" \ 458f0fec74SPeter Tyser "2:" \ 468f0fec74SPeter Tyser : "=&r" (__dummy)); \ 478f0fec74SPeter Tyser } while (0) 488f0fec74SPeter Tyser 498f0fec74SPeter Tyser #define CACHE_VALID 1 508f0fec74SPeter Tyser #define CACHE_UPDATED 2 518f0fec74SPeter Tyser 528f0fec74SPeter Tyser static inline void cache_wback_all(void) 538f0fec74SPeter Tyser { 548f0fec74SPeter Tyser unsigned long addr, data, i, j; 558f0fec74SPeter Tyser 568f0fec74SPeter Tyser jump_to_P2(); 578f0fec74SPeter Tyser for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++){ 588f0fec74SPeter Tyser for (j = 0; j < CACHE_OC_NUM_WAYS; j++) { 598f0fec74SPeter Tyser addr = CACHE_OC_ADDRESS_ARRAY | (j << CACHE_OC_WAY_SHIFT) 608f0fec74SPeter Tyser | (i << CACHE_OC_ENTRY_SHIFT); 618f0fec74SPeter Tyser data = inl(addr); 628f0fec74SPeter Tyser if (data & CACHE_UPDATED) { 638f0fec74SPeter Tyser data &= ~CACHE_UPDATED; 648f0fec74SPeter Tyser outl(data, addr); 658f0fec74SPeter Tyser } 668f0fec74SPeter Tyser } 678f0fec74SPeter Tyser } 688f0fec74SPeter Tyser back_to_P1(); 698f0fec74SPeter Tyser } 708f0fec74SPeter Tyser 718f0fec74SPeter Tyser 728f0fec74SPeter Tyser #define CACHE_ENABLE 0 738f0fec74SPeter Tyser #define CACHE_DISABLE 1 748f0fec74SPeter Tyser 758f0fec74SPeter Tyser int cache_control(unsigned int cmd) 768f0fec74SPeter Tyser { 778f0fec74SPeter Tyser unsigned long ccr; 788f0fec74SPeter Tyser 798f0fec74SPeter Tyser jump_to_P2(); 808f0fec74SPeter Tyser ccr = inl(CCR); 818f0fec74SPeter Tyser 828f0fec74SPeter Tyser if (ccr & CCR_CACHE_ENABLE) 838f0fec74SPeter Tyser cache_wback_all(); 848f0fec74SPeter Tyser 858f0fec74SPeter Tyser if (cmd == CACHE_DISABLE) 868f0fec74SPeter Tyser outl(CCR_CACHE_STOP, CCR); 878f0fec74SPeter Tyser else 888f0fec74SPeter Tyser outl(CCR_CACHE_INIT, CCR); 898f0fec74SPeter Tyser back_to_P1(); 908f0fec74SPeter Tyser 918f0fec74SPeter Tyser return 0; 928f0fec74SPeter Tyser } 9317210643SMike Frysinger 94a633a18fSNobuhiro Iwamatsu void flush_dcache_range(unsigned long start, unsigned long end) 9517210643SMike Frysinger { 9617210643SMike Frysinger u32 v; 9717210643SMike Frysinger 9817210643SMike Frysinger start &= ~(L1_CACHE_BYTES - 1); 9917210643SMike Frysinger for (v = start; v < end; v += L1_CACHE_BYTES) { 100*ee47c4cbSVladimir Zapolskiy asm volatile ("ocbp %0" : /* no output */ 10117210643SMike Frysinger : "m" (__m(v))); 10217210643SMike Frysinger } 10317210643SMike Frysinger } 10417210643SMike Frysinger 105a633a18fSNobuhiro Iwamatsu void invalidate_dcache_range(unsigned long start, unsigned long end) 10617210643SMike Frysinger { 10717210643SMike Frysinger u32 v; 10817210643SMike Frysinger 10917210643SMike Frysinger start &= ~(L1_CACHE_BYTES - 1); 11017210643SMike Frysinger for (v = start; v < end; v += L1_CACHE_BYTES) { 11117210643SMike Frysinger asm volatile ("ocbi %0" : /* no output */ 11217210643SMike Frysinger : "m" (__m(v))); 11317210643SMike Frysinger } 11417210643SMike Frysinger } 115