From: Thor Thayer <thor.tha...@linux.intel.com>

Add the SMMU initialization
- Allow non-secure accesses with SMMU peripherals
- Setup stream ID for SMMU peripheral matching

Signed-off-by: Thor Thayer <thor.tha...@linux.intel.com>
Signed-off-by: Siew Chin Lim <elly.siew.chin....@intel.com>
Signed-off-by: Jit Loon Lim <jit.loon....@intel.com>
---
 arch/arm/mach-socfpga/Makefile                |  2 +
 arch/arm/mach-socfpga/include/mach/smmu_s10.h | 40 ++++++++++
 .../include/mach/system_manager_soc64.h       |  3 +
 arch/arm/mach-socfpga/smmu_s10.c              | 78 +++++++++++++++++++
 arch/arm/mach-socfpga/spl_agilex.c            |  5 ++
 arch/arm/mach-socfpga/spl_s10.c               |  4 +
 6 files changed, 132 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 ec38b64dd4..253f18ec37 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
@@ -64,6 +65,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 0000000000..4c0de2da70
--- /dev/null
+++ b/arch/arm/mach-socfpga/include/mach/smmu_s10.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2017-2018 Intel Corporation <www.intel.com>
+ *
+ */
+#include <common.h>
+
+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 a8009664fe..291583e7e6 100644
--- a/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h
+++ b/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h
@@ -16,6 +16,9 @@ void populate_sysmgr_pinmux(void);
 #define SYSMGR_SOC64_DMA_PERIPH                        0x24
 #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_EMAC_GLOBAL               0x40
 #define SYSMGR_SOC64_EMAC0                     0x44
 #define SYSMGR_SOC64_EMAC1                     0x48
diff --git a/arch/arm/mach-socfpga/smmu_s10.c b/arch/arm/mach-socfpga/smmu_s10.c
new file mode 100644
index 0000000000..8be29b60bc
--- /dev/null
+++ b/arch/arm/mach-socfpga/smmu_s10.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017-2018 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#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 ee5a9dc1e2..01e482847b 100644
--- a/arch/arm/mach-socfpga/spl_agilex.c
+++ b/arch/arm/mach-socfpga/spl_agilex.c
@@ -19,6 +19,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>
@@ -65,6 +66,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 c20e87cdbe..dad2ac5d0d 100644
--- a/arch/arm/mach-socfpga/spl_s10.c
+++ b/arch/arm/mach-socfpga/spl_s10.c
@@ -20,6 +20,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>
@@ -70,6 +71,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.26.2

Reply via email to