diff options
author | Anatolij Gustschin <agust@denx.de> | 2012-04-02 06:18:00 +0000 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2012-04-16 14:53:58 +0200 |
commit | 219872c8fe890cd280cf54f27df86504bb17d277 (patch) | |
tree | 605a49912a56cbda4c85965c11eb746c9a0a104f /arch/arm/cpu/arm1136/cpu.c | |
parent | f4ac6cb6af107ce62754dd3bfc7ff31a92e7e2c8 (diff) |
ARM1136: add cache flush and invalidate operations
Since commit 5c1ad3e6f8ae578bbe30e09652f1531e9bc22031
(net: fec_mxc: allow use with cache enabled) the FEC_MXC
driver uses flush_dcache_range() and invalidate_dcache_range()
functions. This driver is also configured for ARM1136 based
'flea3' and 'mx35pdk' boards which currently do not build
as there are no ARM1136 specific flush_dcache_range() and
invalidate_dcache_range() functions. Add various ARM1136
cache functions to fix building for 'flea3' and 'mx35pdk'.
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Signed-off-by: Stefano Babic <sbabic@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
CC: Mike Frysinger <vapier@gentoo.org>
CC: Marek Vasut <marex@denx.de>
Acked-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'arch/arm/cpu/arm1136/cpu.c')
-rw-r--r-- | arch/arm/cpu/arm1136/cpu.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/arm/cpu/arm1136/cpu.c b/arch/arm/cpu/arm1136/cpu.c index 2b91631735..f2e30b5198 100644 --- a/arch/arm/cpu/arm1136/cpu.c +++ b/arch/arm/cpu/arm1136/cpu.c @@ -75,3 +75,98 @@ static void cache_flush(void) asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */ asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */ } + +#ifndef CONFIG_SYS_DCACHE_OFF + +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE 32 +#endif + +void invalidate_dcache_all(void) +{ + asm ("mcr p15, 0, %0, c7, c6, 0" : : "r" (0)); +} + +void flush_dcache_all(void) +{ + asm ("mcr p15, 0, %0, c7, c10, 0" : : "r" (0)); + asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +} + +static inline int bad_cache_range(unsigned long start, unsigned long stop) +{ + int ok = 1; + + if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (!ok) + debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", + start, stop); + + return ok; +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ + if (bad_cache_range(start, stop)) + return; + + while (start < stop) { + asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)); + start += CONFIG_SYS_CACHELINE_SIZE; + } +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ + if (bad_cache_range(start, stop)) + return; + + while (start < stop) { + asm ("mcr p15, 0, %0, c7, c14, 1" : : "r" (start)); + start += CONFIG_SYS_CACHELINE_SIZE; + } + + asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +} + +void flush_cache(unsigned long start, unsigned long size) +{ + flush_dcache_range(start, start + size); +} + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} + +#else /* #ifndef CONFIG_SYS_DCACHE_OFF */ +void invalidate_dcache_all(void) +{ +} + +void flush_dcache_all(void) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_cache(unsigned long start, unsigned long size) +{ +} +#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ |