blob: e4d9546039d825284dfaee7152c9d10cab91a5ff [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenkaffae2b2002-08-17 09:36:01 +00002/*
3 * (C) Copyright 2002
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
wdenkaffae2b2002-08-17 09:36:01 +00005 */
6
Simon Glass63334482019-11-14 12:57:39 -07007#include <cpu_func.h>
Tom Rinid8d547f2024-06-19 15:27:58 -06008#include <stdio.h>
Stefan Roeseeff3a0a2007-10-31 17:55:58 +01009#include <asm/cache.h>
Yuri Tikhonov18db5a62008-04-29 13:32:45 +020010#include <watchdog.h>
Ilias Apalodimase9e18652025-02-20 15:54:42 +020011#include <linux/errno.h>
wdenk359733b2003-03-31 17:27:09 +000012
Rasmus Villemoesdc322752021-04-21 11:16:03 +020013static ulong maybe_watchdog_reset(ulong flushed)
14{
15 flushed += CONFIG_SYS_CACHELINE_SIZE;
16 if (flushed >= CONFIG_CACHE_FLUSH_WATCHDOG_THRESHOLD) {
Stefan Roese80877fa2022-09-02 14:10:46 +020017 schedule();
Rasmus Villemoesdc322752021-04-21 11:16:03 +020018 flushed = 0;
19 }
20 return flushed;
21}
22
Dave Liu06ed90b2008-12-05 15:36:14 +080023void flush_cache(ulong start_addr, ulong size)
wdenkaffae2b2002-08-17 09:36:01 +000024{
Dave Liu06ed90b2008-12-05 15:36:14 +080025 ulong addr, start, end;
Rasmus Villemoesdc322752021-04-21 11:16:03 +020026 ulong flushed = 0;
wdenkaffae2b2002-08-17 09:36:01 +000027
Dave Liu06ed90b2008-12-05 15:36:14 +080028 start = start_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
29 end = start_addr + size - 1;
wdenkaffae2b2002-08-17 09:36:01 +000030
Kumar Gala3b967ae2009-02-06 08:08:06 -060031 for (addr = start; (addr <= end) && (addr >= start);
32 addr += CONFIG_SYS_CACHELINE_SIZE) {
Dave Liu06ed90b2008-12-05 15:36:14 +080033 asm volatile("dcbst 0,%0" : : "r" (addr) : "memory");
Rasmus Villemoesdc322752021-04-21 11:16:03 +020034 flushed = maybe_watchdog_reset(flushed);
Dave Liu06ed90b2008-12-05 15:36:14 +080035 }
36 /* wait for all dcbst to complete on bus */
37 asm volatile("sync" : : : "memory");
38
Kumar Gala3b967ae2009-02-06 08:08:06 -060039 for (addr = start; (addr <= end) && (addr >= start);
40 addr += CONFIG_SYS_CACHELINE_SIZE) {
Dave Liu06ed90b2008-12-05 15:36:14 +080041 asm volatile("icbi 0,%0" : : "r" (addr) : "memory");
Rasmus Villemoesdc322752021-04-21 11:16:03 +020042 flushed = maybe_watchdog_reset(flushed);
wdenkaffae2b2002-08-17 09:36:01 +000043 }
Dave Liu06ed90b2008-12-05 15:36:14 +080044 asm volatile("sync" : : : "memory");
45 /* flush prefetch queue */
46 asm volatile("isync" : : : "memory");
wdenkaffae2b2002-08-17 09:36:01 +000047}
Tom Rini25d74db2024-06-19 15:27:57 -060048
49/*
50 * Default implementation:
51 * do a range flush for the entire range
52 */
53void flush_dcache_all(void)
54{
55 flush_dcache_range(0, ~0);
56}
Tom Rinid8d547f2024-06-19 15:27:58 -060057
58void invalidate_icache_all(void)
59{
60 puts("No arch specific invalidate_icache_all available!\n");
61}
Ilias Apalodimase9e18652025-02-20 15:54:42 +020062
63int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
64{
65 return -ENOSYS;
66}