summaryrefslogtreecommitdiff
path: root/arch/arc
diff options
context:
space:
mode:
authorEugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>2018-03-21 15:59:02 +0300
committerAlexey Brodkin <abrodkin@synopsys.com>2018-03-21 17:06:54 +0300
commit375945bac2b8cbb547940ad5cf1e16a0eb0ddfeb (patch)
tree1c6a6f8b134ee60f38229a995d7843f75b44a5de /arch/arc
parent95336738f1cf2d4fabfc9bfc4981fa14714efc30 (diff)
ARC: Implement a function to sync and cleanup caches
Implement specialized function to clenup caches (and therefore sync instruction and data caches) which can be used for cleanup before linux launch or to sync caches during U-Boot self-relocation. Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/include/asm/cache.h1
-rw-r--r--arch/arc/lib/bootm.c4
-rw-r--r--arch/arc/lib/cache.c23
-rw-r--r--arch/arc/lib/init_helpers.c6
4 files changed, 29 insertions, 5 deletions
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index fe75409b5c..2269183615 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -31,6 +31,7 @@
void cache_init(void);
void flush_n_invalidate_dcache_all(void);
+void sync_n_cleanup_cache_all(void);
static const inline int is_ioc_enabled(void)
{
diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c
index 4d4acff239..f1ab344773 100644
--- a/arch/arc/lib/bootm.c
+++ b/arch/arc/lib/bootm.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm/cache.h>
#include <common.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -40,8 +41,7 @@ void arch_lmb_reserve(struct lmb *lmb)
static int cleanup_before_linux(void)
{
disable_interrupts();
- flush_dcache_all();
- invalidate_icache_all();
+ sync_n_cleanup_cache_all();
return 0;
}
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index a5aae3d232..5d7583d868 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -591,3 +591,26 @@ void flush_dcache_all(void)
if (is_isa_arcv2() && !slc_data_bypass())
__slc_entire_op(OP_FLUSH);
}
+
+/*
+ * This is function to cleanup all caches (and therefore sync I/D caches) which
+ * can be used for cleanup before linux launch or to sync caches during
+ * relocation.
+ */
+void sync_n_cleanup_cache_all(void)
+{
+ __dc_entire_op(OP_FLUSH_N_INV);
+
+ /*
+ * If SL$ is bypassed for data it is used only for instructions,
+ * and we shouldn't flush it. So invalidate it instead of flush_n_inv.
+ */
+ if (is_isa_arcv2()) {
+ if (slc_data_bypass())
+ __slc_entire_op(OP_INV);
+ else
+ __slc_entire_op(OP_FLUSH_N_INV);
+ }
+
+ __ic_entire_invalidate();
+}
diff --git a/arch/arc/lib/init_helpers.c b/arch/arc/lib/init_helpers.c
index dbc8d68ffb..435fe96ef4 100644
--- a/arch/arc/lib/init_helpers.c
+++ b/arch/arc/lib/init_helpers.c
@@ -4,14 +4,14 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm/cache.h>
#include <common.h>
DECLARE_GLOBAL_DATA_PTR;
int init_cache_f_r(void)
{
-#ifndef CONFIG_SYS_DCACHE_OFF
- flush_dcache_all();
-#endif
+ sync_n_cleanup_cache_all();
+
return 0;
}