diff mbox series

[v1,10/20] arm: socfpga: agilex5: Enable cache flush for system memory cache in CCU

Message ID 20240920070242.20884-11-tien.fong.chee@intel.com
State New
Headers show
Series SoCFPGA: Add Boot Support for Agilex 5 in U-Boot | expand

Commit Message

Chee, Tien Fong Sept. 20, 2024, 7:02 a.m. UTC
From: Tien Fong Chee <tien.fong.chee@intel.com>

set/way instructions "dc cisw" ehich 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.chee@intel.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 mbox series

Patch

diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index e0ada69dd5a..32b3e7a57e2 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..18667131eb9
--- /dev/null
+++ b/arch/arm/mach-socfpga/ccu_ncore3.c
@@ -0,0 +1,64 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Intel Corporation <www.intel.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;
+}