arm: socfpga: stratix10: Add pinmux support for Stratix10 SoC
authorLey Foon Tan <ley.foon.tan@intel.com>
Fri, 18 May 2018 14:05:24 +0000 (22:05 +0800)
committerMarek Vasut <marex@denx.de>
Fri, 18 May 2018 08:30:48 +0000 (10:30 +0200)
Add pinmux driver support for Stratix SoC

Signed-off-by: Chin Liang See <chin.liang.see@intel.com>
Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
arch/arm/mach-socfpga/Makefile
arch/arm/mach-socfpga/include/mach/system_manager.h
arch/arm/mach-socfpga/include/mach/system_manager_s10.h [new file with mode: 0644]
arch/arm/mach-socfpga/system_manager_s10.c [new file with mode: 0644]
arch/arm/mach-socfpga/wrap_pinmux_config_s10.c [new file with mode: 0644]

index 69bdb84..61f5778 100644 (file)
@@ -31,6 +31,8 @@ endif
 ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
 obj-y  += clock_manager_s10.o
 obj-y  += reset_manager_s10.o
+obj-y  += system_manager_s10.o
+obj-y  += wrap_pinmux_config_s10.o
 obj-y  += wrap_pll_config_s10.o
 endif
 ifdef CONFIG_SPL_BUILD
index fbe2a8b..7e76df7 100644 (file)
@@ -6,6 +6,9 @@
 #ifndef _SYSTEM_MANAGER_H_
 #define _SYSTEM_MANAGER_H_
 
+#if defined(CONFIG_TARGET_SOCFPGA_STRATIX10)
+#include <asm/arch/system_manager_s10.h>
+#else
 #define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGPINMUX        BIT(0)
 #define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO    BIT(1)
 #define SYSMGR_ECC_OCRAM_EN    BIT(0)
@@ -88,5 +91,5 @@
 
 #define SYSMGR_GET_BOOTINFO_BSEL(bsel)         \
                (((bsel) >> SYSMGR_BOOTINFO_BSEL_SHIFT) & 7)
-
+#endif
 #endif /* _SYSTEM_MANAGER_H_ */
diff --git a/arch/arm/mach-socfpga/include/mach/system_manager_s10.h b/arch/arm/mach-socfpga/include/mach/system_manager_s10.h
new file mode 100644 (file)
index 0000000..813dff2
--- /dev/null
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ *
+ */
+
+#ifndef        _SYSTEM_MANAGER_S10_
+#define        _SYSTEM_MANAGER_S10_
+
+void sysmgr_pinmux_init(void);
+void populate_sysmgr_fpgaintf_module(void);
+void populate_sysmgr_pinmux(void);
+void sysmgr_pinmux_table_sel(const u32 **table, unsigned int *table_len);
+void sysmgr_pinmux_table_ctrl(const u32 **table, unsigned int *table_len);
+void sysmgr_pinmux_table_fpga(const u32 **table, unsigned int *table_len);
+void sysmgr_pinmux_table_delay(const u32 **table, unsigned int *table_len);
+
+struct socfpga_system_manager {
+       /* System Manager Module */
+       u32     siliconid1;                     /* 0x00 */
+       u32     siliconid2;
+       u32     wddbg;
+       u32     _pad_0xc;
+       u32     mpu_status;                     /* 0x10 */
+       u32     mpu_ace;
+       u32     _pad_0x18_0x1c[2];
+       u32     dma;                            /* 0x20 */
+       u32     dma_periph;
+       /* SDMMC Controller Group */
+       u32     sdmmcgrp_ctrl;
+       u32     sdmmcgrp_l3master;
+       /* NAND Flash Controller Register Group */
+       u32     nandgrp_bootstrap;              /* 0x30 */
+       u32     nandgrp_l3master;
+       /* USB Controller Group */
+       u32     usb0_l3master;
+       u32     usb1_l3master;
+       /* EMAC Group */
+       u32     emac_gbl;                       /* 0x40 */
+       u32     emac0;
+       u32     emac1;
+       u32     emac2;
+       u32     emac0_ace;                      /* 0x50 */
+       u32     emac1_ace;
+       u32     emac2_ace;
+       u32     nand_axuser;
+       u32     _pad_0x60_0x64[2];              /* 0x60 */
+       /* FPGA interface Group */
+       u32     fpgaintf_en_1;
+       u32     fpgaintf_en_2;
+       u32     fpgaintf_en_3;                  /* 0x70 */
+       u32     dma_l3master;
+       u32     etr_l3master;
+       u32     _pad_0x7c;
+       u32     sec_ctrl_slt;                   /* 0x80 */
+       u32     osc_trim;
+       u32     _pad_0x88_0x8c[2];
+       /* ECC Group */
+       u32     ecc_intmask_value;              /* 0x90 */
+       u32     ecc_intmask_set;
+       u32     ecc_intmask_clr;
+       u32     ecc_intstatus_serr;
+       u32     ecc_intstatus_derr;             /* 0xa0 */
+       u32     _pad_0xa4_0xac[3];
+       u32     noc_addr_remap;                 /* 0xb0 */
+       u32     hmc_clk;
+       u32     io_pa_ctrl;
+       u32     _pad_0xbc;
+       /* NOC Group */
+       u32     noc_timeout;                    /* 0xc0 */
+       u32     noc_idlereq_set;
+       u32     noc_idlereq_clr;
+       u32     noc_idlereq_value;
+       u32     noc_idleack;                    /* 0xd0 */
+       u32     noc_idlestatus;
+       u32     fpga2soc_ctrl;
+       u32     fpga_config;
+       u32     iocsrclk_gate;                  /* 0xe0 */
+       u32     gpo;
+       u32     gpi;
+       u32     _pad_0xec;
+       u32     mpu;                            /* 0xf0 */
+       u32     sdm_hps_spare;
+       u32     hps_sdm_spare;
+       u32     _pad_0xfc_0x1fc[65];
+       /* Boot scratch register group */
+       u32     boot_scratch_cold0;             /* 0x200 */
+       u32     boot_scratch_cold1;
+       u32     boot_scratch_cold2;
+       u32     boot_scratch_cold3;
+       u32     boot_scratch_cold4;             /* 0x210 */
+       u32     boot_scratch_cold5;
+       u32     boot_scratch_cold6;
+       u32     boot_scratch_cold7;
+       u32     boot_scratch_cold8;             /* 0x220 */
+       u32     boot_scratch_cold9;
+       u32     _pad_0x228_0xffc[886];
+       /* Pin select and pin control group */
+       u32     pinsel0[40];                    /* 0x1000 */
+       u32     _pad_0x10a0_0x10fc[24];
+       u32     pinsel40[8];
+       u32     _pad_0x1120_0x112c[4];
+       u32     ioctrl0[28];
+       u32     _pad_0x11a0_0x11fc[24];
+       u32     ioctrl28[20];
+       u32     _pad_0x1250_0x12fc[44];
+       /* Use FPGA mux */
+       u32     rgmii0usefpga;                  /* 0x1300 */
+       u32     rgmii1usefpga;
+       u32     rgmii2usefpga;
+       u32     i2c0usefpga;
+       u32     i2c1usefpga;
+       u32     i2c_emac0_usefpga;
+       u32     i2c_emac1_usefpga;
+       u32     i2c_emac2_usefpga;
+       u32     nandusefpga;
+       u32     _pad_0x1324;
+       u32     spim0usefpga;
+       u32     spim1usefpga;
+       u32     spis0usefpga;
+       u32     spis1usefpga;
+       u32     uart0usefpga;
+       u32     uart1usefpga;
+       u32     mdio0usefpga;
+       u32     mdio1usefpga;
+       u32     mdio2usefpga;
+       u32     _pad_0x134c;
+       u32     jtagusefpga;
+       u32     sdmmcusefpga;
+       u32     hps_osc_clk;
+       u32     _pad_0x135c_0x13fc[41];
+       u32     iodelay0[40];
+       u32     _pad_0x14a0_0x14fc[24];
+       u32     iodelay40[8];
+
+};
+
+#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGPINMUX        BIT(0)
+#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO    BIT(1)
+#define SYSMGR_ECC_OCRAM_EN    BIT(0)
+#define SYSMGR_ECC_OCRAM_SERR  BIT(3)
+#define SYSMGR_ECC_OCRAM_DERR  BIT(4)
+#define SYSMGR_FPGAINTF_USEFPGA        0x1
+
+#define SYSMGR_FPGAINTF_NAND   BIT(4)
+#define SYSMGR_FPGAINTF_SDMMC  BIT(8)
+#define SYSMGR_FPGAINTF_SPIM0  BIT(16)
+#define SYSMGR_FPGAINTF_SPIM1  BIT(24)
+#define SYSMGR_FPGAINTF_EMAC0  (0x11 << 0)
+#define SYSMGR_FPGAINTF_EMAC1  (0x11 << 8)
+#define SYSMGR_FPGAINTF_EMAC2  (0x11 << 16)
+
+#define SYSMGR_SDMMC_SMPLSEL_SHIFT     4
+#define SYSMGR_SDMMC_DRVSEL_SHIFT      0
+
+/* EMAC Group Bit definitions */
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII       0x0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII          0x1
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII           0x2
+
+#define SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB                        0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB                        2
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK                        0x3
+
+#define SYSMGR_NOC_H2F_MSK             0x00000001
+#define SYSMGR_NOC_LWH2F_MSK           0x00000010
+#define SYSMGR_HMC_CLK_STATUS_MSK      0x00000001
+
+#define SYSMGR_DMA_IRQ_NS              0xFF000000
+#define SYSMGR_DMA_MGR_NS              0x00010000
+
+#define SYSMGR_DMAPERIPH_ALL_NS                0xFFFFFFFF
+
+#define SYSMGR_WDDBG_PAUSE_ALL_CPU     0x0F0F0F0F
+
+#endif /* _SYSTEM_MANAGER_S10_ */
diff --git a/arch/arm/mach-socfpga/system_manager_s10.c b/arch/arm/mach-socfpga/system_manager_s10.c
new file mode 100644 (file)
index 0000000..122828c
--- /dev/null
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct socfpga_system_manager *sysmgr_regs =
+       (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
+
+/*
+ * Configure all the pin muxes
+ */
+void sysmgr_pinmux_init(void)
+{
+       populate_sysmgr_pinmux();
+       populate_sysmgr_fpgaintf_module();
+}
+
+/*
+ * Populate the value for SYSMGR.FPGAINTF.MODULE based on pinmux setting.
+ * The value is not wrote to SYSMGR.FPGAINTF.MODULE but
+ * CONFIG_SYSMGR_ISWGRP_HANDOFF.
+ */
+void populate_sysmgr_fpgaintf_module(void)
+{
+       u32 handoff_val = 0;
+
+       /* Enable the signal for those HPS peripherals that use FPGA. */
+       if (readl(&sysmgr_regs->nandusefpga) == SYSMGR_FPGAINTF_USEFPGA)
+               handoff_val |= SYSMGR_FPGAINTF_NAND;
+       if (readl(&sysmgr_regs->sdmmcusefpga) == SYSMGR_FPGAINTF_USEFPGA)
+               handoff_val |= SYSMGR_FPGAINTF_SDMMC;
+       if (readl(&sysmgr_regs->spim0usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+               handoff_val |= SYSMGR_FPGAINTF_SPIM0;
+       if (readl(&sysmgr_regs->spim1usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+               handoff_val |= SYSMGR_FPGAINTF_SPIM1;
+       writel(handoff_val, &sysmgr_regs->fpgaintf_en_2);
+
+       handoff_val = 0;
+       if (readl(&sysmgr_regs->rgmii0usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+               handoff_val |= SYSMGR_FPGAINTF_EMAC0;
+       if (readl(&sysmgr_regs->rgmii1usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+               handoff_val |= SYSMGR_FPGAINTF_EMAC1;
+       if (readl(&sysmgr_regs->rgmii2usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+               handoff_val |= SYSMGR_FPGAINTF_EMAC2;
+       writel(handoff_val, &sysmgr_regs->fpgaintf_en_3);
+}
+
+/*
+ * Configure all the pin muxes
+ */
+void populate_sysmgr_pinmux(void)
+{
+       const u32 *sys_mgr_table_u32;
+       unsigned int len, i;
+
+       /* setup the pin sel */
+       sysmgr_pinmux_table_sel(&sys_mgr_table_u32, &len);
+       for (i = 0; i < len; i = i + 2) {
+               writel(sys_mgr_table_u32[i + 1],
+                      sys_mgr_table_u32[i] + (u8 *)&sysmgr_regs->pinsel0[0]);
+       }
+
+       /* setup the pin ctrl */
+       sysmgr_pinmux_table_ctrl(&sys_mgr_table_u32, &len);
+       for (i = 0; i < len; i = i + 2) {
+               writel(sys_mgr_table_u32[i + 1],
+                      sys_mgr_table_u32[i] + (u8 *)&sysmgr_regs->ioctrl0[0]);
+       }
+
+       /* setup the fpga use */
+       sysmgr_pinmux_table_fpga(&sys_mgr_table_u32, &len);
+       for (i = 0; i < len; i = i + 2) {
+               writel(sys_mgr_table_u32[i + 1],
+                      sys_mgr_table_u32[i] +
+                      (u8 *)&sysmgr_regs->rgmii0usefpga);
+       }
+
+       /* setup the IO delay */
+       sysmgr_pinmux_table_delay(&sys_mgr_table_u32, &len);
+       for (i = 0; i < len; i = i + 2) {
+               writel(sys_mgr_table_u32[i + 1],
+                      sys_mgr_table_u32[i] + (u8 *)&sysmgr_regs->iodelay0[0]);
+       }
+}
diff --git a/arch/arm/mach-socfpga/wrap_pinmux_config_s10.c b/arch/arm/mach-socfpga/wrap_pinmux_config_s10.c
new file mode 100644 (file)
index 0000000..0b497ec
--- /dev/null
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/handoff_s10.h>
+
+static void sysmgr_pinmux_handoff_read(void *handoff_address,
+                                      const u32 **table,
+                                      unsigned int *table_len)
+{
+       unsigned int handoff_entry = (swab32(readl(handoff_address +
+                                       S10_HANDOFF_OFFSET_LENGTH)) -
+                                       S10_HANDOFF_OFFSET_DATA) /
+                                       sizeof(unsigned int);
+       unsigned int handoff_chunk[handoff_entry], temp, i;
+
+       if (swab32(readl(S10_HANDOFF_MUX)) == S10_HANDOFF_MAGIC_MUX) {
+               /* using handoff from Quartus tools if exists */
+               for (i = 0; i < handoff_entry; i++) {
+                       temp = readl(handoff_address +
+                                    S10_HANDOFF_OFFSET_DATA + (i * 4));
+                       handoff_chunk[i] = swab32(temp);
+               }
+               *table = handoff_chunk;
+               *table_len = ARRAY_SIZE(handoff_chunk);
+       }
+}
+
+void sysmgr_pinmux_table_sel(const u32 **table, unsigned int *table_len)
+{
+       sysmgr_pinmux_handoff_read((void *)S10_HANDOFF_MUX, table,
+                                  table_len);
+}
+
+void sysmgr_pinmux_table_ctrl(const u32 **table, unsigned int *table_len)
+{
+       sysmgr_pinmux_handoff_read((void *)S10_HANDOFF_IOCTL, table,
+                                  table_len);
+}
+
+void sysmgr_pinmux_table_fpga(const u32 **table, unsigned int *table_len)
+{
+       sysmgr_pinmux_handoff_read((void *)S10_HANDOFF_FPGA, table,
+                                  table_len);
+}
+
+void sysmgr_pinmux_table_delay(const u32 **table, unsigned int *table_len)
+{
+       sysmgr_pinmux_handoff_read((void *)S10_HANODFF_DELAY, table,
+                                  table_len);
+}