Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57c230a8 authored by Jesper Nilsson's avatar Jesper Nilsson Committed by Linus Torvalds
Browse files

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: default avatarJesper Nilsson <jesper.nilsson@axis.com>

Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d8e5219f
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
#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 −0
Original line number Diff line number Diff line
	.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