18d732840SMacpaul Lin /* 28d732840SMacpaul Lin * Copyright (C) 2012 Andes Technology Corporation 38d732840SMacpaul Lin * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> 48d732840SMacpaul Lin * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> 58d732840SMacpaul Lin * 6*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 78d732840SMacpaul Lin */ 88d732840SMacpaul Lin 98d732840SMacpaul Lin #include <common.h> 108d732840SMacpaul Lin 118d732840SMacpaul Lin static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache) 128d732840SMacpaul Lin { 138d732840SMacpaul Lin if (cache == ICACHE) 148d732840SMacpaul Lin return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \ 158d732840SMacpaul Lin >> ICM_CFG_OFF_ISZ) - 1); 168d732840SMacpaul Lin else 178d732840SMacpaul Lin return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \ 188d732840SMacpaul Lin >> DCM_CFG_OFF_DSZ) - 1); 198d732840SMacpaul Lin } 208d732840SMacpaul Lin 218d732840SMacpaul Lin void flush_dcache_range(unsigned long start, unsigned long end) 228d732840SMacpaul Lin { 238d732840SMacpaul Lin unsigned long line_size; 248d732840SMacpaul Lin 258d732840SMacpaul Lin line_size = CACHE_LINE_SIZE(DCACHE); 268d732840SMacpaul Lin 278d732840SMacpaul Lin while (end > start) { 288d732840SMacpaul Lin asm volatile ( 298d732840SMacpaul Lin "\n\tcctl %0, L1D_VA_WB" 308d732840SMacpaul Lin "\n\tcctl %0, L1D_VA_INVAL" 318d732840SMacpaul Lin : 328d732840SMacpaul Lin : "r" (start) 338d732840SMacpaul Lin ); 348d732840SMacpaul Lin start += line_size; 358d732840SMacpaul Lin } 368d732840SMacpaul Lin } 378d732840SMacpaul Lin 388d732840SMacpaul Lin void invalidate_icache_range(unsigned long start, unsigned long end) 398d732840SMacpaul Lin { 408d732840SMacpaul Lin unsigned long line_size; 418d732840SMacpaul Lin 428d732840SMacpaul Lin line_size = CACHE_LINE_SIZE(ICACHE); 438d732840SMacpaul Lin while (end > start) { 448d732840SMacpaul Lin asm volatile ( 458d732840SMacpaul Lin "\n\tcctl %0, L1I_VA_INVAL" 468d732840SMacpaul Lin : 478d732840SMacpaul Lin : "r"(start) 488d732840SMacpaul Lin ); 498d732840SMacpaul Lin start += line_size; 508d732840SMacpaul Lin } 518d732840SMacpaul Lin } 528d732840SMacpaul Lin 538d732840SMacpaul Lin void invalidate_dcache_range(unsigned long start, unsigned long end) 548d732840SMacpaul Lin { 558d732840SMacpaul Lin unsigned long line_size; 568d732840SMacpaul Lin 578d732840SMacpaul Lin line_size = CACHE_LINE_SIZE(DCACHE); 588d732840SMacpaul Lin while (end > start) { 598d732840SMacpaul Lin asm volatile ( 608d732840SMacpaul Lin "\n\tcctl %0, L1D_VA_INVAL" 618d732840SMacpaul Lin : 628d732840SMacpaul Lin : "r"(start) 638d732840SMacpaul Lin ); 648d732840SMacpaul Lin start += line_size; 658d732840SMacpaul Lin } 668d732840SMacpaul Lin } 678d732840SMacpaul Lin 688d732840SMacpaul Lin void flush_cache(unsigned long addr, unsigned long size) 698d732840SMacpaul Lin { 708d732840SMacpaul Lin flush_dcache_range(addr, addr + size); 718d732840SMacpaul Lin invalidate_icache_range(addr, addr + size); 728d732840SMacpaul Lin } 738d732840SMacpaul Lin 748d732840SMacpaul Lin void icache_enable(void) 758d732840SMacpaul Lin { 768d732840SMacpaul Lin asm volatile ( 778d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 788d732840SMacpaul Lin "ori $p0, $p0, 0x01\n\t" 798d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 808d732840SMacpaul Lin "isb\n\t" 818d732840SMacpaul Lin ); 828d732840SMacpaul Lin } 838d732840SMacpaul Lin 848d732840SMacpaul Lin void icache_disable(void) 858d732840SMacpaul Lin { 868d732840SMacpaul Lin asm volatile ( 878d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 888d732840SMacpaul Lin "li $p1, ~0x01\n\t" 898d732840SMacpaul Lin "and $p0, $p0, $p1\n\t" 908d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 918d732840SMacpaul Lin "isb\n\t" 928d732840SMacpaul Lin ); 938d732840SMacpaul Lin } 948d732840SMacpaul Lin 958d732840SMacpaul Lin int icache_status(void) 968d732840SMacpaul Lin { 978d732840SMacpaul Lin int ret; 988d732840SMacpaul Lin 998d732840SMacpaul Lin asm volatile ( 1008d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 1018d732840SMacpaul Lin "andi %0, $p0, 0x01\n\t" 1028d732840SMacpaul Lin : "=r" (ret) 1038d732840SMacpaul Lin : 1048d732840SMacpaul Lin : "memory" 1058d732840SMacpaul Lin ); 1068d732840SMacpaul Lin 1078d732840SMacpaul Lin return ret; 1088d732840SMacpaul Lin } 1098d732840SMacpaul Lin 1108d732840SMacpaul Lin void dcache_enable(void) 1118d732840SMacpaul Lin { 1128d732840SMacpaul Lin asm volatile ( 1138d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 1148d732840SMacpaul Lin "ori $p0, $p0, 0x02\n\t" 1158d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 1168d732840SMacpaul Lin "isb\n\t" 1178d732840SMacpaul Lin ); 1188d732840SMacpaul Lin } 1198d732840SMacpaul Lin 1208d732840SMacpaul Lin void dcache_disable(void) 1218d732840SMacpaul Lin { 1228d732840SMacpaul Lin asm volatile ( 1238d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 1248d732840SMacpaul Lin "li $p1, ~0x02\n\t" 1258d732840SMacpaul Lin "and $p0, $p0, $p1\n\t" 1268d732840SMacpaul Lin "mtsr $p0, $mr8\n\t" 1278d732840SMacpaul Lin "isb\n\t" 1288d732840SMacpaul Lin ); 1298d732840SMacpaul Lin } 1308d732840SMacpaul Lin 1318d732840SMacpaul Lin int dcache_status(void) 1328d732840SMacpaul Lin { 1338d732840SMacpaul Lin int ret; 1348d732840SMacpaul Lin 1358d732840SMacpaul Lin asm volatile ( 1368d732840SMacpaul Lin "mfsr $p0, $mr8\n\t" 1378d732840SMacpaul Lin "andi %0, $p0, 0x02\n\t" 1388d732840SMacpaul Lin : "=r" (ret) 1398d732840SMacpaul Lin : 1408d732840SMacpaul Lin : "memory" 1418d732840SMacpaul Lin ); 1428d732840SMacpaul Lin 1438d732840SMacpaul Lin return ret; 1448d732840SMacpaul Lin } 145