1*8d732840SMacpaul Lin /* 2*8d732840SMacpaul Lin * Copyright (C) 2012 Andes Technology Corporation 3*8d732840SMacpaul Lin * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> 4*8d732840SMacpaul Lin * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> 5*8d732840SMacpaul Lin * 6*8d732840SMacpaul Lin * This program is free software; you can redistribute it and/or modify 7*8d732840SMacpaul Lin * it under the terms of the GNU General Public License as published by 8*8d732840SMacpaul Lin * the Free Software Foundation; either version 2 of the License, or 9*8d732840SMacpaul Lin * (at your option) any later version. 10*8d732840SMacpaul Lin * 11*8d732840SMacpaul Lin * This program is distributed in the hope that it will be useful, 12*8d732840SMacpaul Lin * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*8d732840SMacpaul Lin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*8d732840SMacpaul Lin * GNU General Public License for more details. 15*8d732840SMacpaul Lin * 16*8d732840SMacpaul Lin * You should have received a copy of the GNU General Public License 17*8d732840SMacpaul Lin * along with this program; if not, write to the Free Software 18*8d732840SMacpaul Lin * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19*8d732840SMacpaul Lin * 20*8d732840SMacpaul Lin */ 21*8d732840SMacpaul Lin 22*8d732840SMacpaul Lin #include <common.h> 23*8d732840SMacpaul Lin 24*8d732840SMacpaul Lin static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache) 25*8d732840SMacpaul Lin { 26*8d732840SMacpaul Lin if (cache == ICACHE) 27*8d732840SMacpaul Lin return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \ 28*8d732840SMacpaul Lin >> ICM_CFG_OFF_ISZ) - 1); 29*8d732840SMacpaul Lin else 30*8d732840SMacpaul Lin return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \ 31*8d732840SMacpaul Lin >> DCM_CFG_OFF_DSZ) - 1); 32*8d732840SMacpaul Lin } 33*8d732840SMacpaul Lin 34*8d732840SMacpaul Lin void flush_dcache_range(unsigned long start, unsigned long end) 35*8d732840SMacpaul Lin { 36*8d732840SMacpaul Lin unsigned long line_size; 37*8d732840SMacpaul Lin 38*8d732840SMacpaul Lin line_size = CACHE_LINE_SIZE(DCACHE); 39*8d732840SMacpaul Lin 40*8d732840SMacpaul Lin while (end > start) { 41*8d732840SMacpaul Lin asm volatile ( 42*8d732840SMacpaul Lin "\n\tcctl %0, L1D_VA_WB" 43*8d732840SMacpaul Lin "\n\tcctl %0, L1D_VA_INVAL" 44*8d732840SMacpaul Lin : 45*8d732840SMacpaul Lin : "r" (start) 46*8d732840SMacpaul Lin ); 47*8d732840SMacpaul Lin start += line_size; 48*8d732840SMacpaul Lin } 49*8d732840SMacpaul Lin } 50*8d732840SMacpaul Lin 51*8d732840SMacpaul Lin void invalidate_icache_range(unsigned long start, unsigned long end) 52*8d732840SMacpaul Lin { 53*8d732840SMacpaul Lin unsigned long line_size; 54*8d732840SMacpaul Lin 55*8d732840SMacpaul Lin line_size = CACHE_LINE_SIZE(ICACHE); 56*8d732840SMacpaul Lin while (end > start) { 57*8d732840SMacpaul Lin asm volatile ( 58*8d732840SMacpaul Lin "\n\tcctl %0, L1I_VA_INVAL" 59*8d732840SMacpaul Lin : 60*8d732840SMacpaul Lin : "r"(start) 61*8d732840SMacpaul Lin ); 62*8d732840SMacpaul Lin start += line_size; 63*8d732840SMacpaul Lin } 64*8d732840SMacpaul Lin } 65*8d732840SMacpaul Lin 66*8d732840SMacpaul Lin void invalidate_dcache_range(unsigned long start, unsigned long end) 67*8d732840SMacpaul Lin { 68*8d732840SMacpaul Lin unsigned long line_size; 69*8d732840SMacpaul Lin 70*8d732840SMacpaul Lin line_size = CACHE_LINE_SIZE(DCACHE); 71*8d732840SMacpaul Lin while (end > start) { 72*8d732840SMacpaul Lin asm volatile ( 73*8d732840SMacpaul Lin "\n\tcctl %0, L1D_VA_INVAL" 74*8d732840SMacpaul Lin : 75*8d732840SMacpaul Lin : "r"(start) 76*8d732840SMacpaul Lin ); 77*8d732840SMacpaul Lin start += line_size; 78*8d732840SMacpaul Lin } 79*8d732840SMacpaul Lin } 80*8d732840SMacpaul Lin 81*8d732840SMacpaul Lin void flush_cache(unsigned long addr, unsigned long size) 82*8d732840SMacpaul Lin { 83*8d732840SMacpaul Lin flush_dcache_range(addr, addr + size); 84*8d732840SMacpaul Lin invalidate_icache_range(addr, addr + size); 85*8d732840SMacpaul Lin } 86*8d732840SMacpaul Lin 87*8d732840SMacpaul Lin void icache_enable(void) 88*8d732840SMacpaul Lin { 89*8d732840SMacpaul Lin asm volatile ( 90*8d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 91*8d732840SMacpaul Lin "ori $p0, $p0, 0x01\n\t" 92*8d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 93*8d732840SMacpaul Lin "isb\n\t" 94*8d732840SMacpaul Lin ); 95*8d732840SMacpaul Lin } 96*8d732840SMacpaul Lin 97*8d732840SMacpaul Lin void icache_disable(void) 98*8d732840SMacpaul Lin { 99*8d732840SMacpaul Lin asm volatile ( 100*8d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 101*8d732840SMacpaul Lin "li $p1, ~0x01\n\t" 102*8d732840SMacpaul Lin "and $p0, $p0, $p1\n\t" 103*8d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 104*8d732840SMacpaul Lin "isb\n\t" 105*8d732840SMacpaul Lin ); 106*8d732840SMacpaul Lin } 107*8d732840SMacpaul Lin 108*8d732840SMacpaul Lin int icache_status(void) 109*8d732840SMacpaul Lin { 110*8d732840SMacpaul Lin int ret; 111*8d732840SMacpaul Lin 112*8d732840SMacpaul Lin asm volatile ( 113*8d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 114*8d732840SMacpaul Lin "andi %0, $p0, 0x01\n\t" 115*8d732840SMacpaul Lin : "=r" (ret) 116*8d732840SMacpaul Lin : 117*8d732840SMacpaul Lin : "memory" 118*8d732840SMacpaul Lin ); 119*8d732840SMacpaul Lin 120*8d732840SMacpaul Lin return ret; 121*8d732840SMacpaul Lin } 122*8d732840SMacpaul Lin 123*8d732840SMacpaul Lin void dcache_enable(void) 124*8d732840SMacpaul Lin { 125*8d732840SMacpaul Lin asm volatile ( 126*8d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 127*8d732840SMacpaul Lin "ori $p0, $p0, 0x02\n\t" 128*8d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 129*8d732840SMacpaul Lin "isb\n\t" 130*8d732840SMacpaul Lin ); 131*8d732840SMacpaul Lin } 132*8d732840SMacpaul Lin 133*8d732840SMacpaul Lin void dcache_disable(void) 134*8d732840SMacpaul Lin { 135*8d732840SMacpaul Lin asm volatile ( 136*8d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 137*8d732840SMacpaul Lin "li $p1, ~0x02\n\t" 138*8d732840SMacpaul Lin "and $p0, $p0, $p1\n\t" 139*8d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 140*8d732840SMacpaul Lin "isb\n\t" 141*8d732840SMacpaul Lin ); 142*8d732840SMacpaul Lin } 143*8d732840SMacpaul Lin 144*8d732840SMacpaul Lin int dcache_status(void) 145*8d732840SMacpaul Lin { 146*8d732840SMacpaul Lin int ret; 147*8d732840SMacpaul Lin 148*8d732840SMacpaul Lin asm volatile ( 149*8d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 150*8d732840SMacpaul Lin "andi %0, $p0, 0x02\n\t" 151*8d732840SMacpaul Lin : "=r" (ret) 152*8d732840SMacpaul Lin : 153*8d732840SMacpaul Lin : "memory" 154*8d732840SMacpaul Lin ); 155*8d732840SMacpaul Lin 156*8d732840SMacpaul Lin return ret; 157*8d732840SMacpaul Lin } 158