[PATCH v2 1/3] arch: arm: socfpga: Add SMMU initialization and setup

Naresh Kumar Ravulapalli nareshkumar.ravulapalli at altera.com
Wed Aug 20 09:31:59 CEST 2025


SMMU initialization for SoC64 devices is added and stream IDs are
setup for SMMU peripheral matching. This allows non-secure
accesses with SMMU peripherals.

Signed-off-by: Naresh Kumar Ravulapalli <nareshkumar.ravulapalli at altera.com>
---
 arch/arm/mach-socfpga/Makefile                |  3 +
 arch/arm/mach-socfpga/include/mach/smmu_s10.h | 39 ++++++++++
 .../include/mach/system_manager_soc64.h       |  3 +
 arch/arm/mach-socfpga/smmu_s10.c              | 77 +++++++++++++++++++
 arch/arm/mach-socfpga/spl_soc64.c             |  6 ++
 5 files changed, 128 insertions(+)
 create mode 100644 arch/arm/mach-socfpga/include/mach/smmu_s10.h
 create mode 100644 arch/arm/mach-socfpga/smmu_s10.c

diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index c43fdee4a48..5b414c6e995 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -35,6 +35,7 @@ obj-y	+= mailbox_s10.o
 obj-y	+= misc_soc64.o
 obj-y	+= mmu-arm64_s10.o
 obj-y	+= reset_manager_s10.o
+obj-y	+= smmu_s10.o
 obj-y	+= system_manager_soc64.o
 obj-y	+= timer_s10.o
 obj-y	+= wrap_handoff_soc64.o
@@ -49,6 +50,7 @@ obj-y	+= misc_soc64.o
 obj-y	+= mmu-arm64_s10.o
 obj-y	+= reset_manager_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= secure_vab.o
+obj-y	+= smmu_s10.o
 obj-y	+= system_manager_soc64.o
 obj-y	+= timer_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= vab.o
@@ -80,6 +82,7 @@ obj-y	+= misc_soc64.o
 obj-y	+= mmu-arm64_s10.o
 obj-y	+= reset_manager_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= secure_vab.o
+obj-y	+= smmu_s10.o
 obj-y	+= system_manager_soc64.o
 obj-y	+= timer_s10.o
 obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH)	+= vab.o
diff --git a/arch/arm/mach-socfpga/include/mach/smmu_s10.h b/arch/arm/mach-socfpga/include/mach/smmu_s10.h
new file mode 100644
index 00000000000..4a28b109b0d
--- /dev/null
+++ b/arch/arm/mach-socfpga/include/mach/smmu_s10.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Intel Corporation <www.intel.com>
+ * Copyright (C) 2025 Altera Corporation <www.altera.com>
+ */
+
+void socfpga_init_smmu(void);
+
+#define SMMU_SET_STREAMID(x, r, w)	(((x) << (r)) | ((x) << (w)))
+
+#define SYSMGR_EMAC0_SID_ADDR	0xffd12050	/* EMAC0 (emac0_ace) */
+#define SYSMGR_EMAC1_SID_ADDR	0xffd12054	/* EMAC0 (emac1_ace) */
+#define SYSMGR_EMAC2_SID_ADDR	0xffd12058	/* EMAC0 (emac2_ace) */
+#define SYSMGR_NAND_SID_ADDR	0xffd1205c	/* NAND (nand_axuser) */
+#define SYSMGR_SDMMC_SID_ADDR	0xffd1202c	/* SDMMC (sdmmcgrp_l3master) */
+#define SYSMGR_USB0_SID_ADDR	0xffd12038	/* USB0 (usb0_l3master) */
+#define SYSMGR_USB1_SID_ADDR	0xffd1203c	/* USB0 (usb1_l3master) */
+#define SYSMGR_DMA_SID_ADDR	0xffd12074	/* DMA (dma_l3master) */
+#define SYSMGR_ETR_SID_ADDR	0xffd12078	/* ETR (etr_l3master) */
+
+/* Stream ID field offsets */
+#define EMAC_W_OFST	20
+#define EMAC_R_OFST	8
+#define NAND_W_OFST	0
+#define NAND_R_OFST	16
+#define SDMMC_OFST	16
+#define USB_OFST	16
+#define DMA_W_OFST	0
+#define DMA_R_OFST	16
+#define ETR_W_OFST	0
+#define ETR_R_OFST	16
+
+struct smmu_stream_id {
+	unsigned long addr;
+	u32 sid;
+	u32 r_bit_ofst;
+	u32 w_bit_ofst;
+	u32 secure_bit_offset;
+};
diff --git a/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h b/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h
index 8a7d47bee44..3f91707ec49 100644
--- a/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h
+++ b/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h
@@ -80,6 +80,9 @@ void populate_sysmgr_pinmux(void);
 #define SYSMGR_SOC64_WDDBG			0x08
 #define SYSMGR_SOC64_SDMMC			0x28
 #define SYSMGR_SOC64_SDMMC_L3MASTER		0x2C
+#define SYSMGR_SOC64_NANDGRP_L3MASTER		0x34
+#define SYSMGR_SOC64_USB0_L3MASTER		0x38
+#define SYSMGR_SOC64_USB1_L3MASTER		0x3c
 #define SYSMGR_SOC64_FPGAINTF_EN1		0x68
 #define SYSMGR_SOC64_FPGAINTF_EN2		0x6C
 #define SYSMGR_SOC64_FPGAINTF_EN3		0x70
diff --git a/arch/arm/mach-socfpga/smmu_s10.c b/arch/arm/mach-socfpga/smmu_s10.c
new file mode 100644
index 00000000000..50be049538b
--- /dev/null
+++ b/arch/arm/mach-socfpga/smmu_s10.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Intel Corporation <www.intel.com>
+ * Copyright (C) 2025 Altera Corporation <www.altera.com>
+ */
+
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/firewall.h>
+#include <asm/arch/smmu_s10.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct smmu_stream_id dev_stream_id[] = {
+	{SYSMGR_EMAC0_SID_ADDR, 0x01, EMAC_W_OFST, EMAC_R_OFST},
+	{SYSMGR_EMAC1_SID_ADDR, 0x02, EMAC_W_OFST, EMAC_R_OFST},
+	{SYSMGR_EMAC2_SID_ADDR, 0x03, EMAC_W_OFST, EMAC_R_OFST},
+	{SYSMGR_NAND_SID_ADDR,  0x04, NAND_W_OFST, NAND_R_OFST},
+	{SYSMGR_SDMMC_SID_ADDR, 0x05, SDMMC_OFST, SDMMC_OFST},
+	{SYSMGR_USB0_SID_ADDR,  0x06, USB_OFST, USB_OFST},
+	{SYSMGR_USB1_SID_ADDR,  0x07, USB_OFST, USB_OFST},
+	{SYSMGR_DMA_SID_ADDR,   0x08, DMA_W_OFST, DMA_R_OFST},
+	{SYSMGR_ETR_SID_ADDR,   0x09, ETR_W_OFST, ETR_R_OFST},
+};
+
+static void set_smmu_streamid(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dev_stream_id); i++) {
+		u32 mask = SMMU_SET_STREAMID(0x3FF,
+					 dev_stream_id[i].r_bit_ofst,
+					 dev_stream_id[i].w_bit_ofst);
+		u32 value = SMMU_SET_STREAMID(dev_stream_id[i].sid,
+					 dev_stream_id[i].r_bit_ofst,
+					 dev_stream_id[i].w_bit_ofst);
+
+		clrbits_le32(dev_stream_id[i].addr, mask);
+		setbits_le32(dev_stream_id[i].addr, value);
+	}
+}
+
+/*
+ * Need to set the Secure bit (to make it non-secure) on each peripheral
+ * so that SMMU can access the peripheral
+ */
+static void set_smmu_accessible_reg(void)
+{
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0,
+		     BIT(27) | BIT(25));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC1,
+		     BIT(27) | BIT(25));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC2,
+		     BIT(27) | BIT(25));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NANDGRP_L3MASTER,
+		     BIT(21) | BIT(17));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_SDMMC_L3MASTER,
+		     BIT(5));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_USB0_L3MASTER,
+		     BIT(9));
+	setbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_USB1_L3MASTER,
+		     BIT(9));
+}
+
+static inline void setup_smmu_firewall(void)
+{
+	/* Enable nonsecure SMMU accesses */
+	writel(FIREWALL_L4_DISABLE_ALL, SOCFPGA_FIREWALL_TCU);
+}
+
+void socfpga_init_smmu(void)
+{
+	setup_smmu_firewall();
+	set_smmu_streamid();
+	set_smmu_accessible_reg();
+}
diff --git a/arch/arm/mach-socfpga/spl_soc64.c b/arch/arm/mach-socfpga/spl_soc64.c
index 651d9fc9cb8..6b219fe140d 100644
--- a/arch/arm/mach-socfpga/spl_soc64.c
+++ b/arch/arm/mach-socfpga/spl_soc64.c
@@ -7,6 +7,8 @@
 
 #include <hang.h>
 #include <spl.h>
+#include <asm/arch/mailbox_s10.h>
+#include <asm/arch/smmu_s10.h>
 #include <dm/uclass.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -132,6 +134,7 @@ u32 spl_boot_mode(const u32 boot_device)
 /* board specific function prior loading SSBL / U-Boot */
 void spl_perform_fixups(struct spl_image_info *spl_image)
 {
+#if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5))
 	int ret;
 	struct udevice *dev;
 
@@ -140,4 +143,7 @@ void spl_perform_fixups(struct spl_image_info *spl_image)
 		printf("HPS SMMU secure settings init failed: %d\n", ret);
 		hang();
 	}
+#endif
+
+	socfpga_init_smmu();
 }
-- 
2.35.3



More information about the U-Boot mailing list