-----Original Message-----
From: alif.zakuan.yusla...@intel.com <alif.zakuan.yusla...@intel.com>
Sent: Tuesday, February 18, 2025 4:35 PM
To: u-boot@lists.denx.de
Cc: Marek Vasut <ma...@denx.de>; Simon Goldschmidt
<simon.k.r.goldschm...@gmail.com>; Chee, Tien Fong <tien.fong.c...@altera.com>;
Yuslaimi, Alif Zakuan <alif.zakuan.yusla...@altera.com>; Meng, Tingting
<tingting.m...@altera.com>; Ng, Boon Khai <boon.khai...@altera.com>; Hea, Kok
Kiang <kok.kiang....@altera.com>; Tien Fong Chee <tien.fong.c...@intel.com>
Subject: [PATCH v2 13/26] arm: socfpga: agilex5: Enable cache flush for system
memory cache in CCU
From: Tien Fong Chee <tien.fong.c...@intel.com>
set/way instructions "dc cisw" which is used by the "dcache flush" command only
flushing CPU data caches from L1 -> L2 -> L3 to system memory cache in cache
coherency unit, hence this patch enables data flush from system memory cache of
CCU into DDR memory.
Signed-off-by: Tien Fong Chee <tien.fong.c...@altera.com>
---
arch/arm/mach-socfpga/Makefile | 1 +
arch/arm/mach-socfpga/ccu_ncore3.c | 64 ++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
create mode 100644 arch/arm/mach-socfpga/ccu_ncore3.c
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index cd9e9272024..b6897ba42b1 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -65,6 +65,7 @@ obj-y += mmu-arm64_s10.o
obj-y += reset_manager_s10.o
obj-y += wrap_handoff_soc64.o
obj-y += wrap_pll_config_soc64.o
+obj-y += ccu_ncore3.o
endif
ifdef CONFIG_TARGET_SOCFPGA_N5X
diff --git a/arch/arm/mach-socfpga/ccu_ncore3.c
b/arch/arm/mach-socfpga/ccu_ncore3.c
new file mode 100644
index 00000000000..a399aedcd10
--- /dev/null
+++ b/arch/arm/mach-socfpga/ccu_ncore3.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Altera Corporation <www.altera.com>
+ *
+ */
+#include <wait_bit.h>
+#include <asm/arch/base_addr_soc64.h>
+#include <linux/bitfield.h>
+
+#define CCU_DMI0_DMIUSMCTCR SOCFPGA_CCU_ADDRESS +
0x7300
+#define CCU_DMI0_DMIUSMCMCR SOCFPGA_CCU_ADDRESS +
0x7340
+#define CCU_DMI0_DMIUSMCMAR SOCFPGA_CCU_ADDRESS +
0x7344
+#define CCU_DMI0_DMIUSMCMCR_MNTOP GENMASK(3, 0)
+#define MAX_DISTRIBUTED_MEM_INTERFACE 2
+#define FLUSH_ALL_ENTRIES 0x4
+#define CCU_DMI0_DMIUSMCMCR_ARRAY_ID GENMASK(21, 16)
+#define ARRAY_ID_TAG 0x0
+#define ARRAY_ID_DATA 0x1
+#define CACHE_OPERATION_DONE BIT(0)
+#define TIMEOUT_200MS 200
+
+int __asm_flush_l3_dcache(void)
+{
+ int i;
+ int ret = 0;
+
+ /* Flushing all entries in CCU system memory cache */
+ for (i = 0; i < MAX_DISTRIBUTED_MEM_INTERFACE; i++) {
+ /*
+ * Skipping if the system memory cache is not enabled for
+ * particular DMI
+ */
+ if (!readl((uintptr_t)(CCU_DMI0_DMIUSMCTCR + (i * 0x1000))))
+ continue;
+
+ writel(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES)
|
+ FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID,
ARRAY_ID_TAG),
+ (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+ /* Wait for cache maintenance operation done */
+ ret = wait_for_bit_le32((const void
*)(uintptr_t)(CCU_DMI0_DMIUSMCMAR +
+ (i * 0x1000)), CACHE_OPERATION_DONE, false,
TIMEOUT_200MS,
+ false);
+ if (ret) {
+ debug("%s: Timeout while waiting for flushing tag in
DMI%d done\n",
+ __func__, i);
+ return ret;
+ }
+
+ writel(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES)
|
+ FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID,
ARRAY_ID_DATA),
+ (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+ /* Wait for cache maintenance operation done */
+ ret = wait_for_bit_le32((const void
*)(uintptr_t)(CCU_DMI0_DMIUSMCMAR +
+ (i * 0x1000)), CACHE_OPERATION_DONE, false,
TIMEOUT_200MS,
+ false);
+ if (ret)
+ debug("%s: Timeout waiting for flushing data in DMI%d
done\n",
+ __func__, i);
+ }
+
+ return ret;
+}
--
2.25.1
Reviewed-by: Tien Fong Chee <tien.fong.c...@altera.com>
Best regards,
Tien Fong