On 5/18/18 4:05 PM, Ley Foon Tan wrote: > Add pinmux driver support for Stratix SoC > > Signed-off-by: Chin Liang See <chin.liang....@intel.com> > Signed-off-by: Ley Foon Tan <ley.foon....@intel.com> > --- > arch/arm/mach-socfpga/Makefile | 2 + > .../arm/mach-socfpga/include/mach/system_manager.h | 5 +- > .../mach-socfpga/include/mach/system_manager_s10.h | 176 > ++++++++++++++++++++ > arch/arm/mach-socfpga/system_manager_s10.c | 91 ++++++++++ > arch/arm/mach-socfpga/wrap_pinmux_config_s10.c | 56 ++++++ > 5 files changed, 329 insertions(+), 1 deletions(-) > create mode 100644 arch/arm/mach-socfpga/include/mach/system_manager_s10.h > create mode 100644 arch/arm/mach-socfpga/system_manager_s10.c > create mode 100644 arch/arm/mach-socfpga/wrap_pinmux_config_s10.c > > diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile > index 69bdb84..61f5778 100644 > --- a/arch/arm/mach-socfpga/Makefile > +++ b/arch/arm/mach-socfpga/Makefile > @@ -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 > diff --git a/arch/arm/mach-socfpga/include/mach/system_manager.h > b/arch/arm/mach-socfpga/include/mach/system_manager.h > index fbe2a8b..7e76df7 100644 > --- a/arch/arm/mach-socfpga/include/mach/system_manager.h > +++ b/arch/arm/mach-socfpga/include/mach/system_manager.h > @@ -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 > index 0000000..813dff2 > --- /dev/null > +++ b/arch/arm/mach-socfpga/include/mach/system_manager_s10.h > @@ -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 > index 0000000..122828c > --- /dev/null > +++ b/arch/arm/mach-socfpga/system_manager_s10.c > @@ -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 > index 0000000..0b497ec > --- /dev/null > +++ b/arch/arm/mach-socfpga/wrap_pinmux_config_s10.c > @@ -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;
Here you are passing a variable that only exists on the stack to the caller. Shouldn't you either define handoff_chunk as static or malloc it? Indicated by CppCheck as [arch/arm/mach-socfpga/wrap_pinmux_config_s10.c:29]: (error) Address of local auto-variable assigned to a function parameter. Best regards Heinrich > + *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); > +} >