root/arch/arm/mm/cache-fa.S

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

/* [<][>][^][v][top][bottom][index][help] */