diff options
| author | Peter Tyser <ptyser@xes-inc.com> | 2010-04-12 22:28:04 -0500 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2010-04-13 09:13:03 +0200 | 
| commit | ea0364f1bbfed1e3ea711147420875cf338fe77a (patch) | |
| tree | 15c051bc4d2e94c1661c73e1b87c22c7beda7c24 /arch/blackfin/lib/cache.c | |
| parent | 89f39e177e7b0152aa1d3152baa25d986e36cdcf (diff) | |
| download | olio-uboot-2014.01-ea0364f1bbfed1e3ea711147420875cf338fe77a.tar.xz olio-uboot-2014.01-ea0364f1bbfed1e3ea711147420875cf338fe77a.zip | |
Move lib_$ARCH directories to arch/$ARCH/lib
Also move lib_$ARCH/config.mk to arch/$ARCH/config.mk
This change is intended to clean up the top-level directory structure
and more closely mimic Linux's directory organization.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Diffstat (limited to 'arch/blackfin/lib/cache.c')
| -rw-r--r-- | arch/blackfin/lib/cache.c | 113 | 
1 files changed, 113 insertions, 0 deletions
| diff --git a/arch/blackfin/lib/cache.c b/arch/blackfin/lib/cache.c new file mode 100644 index 000000000..0a321a448 --- /dev/null +++ b/arch/blackfin/lib/cache.c @@ -0,0 +1,113 @@ +/* + * U-boot - cache.c + * + * Copyright (c) 2005-2008 Analog Devices Inc. + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <asm/blackfin.h> +#include <asm/mach-common/bits/mpu.h> + +void flush_cache(unsigned long addr, unsigned long size) +{ +	void *start_addr, *end_addr; +	int istatus, dstatus; + +	/* no need to flush stuff in on chip memory (L1/L2/etc...) */ +	if (addr >= 0xE0000000) +		return; + +	start_addr = (void *)addr; +	end_addr = (void *)(addr + size); +	istatus = icache_status(); +	dstatus = dcache_status(); + +	if (istatus) { +		if (dstatus) +			blackfin_icache_dcache_flush_range(start_addr, end_addr); +		else +			blackfin_icache_flush_range(start_addr, end_addr); +	} else if (dstatus) +		blackfin_dcache_flush_range(start_addr, end_addr); +} + +#ifdef CONFIG_DCACHE_WB +static void flushinv_all_dcache(void) +{ +	u32 way, bank, subbank, set; +	u32 status, addr; +	u32 dmem_ctl = bfin_read_DMEM_CONTROL(); + +	for (bank = 0; bank < 2; ++bank) { +		if (!(dmem_ctl & (1 << (DMC1_P - bank)))) +			continue; + +		for (way = 0; way < 2; ++way) +			for (subbank = 0; subbank < 4; ++subbank) +				for (set = 0; set < 64; ++set) { + +					bfin_write_DTEST_COMMAND( +						way << 26 | +						bank << 23 | +						subbank << 16 | +						set << 5 +					); +					CSYNC(); +					status = bfin_read_DTEST_DATA0(); + +					/* only worry about valid/dirty entries */ +					if ((status & 0x3) != 0x3) +						continue; + +					/* construct the address using the tag */ +					addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); + +					/* flush it */ +					__asm__ __volatile__("FLUSHINV[%0];" : : "a"(addr)); +				} +	} +} +#endif + +void icache_enable(void) +{ +	bfin_write_IMEM_CONTROL(IMC | ENICPLB); +	SSYNC(); +} + +void icache_disable(void) +{ +	bfin_write_IMEM_CONTROL(0); +	SSYNC(); +} + +int icache_status(void) +{ +	return bfin_read_IMEM_CONTROL() & IMC; +} + +void dcache_enable(void) +{ +	bfin_write_DMEM_CONTROL(ACACHE_BCACHE | ENDCPLB | PORT_PREF0); +	SSYNC(); +} + +void dcache_disable(void) +{ +#ifdef CONFIG_DCACHE_WB +	bfin_write_DMEM_CONTROL(bfin_read_DMEM_CONTROL() & ~(ENDCPLB)); +	flushinv_all_dcache(); +#endif +	bfin_write_DMEM_CONTROL(0); +	SSYNC(); +} + +int dcache_status(void) +{ +	return bfin_read_DMEM_CONTROL() & ACACHE_BCACHE; +} |