diff options
author | Alexander Stein <alexanders83@web.de> | 2015-07-24 09:22:10 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-08-12 20:47:41 -0400 |
commit | 2085ae74dee47ed3da63416aac0305936b43eeea (patch) | |
tree | 8739d32fffb98508984cf9aa7d5a764136d1b6da /arch/arm/cpu/arm11 | |
parent | b16a52b9b5185176a8923476bebc2e0bc29148da (diff) |
arm1136/arm1176: Merge cache handling code
As both cores are similar merge the cache handling code for both CPUs
to arm11 directory.
Signed-off-by: Alexander Stein <alexanders83@web.de>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
Tested-by: Stephen Warren <swarren@wwwdotorg.org>
[trini: Add hunk to arch/arm/cpu/arm1136/Makefile]
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch/arm/cpu/arm11')
-rw-r--r-- | arch/arm/cpu/arm11/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/cpu/arm11/cpu.c | 150 |
2 files changed, 158 insertions, 0 deletions
diff --git a/arch/arm/cpu/arm11/Makefile b/arch/arm/cpu/arm11/Makefile new file mode 100644 index 0000000000..2379b0fe10 --- /dev/null +++ b/arch/arm/cpu/arm11/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o diff --git a/arch/arm/cpu/arm11/cpu.c b/arch/arm/cpu/arm11/cpu.c new file mode 100644 index 0000000000..5d4b3c2a02 --- /dev/null +++ b/arch/arm/cpu/arm11/cpu.c @@ -0,0 +1,150 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +static void cache_flush(void) +{ + unsigned long i = 0; + /* clean entire data cache */ + asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i)); + /* invalidate both caches and flush btb */ + asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i)); + /* mem barrier to sync things */ + asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i)); +} + +#ifndef CONFIG_SYS_DCACHE_OFF + +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE 32 +#endif + +void invalidate_dcache_all(void) +{ + asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0)); +} + +void flush_dcache_all(void) +{ + asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0)); + asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +} + +static int check_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 (!check_cache_range(start, stop)) + return; + + while (start < stop) { + asm volatile("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 (!check_cache_range(start, stop)) + return; + + while (start < stop) { + asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start)); + start += CONFIG_SYS_CACHELINE_SIZE; + } + + asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +} + +void flush_cache(unsigned long start, unsigned long size) +{ + flush_dcache_range(start, start + size); +} + +#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 */ + +#if !defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF) +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} +#endif |