-----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

Reply via email to