CRISv32: add cache flush operations
These are needed due to a cache bug, and can be used to make sure that the DMA descriptors are flushed to memory and can be safely handled by DMA. flush_dma_descr - Flush one DMA descriptor. flush_dma_list - Flush a complete list of DMA descriptors. cris_flush_cache - Flush the complete cache. cris_flush_cache_range - Flush only the specified range Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
d8e5219f9f
commit
57c230a873
33
arch/cris/arch-v32/kernel/cache.c
Normal file
33
arch/cris/arch-v32/kernel/cache.c
Normal file
|
@ -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);
|
94
arch/cris/arch-v32/kernel/cacheflush.S
Normal file
94
arch/cris/arch-v32/kernel/cacheflush.S
Normal file
|
@ -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
|
Loading…
Reference in a new issue