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