Dear Hong Xu, > After DMA operation, we need to maintain D-Cache coherency. > We need to clean cache (write back the dirty lines) and then > make the cache invalidate as well(hence CPU will fetch data > written by DMA controller from RAM). > > Tested on AT91SAM9261EK with Peripheral DMA controller. > > Signed-off-by: Hong Xu<hong...@atmel.com> > Tested-by: Elen Song<elen.s...@atmel.com> > CC: Albert Aribaud<albert.arib...@free.fr> > CC: Heiko Schocher<h...@denx.de> > --- > Changes since v1 > ~ Per Albert's suggestion, add invalidate_dcache_range originally defined > in include/common.h > > arch/arm/lib/cache.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 46 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c > index 92b61a2..0436443 100644 > --- a/arch/arm/lib/cache.c > +++ b/arch/arm/lib/cache.c > @@ -53,3 +53,49 @@ void __flush_dcache_all(void) > } > void flush_dcache_all(void) > __attribute__((weak, alias("__flush_dcache_all"))); > + > +void __invalidate_dcache_range(unsigned long start, unsigned long stop) > +{ > + int cache_line_len; > + unsigned long mva; > + > +#ifdef CONFIG_ARM926EJS > + > +#ifdef CONFIG_SYS_CACHELINE_SIZE > + cache_line_len = CONFIG_SYS_CACHELINE_SIZE; > +#else > + cache_line_len = 32; > +#endif > + /* > + * If start and stop are not aligned to cache-line, > + * the adjacent lines will be cleaned > + */ > + if ((start& (cache_line_len - 1)) != 0) > + asm("mcr p15, 0, %0, c7, c10, 1" : : "r" (start)); > + if ((stop& (cache_line_len - 1)) != 0) > + asm("mcr p15, 0, %0, c7, c10, 1" : : "r" (stop));
Why so complicated? How about: /* round down to the start of the cache line */ start &= (cache_line_len - 1); /* round up to the end of the cache line */ note: if, what I assume, the range to be invalidated is [start, stop) - that means stop is the first address not to be invalidated, the next statement is not necessary stop |= (cache_line_len - 1); while (start < stop) { asm("mcr p15, 0, %0, c7, c6, 1" : : "r"(start)); start += cache_line_len; } /* Drain the WB */ asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); > +#endif Best Regards, Reinhard _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot