diff options
| author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-12-10 14:31:56 +0100 | 
|---|---|---|
| committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-12-10 22:23:59 +0100 | 
| commit | f15ea6e1d67782a1626d4a4922b6c20e380085e5 (patch) | |
| tree | 57d78f1ee94a2060eaa591533278d2934d4f1da3 /arch/mips/cpu/mips32/cpu.c | |
| parent | cb7ee1b98cac6baf244daefb1192adf5a47bc983 (diff) | |
| parent | f44483b57c49282299da0e5c10073b909cdad979 (diff) | |
| download | olio-uboot-2014.01-f15ea6e1d67782a1626d4a4922b6c20e380085e5.tar.xz olio-uboot-2014.01-f15ea6e1d67782a1626d4a4922b6c20e380085e5.zip | |
Merge branch 'u-boot/master' into 'u-boot-arm/master'
Conflicts:
	arch/arm/cpu/armv7/rmobile/Makefile
	doc/README.scrapyard
Needed manual fix:
	arch/arm/cpu/armv7/omap-common/Makefile
	board/compulab/cm_t335/u-boot.lds
Diffstat (limited to 'arch/mips/cpu/mips32/cpu.c')
| -rw-r--r-- | arch/mips/cpu/mips32/cpu.c | 73 | 
1 files changed, 67 insertions, 6 deletions
| diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c index 28d5c4568..278865b6f 100644 --- a/arch/mips/cpu/mips32/cpu.c +++ b/arch/mips/cpu/mips32/cpu.c @@ -34,28 +34,89 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	return 0;  } +#ifdef CONFIG_SYS_CACHELINE_SIZE + +static inline unsigned long icache_line_size(void) +{ +	return CONFIG_SYS_CACHELINE_SIZE; +} + +static inline unsigned long dcache_line_size(void) +{ +	return CONFIG_SYS_CACHELINE_SIZE; +} + +#else /* !CONFIG_SYS_CACHELINE_SIZE */ + +static inline unsigned long icache_line_size(void) +{ +	unsigned long conf1, il; +	conf1 = read_c0_config1(); +	il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHIFT; +	if (!il) +		return 0; +	return 2 << il; +} + +static inline unsigned long dcache_line_size(void) +{ +	unsigned long conf1, dl; +	conf1 = read_c0_config1(); +	dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHIFT; +	if (!dl) +		return 0; +	return 2 << dl; +} + +#endif /* !CONFIG_SYS_CACHELINE_SIZE */ +  void flush_cache(ulong start_addr, ulong size)  { -	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; -	unsigned long addr = start_addr & ~(lsize - 1); -	unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); +	unsigned long ilsize = icache_line_size(); +	unsigned long dlsize = dcache_line_size(); +	unsigned long addr, aend;  	/* aend will be miscalculated when size is zero, so we return here */  	if (size == 0)  		return; +	addr = start_addr & ~(dlsize - 1); +	aend = (start_addr + size - 1) & ~(dlsize - 1); + +	if (ilsize == dlsize) { +		/* flush I-cache & D-cache simultaneously */ +		while (1) { +			cache_op(HIT_WRITEBACK_INV_D, addr); +			cache_op(HIT_INVALIDATE_I, addr); +			if (addr == aend) +				break; +			addr += dlsize; +		} +		return; +	} + +	/* flush D-cache */  	while (1) {  		cache_op(HIT_WRITEBACK_INV_D, addr); +		if (addr == aend) +			break; +		addr += dlsize; +	} + +	/* flush I-cache */ +	addr = start_addr & ~(ilsize - 1); +	aend = (start_addr + size - 1) & ~(ilsize - 1); +	while (1) {  		cache_op(HIT_INVALIDATE_I, addr);  		if (addr == aend)  			break; -		addr += lsize; +		addr += ilsize;  	}  }  void flush_dcache_range(ulong start_addr, ulong stop)  { -	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; +	unsigned long lsize = dcache_line_size();  	unsigned long addr = start_addr & ~(lsize - 1);  	unsigned long aend = (stop - 1) & ~(lsize - 1); @@ -69,7 +130,7 @@ void flush_dcache_range(ulong start_addr, ulong stop)  void invalidate_dcache_range(ulong start_addr, ulong stop)  { -	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; +	unsigned long lsize = dcache_line_size();  	unsigned long addr = start_addr & ~(lsize - 1);  	unsigned long aend = (stop - 1) & ~(lsize - 1); |