diff options
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/arch-v32/kernel/cache.c | 33 | ||||
-rw-r--r-- | arch/cris/arch-v32/kernel/cacheflush.S | 94 |
2 files changed, 127 insertions, 0 deletions
diff --git a/arch/cris/arch-v32/kernel/cache.c b/arch/cris/arch-v32/kernel/cache.c new file mode 100644 index 00000000000..80da7b88a72 --- /dev/null +++ b/arch/cris/arch-v32/kernel/cache.c @@ -0,0 +1,33 @@ +#include <linux/module.h> +#include <asm/io.h> +#include <asm/arch/cache.h> +#include <asm/arch/hwregs/dma.h> + +/* This file is used to workaround a cache bug, Guinness TR 106. */ + +inline void flush_dma_descr(struct dma_descr_data *descr, int flush_buf) +{ + /* Flush descriptor to make sure we get correct in_eop and after. */ + asm volatile ("ftagd [%0]" :: "r" (descr)); + /* Flush buffer pointed out by descriptor. */ + if (flush_buf) + cris_flush_cache_range(phys_to_virt((unsigned)descr->buf), + (unsigned)(descr->after - descr->buf)); +} +EXPORT_SYMBOL(flush_dma_descr); + +void flush_dma_list(struct dma_descr_data *descr) +{ + while (1) { + flush_dma_descr(descr, 1); + if (descr->eol) + break; + descr = phys_to_virt((unsigned)descr->next); + } +} +EXPORT_SYMBOL(flush_dma_list); + +/* From cacheflush.S */ +EXPORT_SYMBOL(cris_flush_cache); +/* From cacheflush.S */ +EXPORT_SYMBOL(cris_flush_cache_range); diff --git a/arch/cris/arch-v32/kernel/cacheflush.S b/arch/cris/arch-v32/kernel/cacheflush.S new file mode 100644 index 00000000000..956e8fb82f0 --- /dev/null +++ b/arch/cris/arch-v32/kernel/cacheflush.S @@ -0,0 +1,94 @@ + .global cris_flush_cache_range +cris_flush_cache_range: + move.d 1024, $r12 + cmp.d $r11, $r12 + bhi cris_flush_1KB + nop + add.d $r10, $r11 + ftagd [$r10] +cris_flush_last: + addq 32, $r10 + cmp.d $r11, $r10 + blt cris_flush_last + ftagd [$r10] + ret + nop +cris_flush_1KB: + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ftagd [$r10] + addq 32, $r10 + ba cris_flush_cache_range + sub.d $r12, $r11 + + .global cris_flush_cache +cris_flush_cache: + moveq 0, $r10 +cris_flush_line: + move.d 16*1024, $r11 + addq 16, $r10 + cmp.d $r10, $r11 + blt cris_flush_line + fidxd [$r10] + ret + nop |