1/* 2 * linux/arch/arm/mm/cache-fa.S 3 * 4 * Copyright (C) 2005 Faraday Corp. 5 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> 6 * 7 * Based on cache-v4wb.S: 8 * Copyright (C) 1997-2002 Russell king 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * Processors: FA520 FA526 FA626 15 */ 16#include <linux/linkage.h> 17#include <linux/init.h> 18#include <asm/memory.h> 19#include <asm/page.h> 20 21#include "proc-macros.S" 22 23/* 24 * The size of one data cache line. 25 */ 26#define CACHE_DLINESIZE 16 27 28/* 29 * The total size of the data cache. 30 */ 31#ifdef CONFIG_ARCH_GEMINI 32#define CACHE_DSIZE 8192 33#else 34#define CACHE_DSIZE 16384 35#endif 36 37/* FIXME: put optimal value here. Current one is just estimation */ 38#define CACHE_DLIMIT (CACHE_DSIZE * 2) 39 40/* 41 * flush_user_cache_all() 42 * 43 * Clean and invalidate all cache entries in a particular address 44 * space. 45 */ 46ENTRY(fa_flush_user_cache_all) 47 /* FALLTHROUGH */ 48/* 49 * flush_kern_cache_all() 50 * 51 * Clean and invalidate the entire cache. 52 */ 53ENTRY(fa_flush_kern_cache_all) 54 mov ip, #0 55 mov r2, #VM_EXEC 56__flush_whole_cache: 57 mcr p15, 0, ip, c7, c14, 0 @ clean/invalidate D cache 58 tst r2, #VM_EXEC 59 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache 60 mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB 61 mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer 62 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush 63 mov pc, lr 64 65/* 66 * flush_user_cache_range(start, end, flags) 67 * 68 * Invalidate a range of cache entries in the specified 69 * address space. 70 * 71 * - start - start address (inclusive, page aligned) 72 * - end - end address (exclusive, page aligned) 73 * - flags - vma_area_struct flags describing address space 74 */ 75ENTRY(fa_flush_user_cache_range) 76 mov ip, #0 77 sub r3, r1, r0 @ calculate total size 78 cmp r3, #CACHE_DLIMIT @ total size >= limit? 79 bhs __flush_whole_cache @ flush whole D cache 80 811: tst r2, #VM_EXEC 82 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I line 83 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry 84 add r0, r0, #CACHE_DLINESIZE 85 cmp r0, r1 86 blo 1b 87 tst r2, #VM_EXEC 88 mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB 89 mcrne p15, 0, ip, c7, c10, 4 @ data write barrier 90 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush 91 mov pc, lr 92 93/* 94 * coherent_kern_range(start, end) 95 * 96 * Ensure coherency between the Icache and the Dcache in the 97 * region described by start. If you have non-snooping 98 * Harvard caches, you need to implement this function. 99 * 100 * - start - virtual start address 101 * - end - virtual end address 102 */ 103ENTRY(fa_coherent_kern_range) 104 /* fall through */ 105 106/* 107 * coherent_user_range(start, end) 108 * 109 * Ensure coherency between the Icache and the Dcache in the 110 * region described by start. If you have non-snooping 111 * Harvard caches, you need to implement this function. 112 * 113 * - start - virtual start address 114 * - end - virtual end address 115 */ 116ENTRY(fa_coherent_user_range) 117 bic r0, r0, #CACHE_DLINESIZE - 1 1181: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry 119 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry 120 add r0, r0, #CACHE_DLINESIZE 121 cmp r0, r1 122 blo 1b 123 mov r0, #0 124 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB 125 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 126 mcr p15, 0, r0, c7, c5, 4 @ prefetch flush 127 mov pc, lr 128 129/* 130 * flush_kern_dcache_area(void *addr, size_t size) 131 * 132 * Ensure that the data held in the page kaddr is written back 133 * to the page in question. 134 * 135 * - addr - kernel address 136 * - size - size of region 137 */ 138ENTRY(fa_flush_kern_dcache_area) 139 add r1, r0, r1 1401: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line 141 add r0, r0, #CACHE_DLINESIZE 142 cmp r0, r1 143 blo 1b 144 mov r0, #0 145 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache 146 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 147 mov pc, lr 148 149/* 150 * dma_inv_range(start, end) 151 * 152 * Invalidate (discard) the specified virtual address range. 153 * May not write back any entries. If 'start' or 'end' 154 * are not cache line aligned, those lines must be written 155 * back. 156 * 157 * - start - virtual start address 158 * - end - virtual end address 159 */ 160ENTRY(fa_dma_inv_range) 161 tst r0, #CACHE_DLINESIZE - 1 162 bic r0, r0, #CACHE_DLINESIZE - 1 163 mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry 164 tst r1, #CACHE_DLINESIZE - 1 165 bic r1, r1, #CACHE_DLINESIZE - 1 166 mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D entry 1671: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry 168 add r0, r0, #CACHE_DLINESIZE 169 cmp r0, r1 170 blo 1b 171 mov r0, #0 172 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 173 mov pc, lr 174 175/* 176 * dma_clean_range(start, end) 177 * 178 * Clean (write back) the specified virtual address range. 179 * 180 * - start - virtual start address 181 * - end - virtual end address 182 */ 183ENTRY(fa_dma_clean_range) 184 bic r0, r0, #CACHE_DLINESIZE - 1 1851: mcr p15, 0, r0, c7, c10, 1 @ clean D entry 186 add r0, r0, #CACHE_DLINESIZE 187 cmp r0, r1 188 blo 1b 189 mov r0, #0 190 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 191 mov pc, lr 192 193/* 194 * dma_flush_range(start,end) 195 * - start - virtual start address of region 196 * - end - virtual end address of region 197 */ 198ENTRY(fa_dma_flush_range) 199 bic r0, r0, #CACHE_DLINESIZE - 1 2001: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry 201 add r0, r0, #CACHE_DLINESIZE 202 cmp r0, r1 203 blo 1b 204 mov r0, #0 205 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 206 mov pc, lr 207 208 __INITDATA 209 210 .type fa_cache_fns, #object 211ENTRY(fa_cache_fns) 212 .long fa_flush_kern_cache_all 213 .long fa_flush_user_cache_all 214 .long fa_flush_user_cache_range 215 .long fa_coherent_kern_range 216 .long fa_coherent_user_range 217 .long fa_flush_kern_dcache_area 218 .long fa_dma_inv_range 219 .long fa_dma_clean_range 220 .long fa_dma_flush_range 221 .size fa_cache_fns, . - fa_cache_fns 222