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.ravulapa...@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_agilex.c | 5 ++ arch/arm/mach-socfpga/spl_s10.c | 4 + 6 files changed, 131 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_agilex.c b/arch/arm/mach-socfpga/spl_agilex.c index 91c27a5543d..95e092377ef 100644 --- a/arch/arm/mach-socfpga/spl_agilex.c +++ b/arch/arm/mach-socfpga/spl_agilex.c @@ -17,6 +17,7 @@ #include <asm/arch/mailbox_s10.h> #include <asm/arch/misc.h> #include <asm/arch/reset_manager.h> +#include <asm/arch/smmu_s10.h> #include <asm/arch/system_manager.h> #include <watchdog.h> #include <dm/uclass.h> @@ -67,6 +68,10 @@ void board_init_f(ulong dummy) cm_print_clock_quick_summary(); firewall_setup(); + + /* Setup and Initialize SMMU */ + socfpga_init_smmu(); + ret = uclass_get_device(UCLASS_CACHE, 0, &dev); if (ret) { debug("CCU init failed: %d\n", ret); diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c index fa83ff96adc..9eebeda308f 100644 --- a/arch/arm/mach-socfpga/spl_s10.c +++ b/arch/arm/mach-socfpga/spl_s10.c @@ -18,6 +18,7 @@ #include <asm/arch/mailbox_s10.h> #include <asm/arch/misc.h> #include <asm/arch/reset_manager.h> +#include <asm/arch/smmu_s10.h> #include <asm/arch/system_manager.h> #include <watchdog.h> #include <dm/uclass.h> @@ -72,6 +73,9 @@ void board_init_f(ulong dummy) firewall_setup(); + /* Setup and Initialize SMMU */ + socfpga_init_smmu(); + /* disable ocram security at CCU for non secure access */ clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADMASK_MEM_RAM0), CCU_ADMASK_P_MASK | CCU_ADMASK_NS_MASK); -- 2.35.3