On Wednesday, August 10, 2011 04:49:25 AM Hong Xu wrote: > After DMA operation, we need to maintain D-Cache coherency. > So that the DCache must be invalidated (hence CPU will fetch > data written by DMA controller from RAM). > > Tested on AT91SAM9261EK with Peripheral DMA controller.
Hi Hong, one more thing, not that I want to disappoint you. Try to take a look at arch/arm/cpu/armv7/cache_v7.c Maybe we should do the same for arm926ejs -- have arch/arm/cpu/arm926ejs/cache.c -- containing arm926ejs specific cache management functions. That way, arch/arm/lib/cache.c won't become mess. What do you think ? > > Signed-off-by: Hong Xu <hong...@atmel.com> > Tested-by: Elen Song <elen.s...@atmel.com> > CC: Albert Aribaud <albert.u.b...@aribaud.net> > CC: Aneesh V <ane...@ti.com> > CC: Marek Vasut <marek.va...@gmail.com> > CC: Reinhard Meyer <u-b...@emk-elektronik.de> > CC: Heiko Schocher <h...@denx.de> > --- > V2: > Per Albert's suggestion, add invalidate_dcache_range > > V3: > invalidate_dcache_range emits warning when detecting unaligned buffer > > invalidate_dcache_range won't clean any adjacent cache line when > detecting unaligned buffer and only round up/down the buffer address > > v4: > invalidate_dcache_range will emit clearer warning message > > Per Albert's suggestion, if not alighed to cache line size, round up > start address, round down stop addres > > Per Marek Vasut's suggestion, use __func__ stated in C99 > > arch/arm/lib/cache.c | 58 > ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 58 > insertions(+), 0 deletions(-) > > diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c > index 92b61a2..4c8e160 100644 > --- a/arch/arm/lib/cache.c > +++ b/arch/arm/lib/cache.c > @@ -53,3 +53,61 @@ void __flush_dcache_all(void) > } > void flush_dcache_all(void) > __attribute__((weak, alias("__flush_dcache_all"))); > + > +/* > + * The buffer range to be invalidated is [start, stop) > + */ > +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 > + /* > + * ARM926EJ-S Technical Reference Manual, Chap 2.3.1 Table 2-9 > + * only b'10, aka. 32 bytes cache line len is valid > + */ > + cache_line_len = 32; > +#endif > + mva = start; > + if ((mva & (cache_line_len - 1)) != 0) { > + printf("WARNING: %s - start address 0x%08x not aligned to" > + "cache line size(%d bytes)\n", __func__, start, > + cache_line_len); > + /* Round up starting address */ > + mva = (mva | (cache_line_len - 1)) + 1; > + } > + if ((stop & (cache_line_len - 1)) != 0) { > + printf("WARNING: %s - stop address 0x%08x not aligned to" > + "cache line size(%d bytes)\n", __func__, stop, > + cache_line_len); > + /* Round down ending address */ > + stop &= ~(cache_line_len - 1); > + } > + > + while (mva < stop) { > + asm("mcr p15, 0, %0, c7, c6, 1" : : "r"(mva)); > + mva += cache_line_len; > + } > + > + /* Drain the WB */ > + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); > +#endif > + > + return; > +} > +void invalidate_dcache_range(unsigned long start, unsigned long stop) > + __attribute__((weak, alias("__invalidate_dcache_range"))); > + > +void __invalidate_dcache_all(void) > +{ > +#ifdef CONFIG_ARM926EJS > + asm("mcr p15, 0, %0, c7, c6, 0" : : "r" (0)); > +#endif > + return; > +} > +void invalidate_dcache_all(void) > + __attribute__((weak, alias("__invalidate_dcache_all"))); _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot