arm64: mvebu: Add L3 cache flush functionality to A8K family
authorKonstantin Porotchkin <kostap@marvell.com>
Sun, 4 Dec 2016 16:34:13 +0000 (18:34 +0200)
committerStefan Roese <sr@denx.de>
Mon, 12 Dec 2016 08:05:28 +0000 (09:05 +0100)
Add missing L3 cache flush functionality which absence prevents
Linux kernel from normal boot in case the L3 cache is enabled
by ATF.
The L3 cache is named the "last level" cache in order to keep
the terminology similar to the ATF code.
This cache should not be disabled by u-boot since the Linux
kernel cannot activate it, so it is activates at ATF stage.
However the cache flush is required for preventing data corruption
after disabling the MMU and the data cache before passing control
to the loaded Linux image.

Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
Cc: Stefan Roese <sr@denx.de>
Cc: Nadav Haklai <nadavh@marvell.com>
Cc: Neta Zur Hershkovits <neta@marvell.com>
Cc: Omri Itach <omrii@marvell.com>
Cc: Igal Liberman <igall@marvell.com>
Cc: Haim Boot <hayim@marvell.com>
Cc: Hanna Hawa <hannah@marvell.com>
Signed-off-by: Stefan Roese <sr@denx.de>
arch/arm/include/asm/arch-armada8k/cache_llc.h [new file with mode: 0644]
arch/arm/mach-mvebu/armada8k/Makefile
arch/arm/mach-mvebu/armada8k/cache_llc.S [new file with mode: 0644]

diff --git a/arch/arm/include/asm/arch-armada8k/cache_llc.h b/arch/arm/include/asm/arch-armada8k/cache_llc.h
new file mode 100644 (file)
index 0000000..8f97e6d
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ * https://spdx.org/licenses
+ */
+
+#ifndef _CACHE_LLC_H_
+#define _CACHE_LLC_H_
+
+/* Armada-7K/8K last level cache */
+
+#define MVEBU_A8K_REGS_BASE_MSB                0xf000
+#define LLC_BASE_ADDR                  0x8000
+#define LLC_CACHE_SYNC                 0x700
+#define LLC_CACHE_SYNC_COMPLETE                0x730
+#define LLC_FLUSH_BY_WAY               0x7fc
+#define LLC_WAY_MASK                   0xffffffff
+#define LLC_CACHE_SYNC_MASK            0x1
+
+#endif /* _CACHE_LLC_H_ */
index 84c69d90e73f1b5840ed738da824b04c72c9c3de..0facf14942df62d39ecc52e773b36341b37ae5e2 100644 (file)
@@ -5,3 +5,4 @@
 #
 
 obj-y = cpu.o
+obj-y += cache_llc.o
diff --git a/arch/arm/mach-mvebu/armada8k/cache_llc.S b/arch/arm/mach-mvebu/armada8k/cache_llc.S
new file mode 100644 (file)
index 0000000..71aecb2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ * https://spdx.org/licenses
+ */
+
+#include <asm/arch-armada8k/cache_llc.h>
+#include <linux/linkage.h>
+
+/*
+ * int __asm_flush_l3_dcache
+ *
+ * flush Armada-8K last level cache.
+ *
+ */
+ENTRY(__asm_flush_l3_dcache)
+       /* flush cache */
+       mov     x0, #LLC_BASE_ADDR
+       add     x0, x0, #LLC_FLUSH_BY_WAY
+       movk    x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16
+       mov     w1, #LLC_WAY_MASK
+       str     w1, [x0]
+       /* sync cache */
+       mov     x0, #LLC_BASE_ADDR
+       add     x0, x0, #LLC_CACHE_SYNC
+       movk    x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16
+       str     wzr, [x0]
+       /* check that cache sync completed */
+       mov     x0, #LLC_BASE_ADDR
+       add     x0, x0, #LLC_CACHE_SYNC_COMPLETE
+       movk    x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16
+1:     ldr     w1, [x0]
+       and     w1, w1, #LLC_CACHE_SYNC_MASK
+       cbnz    w1, 1b
+       /* return success */
+       mov     x0, #0
+       ret
+ENDPROC(__asm_flush_l3_dcache)