diff options
| author | Tom Rini <trini@ti.com> | 2013-11-11 09:40:34 -0500 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-11-11 09:40:34 -0500 | 
| commit | 60390d70be7336b2441f5f69bd4f5affa83d064d (patch) | |
| tree | 857824f8b7f5f7aaf2f5dac91eea94392818a7a0 /arch/mips/cpu/mips32/cpu.c | |
| parent | 85b8c5c4bf80025de4632ae6c9a8a606e51508a4 (diff) | |
| parent | a3e80904fb07cda792e636704e3b3950d1446af3 (diff) | |
| download | olio-uboot-2014.01-60390d70be7336b2441f5f69bd4f5affa83d064d.tar.xz olio-uboot-2014.01-60390d70be7336b2441f5f69bd4f5affa83d064d.zip | |
Merge branch 'master' of git://git.denx.de/u-boot-mips
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); |