1*93bc2193SAneesh V /* 2*93bc2193SAneesh V * (C) Copyright 2010 3*93bc2193SAneesh V * Texas Instruments, <www.ti.com> 4*93bc2193SAneesh V * Aneesh V <aneesh@ti.com> 5*93bc2193SAneesh V * 6*93bc2193SAneesh V * See file CREDITS for list of people who contributed to this 7*93bc2193SAneesh V * project. 8*93bc2193SAneesh V * 9*93bc2193SAneesh V * This program is free software; you can redistribute it and/or 10*93bc2193SAneesh V * modify it under the terms of the GNU General Public License as 11*93bc2193SAneesh V * published by the Free Software Foundation; either version 2 of 12*93bc2193SAneesh V * the License, or (at your option) any later version. 13*93bc2193SAneesh V * 14*93bc2193SAneesh V * This program is distributed in the hope that it will be useful, 15*93bc2193SAneesh V * but WITHOUT ANY WARRANTY; without even the implied warranty of 16*93bc2193SAneesh V * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17*93bc2193SAneesh V * GNU General Public License for more details. 18*93bc2193SAneesh V * 19*93bc2193SAneesh V * You should have received a copy of the GNU General Public License 20*93bc2193SAneesh V * along with this program; if not, write to the Free Software 21*93bc2193SAneesh V * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22*93bc2193SAneesh V * MA 02111-1307 USA 23*93bc2193SAneesh V */ 24*93bc2193SAneesh V #include <linux/types.h> 25*93bc2193SAneesh V #include <asm/io.h> 26*93bc2193SAneesh V #include <asm/armv7.h> 27*93bc2193SAneesh V #include <asm/pl310.h> 28*93bc2193SAneesh V #include <config.h> 29*93bc2193SAneesh V 30*93bc2193SAneesh V struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 31*93bc2193SAneesh V 32*93bc2193SAneesh V static void pl310_cache_sync(void) 33*93bc2193SAneesh V { 34*93bc2193SAneesh V writel(0, &pl310->pl310_cache_sync); 35*93bc2193SAneesh V } 36*93bc2193SAneesh V 37*93bc2193SAneesh V static void pl310_background_op_all_ways(u32 *op_reg) 38*93bc2193SAneesh V { 39*93bc2193SAneesh V u32 assoc_16, associativity, way_mask; 40*93bc2193SAneesh V 41*93bc2193SAneesh V assoc_16 = readl(&pl310->pl310_aux_ctrl) & 42*93bc2193SAneesh V PL310_AUX_CTRL_ASSOCIATIVITY_MASK; 43*93bc2193SAneesh V if (assoc_16) 44*93bc2193SAneesh V associativity = 16; 45*93bc2193SAneesh V else 46*93bc2193SAneesh V associativity = 8; 47*93bc2193SAneesh V 48*93bc2193SAneesh V way_mask = (1 << associativity) - 1; 49*93bc2193SAneesh V /* Invalidate all ways */ 50*93bc2193SAneesh V writel(way_mask, op_reg); 51*93bc2193SAneesh V /* Wait for all ways to be invalidated */ 52*93bc2193SAneesh V while (readl(op_reg) && way_mask) 53*93bc2193SAneesh V ; 54*93bc2193SAneesh V pl310_cache_sync(); 55*93bc2193SAneesh V } 56*93bc2193SAneesh V 57*93bc2193SAneesh V void v7_outer_cache_inval_all(void) 58*93bc2193SAneesh V { 59*93bc2193SAneesh V pl310_background_op_all_ways(&pl310->pl310_inv_way); 60*93bc2193SAneesh V } 61*93bc2193SAneesh V 62*93bc2193SAneesh V void v7_outer_cache_flush_all(void) 63*93bc2193SAneesh V { 64*93bc2193SAneesh V pl310_background_op_all_ways(&pl310->pl310_clean_inv_way); 65*93bc2193SAneesh V } 66*93bc2193SAneesh V 67*93bc2193SAneesh V /* Flush(clean invalidate) memory from start to stop-1 */ 68*93bc2193SAneesh V void v7_outer_cache_flush_range(u32 start, u32 stop) 69*93bc2193SAneesh V { 70*93bc2193SAneesh V /* PL310 currently supports only 32 bytes cache line */ 71*93bc2193SAneesh V u32 pa, line_size = 32; 72*93bc2193SAneesh V 73*93bc2193SAneesh V /* 74*93bc2193SAneesh V * Align to the beginning of cache-line - this ensures that 75*93bc2193SAneesh V * the first 5 bits are 0 as required by PL310 TRM 76*93bc2193SAneesh V */ 77*93bc2193SAneesh V start &= ~(line_size - 1); 78*93bc2193SAneesh V 79*93bc2193SAneesh V for (pa = start; pa < stop; pa = pa + line_size) 80*93bc2193SAneesh V writel(pa, &pl310->pl310_clean_inv_line_pa); 81*93bc2193SAneesh V 82*93bc2193SAneesh V pl310_cache_sync(); 83*93bc2193SAneesh V } 84*93bc2193SAneesh V 85*93bc2193SAneesh V /* invalidate memory from start to stop-1 */ 86*93bc2193SAneesh V void v7_outer_cache_inval_range(u32 start, u32 stop) 87*93bc2193SAneesh V { 88*93bc2193SAneesh V /* PL310 currently supports only 32 bytes cache line */ 89*93bc2193SAneesh V u32 pa, line_size = 32; 90*93bc2193SAneesh V 91*93bc2193SAneesh V /* 92*93bc2193SAneesh V * If start address is not aligned to cache-line flush the first 93*93bc2193SAneesh V * line to prevent affecting somebody else's buffer 94*93bc2193SAneesh V */ 95*93bc2193SAneesh V if (start & (line_size - 1)) { 96*93bc2193SAneesh V v7_outer_cache_flush_range(start, start + 1); 97*93bc2193SAneesh V /* move to next cache line */ 98*93bc2193SAneesh V start = (start + line_size - 1) & ~(line_size - 1); 99*93bc2193SAneesh V } 100*93bc2193SAneesh V 101*93bc2193SAneesh V /* 102*93bc2193SAneesh V * If stop address is not aligned to cache-line flush the last 103*93bc2193SAneesh V * line to prevent affecting somebody else's buffer 104*93bc2193SAneesh V */ 105*93bc2193SAneesh V if (stop & (line_size - 1)) { 106*93bc2193SAneesh V v7_outer_cache_flush_range(stop, stop + 1); 107*93bc2193SAneesh V /* align to the beginning of this cache line */ 108*93bc2193SAneesh V stop &= ~(line_size - 1); 109*93bc2193SAneesh V } 110*93bc2193SAneesh V 111*93bc2193SAneesh V for (pa = start; pa < stop; pa = pa + line_size) 112*93bc2193SAneesh V writel(pa, &pl310->pl310_inv_line_pa); 113*93bc2193SAneesh V 114*93bc2193SAneesh V pl310_cache_sync(); 115*93bc2193SAneesh V } 116