12f3427ccSIlya Yanok /* 22f3427ccSIlya Yanok * (C) Copyright 2011 32f3427ccSIlya Yanok * Ilya Yanok, EmCraft Systems 42f3427ccSIlya Yanok * 52f3427ccSIlya Yanok * See file CREDITS for list of people who contributed to this 62f3427ccSIlya Yanok * project. 72f3427ccSIlya Yanok * 82f3427ccSIlya Yanok * This program is free software; you can redistribute it and/or 92f3427ccSIlya Yanok * modify it under the terms of the GNU General Public License as 102f3427ccSIlya Yanok * published by the Free Software Foundation; either version 2 of 112f3427ccSIlya Yanok * the License, or (at your option) any later version. 122f3427ccSIlya Yanok * 132f3427ccSIlya Yanok * This program is distributed in the hope that it will be useful, 142f3427ccSIlya Yanok * but WITHOUT ANY WARRANTY; without even the implied warranty of 152f3427ccSIlya Yanok * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 162f3427ccSIlya Yanok * GNU General Public License for more details. 172f3427ccSIlya Yanok * 182f3427ccSIlya Yanok * You should have received a copy of the GNU General Public License 192f3427ccSIlya Yanok * along with this program; if not, write to the Free Software 202f3427ccSIlya Yanok * Foundation, Inc. 212f3427ccSIlya Yanok */ 222f3427ccSIlya Yanok #include <linux/types.h> 232f3427ccSIlya Yanok #include <common.h> 242f3427ccSIlya Yanok 252f3427ccSIlya Yanok #ifndef CONFIG_SYS_DCACHE_OFF 26a4aaad70SMarek Vasut 27a4aaad70SMarek Vasut #ifndef CONFIG_SYS_CACHELINE_SIZE 28a4aaad70SMarek Vasut #define CONFIG_SYS_CACHELINE_SIZE 32 29a4aaad70SMarek Vasut #endif 302f3427ccSIlya Yanok 312f3427ccSIlya Yanok void invalidate_dcache_all(void) 322f3427ccSIlya Yanok { 33a4aaad70SMarek Vasut asm volatile("mcr p15, 0, %0, c7, c6, 0\n"::"r"(0)); 34a4aaad70SMarek Vasut } 35a4aaad70SMarek Vasut 36a4aaad70SMarek Vasut void flush_dcache_all(void) 37a4aaad70SMarek Vasut { 38a4aaad70SMarek Vasut asm volatile( 39a4aaad70SMarek Vasut "0:" 40a4aaad70SMarek Vasut "mrc p15, 0, r15, c7, c14, 3\n" 41a4aaad70SMarek Vasut "bne 0b\n" 42a4aaad70SMarek Vasut "mcr p15, 0, %0, c7, c10, 4\n" 43a4aaad70SMarek Vasut ::"r"(0):"memory" 44a4aaad70SMarek Vasut ); 45a4aaad70SMarek Vasut } 46a4aaad70SMarek Vasut 47a4aaad70SMarek Vasut static int check_cache_range(unsigned long start, unsigned long stop) 48a4aaad70SMarek Vasut { 49a4aaad70SMarek Vasut int ok = 1; 50a4aaad70SMarek Vasut 51a4aaad70SMarek Vasut if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) 52a4aaad70SMarek Vasut ok = 0; 53a4aaad70SMarek Vasut 54a4aaad70SMarek Vasut if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) 55a4aaad70SMarek Vasut ok = 0; 56a4aaad70SMarek Vasut 57a4aaad70SMarek Vasut if (!ok) 58*c8d9ceafSStefano Babic debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", 59a4aaad70SMarek Vasut start, stop); 60a4aaad70SMarek Vasut 61a4aaad70SMarek Vasut return ok; 622f3427ccSIlya Yanok } 632f3427ccSIlya Yanok 642f3427ccSIlya Yanok void invalidate_dcache_range(unsigned long start, unsigned long stop) 652f3427ccSIlya Yanok { 66a4aaad70SMarek Vasut if (!check_cache_range(start, stop)) 67a4aaad70SMarek Vasut return; 68a4aaad70SMarek Vasut 69a4aaad70SMarek Vasut while (start < stop) { 70a4aaad70SMarek Vasut asm volatile("mcr p15, 0, %0, c7, c6, 1\n"::"r"(start)); 71a4aaad70SMarek Vasut start += CONFIG_SYS_CACHELINE_SIZE; 72a4aaad70SMarek Vasut } 732f3427ccSIlya Yanok } 742f3427ccSIlya Yanok 752f3427ccSIlya Yanok void flush_dcache_range(unsigned long start, unsigned long stop) 762f3427ccSIlya Yanok { 77a4aaad70SMarek Vasut if (!check_cache_range(start, stop)) 78a4aaad70SMarek Vasut return; 79a4aaad70SMarek Vasut 80a4aaad70SMarek Vasut while (start < stop) { 81a4aaad70SMarek Vasut asm volatile("mcr p15, 0, %0, c7, c14, 1\n"::"r"(start)); 82a4aaad70SMarek Vasut start += CONFIG_SYS_CACHELINE_SIZE; 83a4aaad70SMarek Vasut } 84a4aaad70SMarek Vasut 85a4aaad70SMarek Vasut asm("mcr p15, 0, %0, c7, c10, 4\n"::"r"(0)); 86a4aaad70SMarek Vasut } 87a4aaad70SMarek Vasut 88a4aaad70SMarek Vasut void flush_cache(unsigned long start, unsigned long size) 89a4aaad70SMarek Vasut { 90a4aaad70SMarek Vasut flush_dcache_range(start, start + size); 912f3427ccSIlya Yanok } 922f3427ccSIlya Yanok #else /* #ifndef CONFIG_SYS_DCACHE_OFF */ 932f3427ccSIlya Yanok void invalidate_dcache_all(void) 942f3427ccSIlya Yanok { 952f3427ccSIlya Yanok } 962f3427ccSIlya Yanok 972f3427ccSIlya Yanok void flush_dcache_all(void) 982f3427ccSIlya Yanok { 992f3427ccSIlya Yanok } 1002f3427ccSIlya Yanok 1012f3427ccSIlya Yanok void invalidate_dcache_range(unsigned long start, unsigned long stop) 1022f3427ccSIlya Yanok { 1032f3427ccSIlya Yanok } 1042f3427ccSIlya Yanok 1052f3427ccSIlya Yanok void flush_dcache_range(unsigned long start, unsigned long stop) 1062f3427ccSIlya Yanok { 1072f3427ccSIlya Yanok } 1082f3427ccSIlya Yanok 1092f3427ccSIlya Yanok void flush_cache(unsigned long start, unsigned long size) 1102f3427ccSIlya Yanok { 1112f3427ccSIlya Yanok } 1122f3427ccSIlya Yanok #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ 11367953027SMichael Walle 11467953027SMichael Walle /* 11567953027SMichael Walle * Stub implementations for l2 cache operations 11667953027SMichael Walle */ 11767953027SMichael Walle void __l2_cache_disable(void) 11867953027SMichael Walle { 11967953027SMichael Walle } 12067953027SMichael Walle void l2_cache_disable(void) 12167953027SMichael Walle __attribute__((weak, alias("__l2_cache_disable"))); 122