1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2002
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  */
6 
7 #include <common.h>
8 #include <cpu_func.h>
9 #include <asm/cache.h>
10 #include <watchdog.h>
11 
maybe_watchdog_reset(ulong flushed)12 static ulong maybe_watchdog_reset(ulong flushed)
13 {
14 	flushed += CONFIG_SYS_CACHELINE_SIZE;
15 	if (flushed >= CONFIG_CACHE_FLUSH_WATCHDOG_THRESHOLD) {
16 		WATCHDOG_RESET();
17 		flushed = 0;
18 	}
19 	return flushed;
20 }
21 
flush_cache(ulong start_addr,ulong size)22 void flush_cache(ulong start_addr, ulong size)
23 {
24 	ulong addr, start, end;
25 	ulong flushed = 0;
26 
27 	start = start_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
28 	end = start_addr + size - 1;
29 
30 	for (addr = start; (addr <= end) && (addr >= start);
31 			addr += CONFIG_SYS_CACHELINE_SIZE) {
32 		asm volatile("dcbst 0,%0" : : "r" (addr) : "memory");
33 		flushed = maybe_watchdog_reset(flushed);
34 	}
35 	/* wait for all dcbst to complete on bus */
36 	asm volatile("sync" : : : "memory");
37 
38 	for (addr = start; (addr <= end) && (addr >= start);
39 			addr += CONFIG_SYS_CACHELINE_SIZE) {
40 		asm volatile("icbi 0,%0" : : "r" (addr) : "memory");
41 		flushed = maybe_watchdog_reset(flushed);
42 	}
43 	asm volatile("sync" : : : "memory");
44 	/* flush prefetch queue */
45 	asm volatile("isync" : : : "memory");
46 }
47