[U-Boot] [PATCH 07/10] arm: socfpga: arria10: Added miscellaneous drivers for Arria10

From: Tien Fong Chee tien.fong.chee@intel.com
The drivers is restructured such common functions, gen5 functions, and arria10 functions are moved to misc.c, misc_gen5 and misc_arria10 respectively.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com Cc: Marek Vasut marex@denx.de Cc: Dinh Nguyen dinguyen@kernel.org Cc: Chin Liang See chin.liang.see@intel.com Cc: Tien Fong skywindctf@gmail.com --- arch/arm/mach-socfpga/Makefile | 4 +- arch/arm/mach-socfpga/include/mach/misc.h | 25 ++ arch/arm/mach-socfpga/misc.c | 429 +--------------------------- arch/arm/mach-socfpga/misc_arria10.c | 111 ++++++++ arch/arm/mach-socfpga/misc_gen5.c | 363 ++++++++++++++++++++++++ 5 files changed, 517 insertions(+), 415 deletions(-) create mode 100644 arch/arm/mach-socfpga/include/mach/misc.h create mode 100644 arch/arm/mach-socfpga/misc_arria10.c create mode 100644 arch/arm/mach-socfpga/misc_gen5.c
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index b8fcf6e..f8b529e 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -9,9 +9,9 @@
obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o \ fpga_manager.o board.o -obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += reset_manager_arria10.o +obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += reset_manager_arria10.o misc_arria10.o obj-$(CONFIG_TARGET_SOCFPGA_GEN5) += scan_manager.o wrap_pll_config.o \ - reset_manager_gen5.o + reset_manager_gen5.o misc_gen5.o
ifdef CONFIG_SPL_BUILD obj-y += spl.o diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h new file mode 100644 index 0000000..1bf1783 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016, Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _MISC_H_ +#define _MISC_H_ + +extern void dwmac_deassert_reset(const unsigned int of_reset_id, + const u32 phymode); + +struct bsel{ + const char *mode; + const char *name; +}; + +extern struct bsel bsel_str[]; + +#ifdef CONFIG_FPGA +extern void socfpga_fpga_add(void); +#else +inline void socfpga_fpga_add(void) {} +#endif +#endif /* _MISC_H_ */ diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c index 00e385f..f44233d 100644 --- a/arch/arm/mach-socfpga/misc.c +++ b/arch/arm/mach-socfpga/misc.c @@ -1,51 +1,39 @@ /* - * Copyright (C) 2012 Altera Corporation <www.altera.com> + * Copyright (C) 2012-2016 Altera Corporation <www.altera.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0 */
#include <common.h> #include <asm/io.h> #include <errno.h> -#include <fdtdec.h> -#include <libfdt.h> #include <altera.h> #include <miiphy.h> #include <netdev.h> #include <watchdog.h> +#include <asm/arch/misc.h> #include <asm/arch/reset_manager.h> -#include <asm/arch/scan_manager.h> #include <asm/arch/sdram_a10.h> #include <asm/arch/system_manager.h> #include <asm/arch/nic301.h> #include <asm/arch/scu.h> #include <asm/pl310.h>
-#if defined(CONFIG_TARGET_SOCFPGA_GEN5) -#include <dt-bindings/reset/altr,rst-mgr.h> -#else -#include <dt-bindings/reset/altr,rst-mgr-a10.h> -#endif - DECLARE_GLOBAL_DATA_PTR;
-static struct pl310_regs *const pl310 = +static const struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE; -static struct socfpga_system_manager *sysmgr_regs = - (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; -static struct socfpga_reset_manager *reset_manager_base = - (struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS; -#if defined(CONFIG_TARGET_SOCFPGA_GEN5) -static struct nic301_registers *nic301_regs = - (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; -#else -static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base = - (void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS; -static const struct socfpga_noc_fw_ddr_l3 *noc_fw_ddr_l3_base = - (void *)SOCFPGA_SDR_FIREWALL_L3_ADDRESS; -#endif -static struct scu_registers *scu_regs = - (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; + +struct bsel bsel_str[] = { + { "rsvd", "Reserved", }, + { "fpga", "FPGA (HPS2FPGA Bridge)", }, + { "nand", "NAND Flash (1.8V)", }, + { "nand", "NAND Flash (3.0V)", }, + { "sd", "SD/MMC External Transceiver (1.8V)", }, + { "sd", "SD/MMC Internal Transceiver (3.0V)", }, + { "qspi", "QSPI Flash (1.8V)", }, + { "qspi", "QSPI Flash (3.0V)", }, +};
int dram_init(void) { @@ -84,219 +72,6 @@ void v7_outer_cache_disable(void) clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); }
-/* - * DesignWare Ethernet initialization - */ -#ifdef CONFIG_ETH_DESIGNWARE -static void dwmac_deassert_reset(const unsigned int of_reset_id, - const u32 phymode) -{ - u32 physhift, reset; - - if (of_reset_id == EMAC0_RESET) { - physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; - reset = SOCFPGA_RESET(EMAC0); - } else if (of_reset_id == EMAC1_RESET) { - physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; - reset = SOCFPGA_RESET(EMAC1); -#ifndef CONFIG_TARGET_SOCFPGA_GEN5 - } else if (of_reset_id == EMAC2_RESET) { - reset = SOCFPGA_RESET(EMAC2); -#endif - } else { - printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id); - return; - } - -#if defined(CONFIG_TARGET_SOCFPGA_GEN5) - /* configure to PHY interface select choosed */ - clrsetbits_le32(&sysmgr_regs->emacgrp_ctrl, - SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift, - phymode << physhift); -#else - clrsetbits_le32(&sysmgr_regs->emac[of_reset_id - EMAC0_RESET], - SYSMGR_EMACGRP_CTRL_PHYSEL_MASK, - phymode); -#endif - - /* Release the EMAC controller from reset */ - socfpga_per_reset(reset, 0); -} - -static u32 dwmac_phymode_to_modereg(const char *phymode, u32 *modereg) -{ - if (!phymode) - return -EINVAL; - - if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; - return 0; - } - - if (!strcmp(phymode, "rgmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; - return 0; - } - - if (!strcmp(phymode, "rmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; - return 0; - } - - return -EINVAL; -} - -static int socfpga_eth_reset(void) -{ - const void *fdt = gd->fdt_blob; - struct fdtdec_phandle_args args; - const char *phy_mode; - u32 phy_modereg; - int nodes[2]; /* Max. two GMACs */ - int ret, count; - int i, node; - - /* Put both GMACs into RESET state. */ - socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1); - socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1); - - count = fdtdec_find_aliases_for_id(fdt, "ethernet", - COMPAT_ALTERA_SOCFPGA_DWMAC, - nodes, ARRAY_SIZE(nodes)); - for (i = 0; i < count; i++) { - node = nodes[i]; - if (node <= 0) - continue; - - ret = fdtdec_parse_phandle_with_args(fdt, node, "resets", - "#reset-cells", 1, 0, - &args); - if (ret || (args.args_count != 1)) { - debug("GMAC%i: Failed to parse DT 'resets'!\n", i); - continue; - } - - phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); - ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg); - if (ret) { - debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); - continue; - } - - dwmac_deassert_reset(args.args[0], phy_modereg); - } - - return 0; -} -#else -static int socfpga_eth_reset(void) -{ - return 0; -}; -#endif - -struct { - const char *mode; - const char *name; -} bsel_str[] = { - { "rsvd", "Reserved", }, - { "fpga", "FPGA (HPS2FPGA Bridge)", }, - { "nand", "NAND Flash (1.8V)", }, - { "nand", "NAND Flash (3.0V)", }, - { "sd", "SD/MMC External Transceiver (1.8V)", }, - { "sd", "SD/MMC Internal Transceiver (3.0V)", }, - { "qspi", "QSPI Flash (1.8V)", }, - { "qspi", "QSPI Flash (3.0V)", }, -}; - -static const struct { - const u16 pn; - const char *name; - const char *var; -} const socfpga_fpga_model[] = { - /* Cyclone V E */ - { 0x2b15, "Cyclone V, E/A2", "cv_e_a2" }, - { 0x2b05, "Cyclone V, E/A4", "cv_e_a4" }, - { 0x2b22, "Cyclone V, E/A5", "cv_e_a5" }, - { 0x2b13, "Cyclone V, E/A7", "cv_e_a7" }, - { 0x2b14, "Cyclone V, E/A9", "cv_e_a9" }, - /* Cyclone V GX/GT */ - { 0x2b01, "Cyclone V, GX/C3", "cv_gx_c3" }, - { 0x2b12, "Cyclone V, GX/C4", "cv_gx_c4" }, - { 0x2b02, "Cyclone V, GX/C5 or GT/D5", "cv_gx_c5" }, - { 0x2b03, "Cyclone V, GX/C7 or GT/D7", "cv_gx_c7" }, - { 0x2b04, "Cyclone V, GX/C9 or GT/D9", "cv_gx_c9" }, - /* Cyclone V SE/SX/ST */ - { 0x2d11, "Cyclone V, SE/A2 or SX/C2", "cv_se_a2" }, - { 0x2d01, "Cyclone V, SE/A4 or SX/C4", "cv_se_a4" }, - { 0x2d12, "Cyclone V, SE/A5 or SX/C5 or ST/D5", "cv_se_a5" }, - { 0x2d02, "Cyclone V, SE/A6 or SX/C6 or ST/D6", "cv_se_a6" }, - /* Arria V */ - { 0x2d03, "Arria V, D5", "av_d5" }, -}; - -static int socfpga_fpga_id(const bool print_id) -{ - const u32 altera_mi = 0x6e; - const u32 id = scan_mgr_get_fpga_id(); - - const u32 lsb = id & 0x00000001; - const u32 mi = (id >> 1) & 0x000007ff; - const u32 pn = (id >> 12) & 0x0000ffff; - const u32 version = (id >> 28) & 0x0000000f; - int i; - - if ((mi != altera_mi) || (lsb != 1)) { - printf("FPGA: Not Altera chip ID\n"); - return -EINVAL; - } - - for (i = 0; i < ARRAY_SIZE(socfpga_fpga_model); i++) - if (pn == socfpga_fpga_model[i].pn) - break; - - if (i == ARRAY_SIZE(socfpga_fpga_model)) { - printf("FPGA: Unknown Altera chip, ID 0x%08x\n", id); - return -EINVAL; - } - - if (print_id) - printf("FPGA: Altera %s, version 0x%01x\n", - socfpga_fpga_model[i].name, version); - return i; -} - -/* - * Print CPU information - */ -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - const u32 bsel = (readl(&sysmgr_regs->bootinfo) >> - SYSMGR_BOOTINFO_BSEL_SHIFT) & 0x7; -#if defined(CONFIG_TARGET_SOCFPGA_GEN5) - puts("CPU: Altera SoCFPGA Platform\n"); - socfpga_fpga_id(1); -#else - puts("CPU: Altera SoCFPGA Arria 10\n"); -#endif - printf("BOOT: %s\n", bsel_str[bsel].name); - return 0; -} -#endif - -#ifdef CONFIG_ARCH_MISC_INIT -int arch_misc_init(void) -{ - const u32 bsel = readl(&sysmgr_regs->bootinfo) & 0x7; - const int fpga_id = socfpga_fpga_id(0); - setenv("bootmode", bsel_str[bsel].mode); - if (fpga_id >= 0) - setenv("fpgatype", socfpga_fpga_model[fpga_id].var); - return socfpga_eth_reset(); -} -#endif - #if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) int overwrite_console(void) @@ -327,15 +102,13 @@ static Altera_desc altera_fpga[] = { };
/* add device descriptor to FPGA device table */ -static void socfpga_fpga_add(void) +void socfpga_fpga_add(void) { int i; fpga_init(); for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) fpga_add(fpga_altera, &altera_fpga[i]); } -#else -static inline void socfpga_fpga_add(void) {} #endif
int arch_cpu_init(void) @@ -361,173 +134,3 @@ int arch_cpu_init(void)
return 0; } - -#if defined(CONFIG_TARGET_SOCFPGA_GEN5) -/* - * Convert all NIC-301 AMBA slaves from secure to non-secure - */ -static void socfpga_nic301_slave_ns(void) -{ - writel(0x1, &nic301_regs->lwhps2fpgaregs); - writel(0x1, &nic301_regs->hps2fpgaregs); - writel(0x1, &nic301_regs->acp); - writel(0x1, &nic301_regs->rom); - writel(0x1, &nic301_regs->ocram); - writel(0x1, &nic301_regs->sdrdata); -} - -static uint32_t iswgrp_handoff[8]; - -int arch_early_init_r(void) -{ - int i; - - /* - * Write magic value into magic register to unlock support for - * issuing warm reset. The ancient kernel code expects this - * value to be written into the register by the bootloader, so - * to support that old code, we write it here instead of in the - * reset_cpu() function just before reseting the CPU. - */ - writel(0xae9efebc, &sysmgr_regs->romcodegrp_warmramgrp_enable); - - for (i = 0; i < 8; i++) /* Cache initial SW setting regs */ - iswgrp_handoff[i] = readl(&sysmgr_regs->iswgrp_handoff[i]); - - socfpga_bridges_reset(1); - socfpga_nic301_slave_ns(); - - /* - * Private components security: - * U-Boot : configure private timer, global timer and cpu component - * access as non secure for kernel stage (as required by Linux) - */ - setbits_le32(&scu_regs->sacr, 0xfff); - - /* Configure the L2 controller to make SDRAM start at 0 */ -#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET - writel(0x2, &nic301_regs->remap); -#else - writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ - writel(0x1, &pl310->pl310_addr_filter_start); -#endif - - /* Add device descriptor to FPGA device table */ - socfpga_fpga_add(); - -#ifdef CONFIG_DESIGNWARE_SPI - /* Get Designware SPI controller out of reset */ - socfpga_per_reset(SOCFPGA_RESET(SPIM0), 0); - socfpga_per_reset(SOCFPGA_RESET(SPIM1), 0); -#endif - -#ifdef CONFIG_NAND_DENALI - socfpga_per_reset(SOCFPGA_RESET(NAND), 0); -#endif - - return 0; -} - -static void socfpga_sdram_apply_static_cfg(void) -{ - const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c; - const uint32_t applymask = 0x8; - uint32_t val = readl(staticcfg) | applymask; - - /* - * SDRAM staticcfg register specific: - * When applying the register setting, the CPU must not access - * SDRAM. Luckily for us, we can abuse i-cache here to help us - * circumvent the SDRAM access issue. The idea is to make sure - * that the code is in one full i-cache line by branching past - * it and back. Once it is in the i-cache, we execute the core - * of the code and apply the register settings. - * - * The code below uses 7 instructions, while the Cortex-A9 has - * 32-byte cachelines, thus the limit is 8 instructions total. - */ - asm volatile( - ".align 5 \n" - " b 2f \n" - "1: str %0, [%1] \n" - " dsb \n" - " isb \n" - " b 3f \n" - "2: b 1b \n" - "3: nop \n" - : : "r"(val), "r"(staticcfg) : "memory", "cc"); -} - -int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - if (argc != 2) - return CMD_RET_USAGE; - - argv++; - - switch (*argv[0]) { - case 'e': /* Enable */ - writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module); - socfpga_sdram_apply_static_cfg(); - writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080); - writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); - writel(iswgrp_handoff[1], &nic301_regs->remap); - break; - case 'd': /* Disable */ - writel(0, &sysmgr_regs->fpgaintfgrp_module); - writel(0, SOCFPGA_SDR_ADDRESS + 0x5080); - socfpga_sdram_apply_static_cfg(); - writel(0, &reset_manager_base->brg_mod_reset); - writel(1, &nic301_regs->remap); - break; - default: - return CMD_RET_USAGE; - } - - return 0; -} -#else -/* -+ * This function initializes security policies to be consistent across -+ * all logic units in the Arria 10. -+ * -+ * The idea is to set all security policies to be normal, nonsecure -+ * for all units. -+ */ -static void initialize_security_policies(void) -{ - /* Put OCRAM in non-secure */ - writel(0x003f0000, &noc_fw_ocram_base->region0); - writel(0x1, &noc_fw_ocram_base->enable); - - /* Put DDR in non-secure */ - writel(0xffff0000, &noc_fw_ddr_l3_base->hpsregion0addr); - writel(0x1, &noc_fw_ddr_l3_base->enable); -} - -int arch_early_init_r(void) -{ - initialize_security_policies(); - - /* Configure the L2 controller to make SDRAM start at 0 */ - writel(0x1, &pl310->pl310_addr_filter_start); - - /* assert reset to all except L4WD0 and L4TIMER0 */ - socfpga_per_reset_all(); - - /* configuring the clock based on handoff */ - /* TODO: Add call to cm_basic_init() */ - - /* Add device descriptor to FPGA device table */ - socfpga_fpga_add(); - return 0; -} -#endif - -U_BOOT_CMD( - bridge, 2, 1, do_bridge, - "SoCFPGA HPS FPGA bridge control", - "enable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" - "bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" - "" -); diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c new file mode 100644 index 0000000..b0bc51c --- /dev/null +++ b/arch/arm/mach-socfpga/misc_arria10.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2016, Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <altera.h> +#include <miiphy.h> +#include <netdev.h> +#include <watchdog.h> +#include <asm/arch/misc.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/sdram_a10.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/nic301.h> +#include <asm/pl310.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; +static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base = + (void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS; +static const struct socfpga_noc_fw_ddr_l3 *noc_fw_ddr_l3_base = + (void *)SOCFPGA_SDR_FIREWALL_L3_ADDRESS; + +/* + * DesignWare Ethernet initialization + */ +#ifdef CONFIG_ETH_DESIGNWARE +void dwmac_deassert_reset(const unsigned int of_reset_id, + const u32 phymode) +{ + u32 reset; + + if (of_reset_id == EMAC0_RESET) { + reset = SOCFPGA_RESET(EMAC0); + } else if (of_reset_id == EMAC1_RESET) { + reset = SOCFPGA_RESET(EMAC1); + } else if (of_reset_id == EMAC2_RESET) { + reset = SOCFPGA_RESET(EMAC2); + } else { + printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id); + return; + } + + clrsetbits_le32(&sysmgr_regs->emac[of_reset_id - EMAC0_RESET], + SYSMGR_EMACGRP_CTRL_PHYSEL_MASK, + phymode); + + /* Release the EMAC controller from reset */ + socfpga_per_reset(reset, 0); +} +#endif + +/* ++ * This function initializes security policies to be consistent across ++ * all logic units in the Arria 10. ++ * ++ * The idea is to set all security policies to be normal, nonsecure ++ * for all units. ++ */ +static void initialize_security_policies(void) +{ + /* Put OCRAM in non-secure */ + writel(0x003f0000, &noc_fw_ocram_base->region0); + writel(0x1, &noc_fw_ocram_base->enable); + + /* Put DDR in non-secure */ + writel(0xffff0000, &noc_fw_ddr_l3_base->hpsregion0addr); + writel(0x1, &noc_fw_ddr_l3_base->enable); +} + +int arch_early_init_r(void) +{ + initialize_security_policies(); + + /* Configure the L2 controller to make SDRAM start at 0 */ + writel(0x1, &pl310->pl310_addr_filter_start); + + /* assert reset to all except L4WD0 and L4TIMER0 */ + socfpga_per_reset_all(); + + /* configuring the clock based on handoff */ + /* TODO: Add call to cm_basic_init() */ + + /* Add device descriptor to FPGA device table */ + socfpga_fpga_add(); + return 0; +} + +/* + * Print CPU information + */ +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + const u32 bsel = (readl(&sysmgr_regs->bootinfo) >> + SYSMGR_BOOTINFO_BSEL_SHIFT) & 0x7; + + puts("CPU: Altera SoCFPGA Arria 10\n"); + + printf("BOOT: %s\n", bsel_str[bsel].name); + return 0; +} +#endif diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c new file mode 100644 index 0000000..b91aeb1 --- /dev/null +++ b/arch/arm/mach-socfpga/misc_gen5.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2016, Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <altera.h> +#include <miiphy.h> +#include <netdev.h> +#include <watchdog.h> +#include <asm/arch/misc.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/scan_manager.h> +#include <asm/arch/sdram_a10.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/nic301.h> +#include <asm/arch/scu.h> +#include <asm/pl310.h> +#include <dt-bindings/reset/altr,rst-mgr.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; +static struct socfpga_reset_manager *reset_manager_base = + (struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS; +static struct nic301_registers *nic301_regs = + (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; +static struct scu_registers *scu_regs = + (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; + +/* + * DesignWare Ethernet initialization + */ +#ifdef CONFIG_ETH_DESIGNWARE +void dwmac_deassert_reset(const unsigned int of_reset_id, + const u32 phymode) +{ + u32 physhift; + u32 reset; + + if (of_reset_id == EMAC0_RESET) { + physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; + + reset = SOCFPGA_RESET(EMAC0); + } else if (of_reset_id == EMAC1_RESET) { + physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; + + reset = SOCFPGA_RESET(EMAC1); + } + else { + printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id); + return; + } + + /* configure to PHY interface select choosed */ + clrsetbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift, + phymode << physhift); + + /* Release the EMAC controller from reset */ + socfpga_per_reset(reset, 0); +} + +/* + * DesignWare Ethernet initialization + */ +static u32 dwmac_phymode_to_modereg(const char *phymode, u32 *modereg) +{ + if (!phymode) + return -EINVAL; + + if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) { + *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; + return 0; + } + + if (!strcmp(phymode, "rgmii")) { + *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; + return 0; + } + + if (!strcmp(phymode, "rmii")) { + *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; + return 0; + } + + return -EINVAL; +} + +static int socfpga_eth_reset(void) +{ + const void *fdt = gd->fdt_blob; + struct fdtdec_phandle_args args; + const char *phy_mode; + u32 phy_modereg; + int nodes[2]; /* Max. two GMACs */ + int ret, count; + int i, node; + + /* Put both GMACs into RESET state. */ + socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1); + socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1); + + count = fdtdec_find_aliases_for_id(fdt, "ethernet", + COMPAT_ALTERA_SOCFPGA_DWMAC, + nodes, ARRAY_SIZE(nodes)); + for (i = 0; i < count; i++) { + node = nodes[i]; + if (node <= 0) + continue; + + ret = fdtdec_parse_phandle_with_args(fdt, node, "resets", + "#reset-cells", 1, 0, + &args); + if (ret || (args.args_count != 1)) { + debug("GMAC%i: Failed to parse DT 'resets'!\n", i); + continue; + } + + phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); + ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg); + if (ret) { + debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); + continue; + } + + dwmac_deassert_reset(args.args[0], phy_modereg); + } + + return 0; +} +#else +static int socfpga_eth_reset(void) +{ + return 0; +}; +#endif + +static const struct { + const u16 pn; + const char *name; + const char *var; +} const socfpga_fpga_model[] = { + /* Cyclone V E */ + { 0x2b15, "Cyclone V, E/A2", "cv_e_a2" }, + { 0x2b05, "Cyclone V, E/A4", "cv_e_a4" }, + { 0x2b22, "Cyclone V, E/A5", "cv_e_a5" }, + { 0x2b13, "Cyclone V, E/A7", "cv_e_a7" }, + { 0x2b14, "Cyclone V, E/A9", "cv_e_a9" }, + /* Cyclone V GX/GT */ + { 0x2b01, "Cyclone V, GX/C3", "cv_gx_c3" }, + { 0x2b12, "Cyclone V, GX/C4", "cv_gx_c4" }, + { 0x2b02, "Cyclone V, GX/C5 or GT/D5", "cv_gx_c5" }, + { 0x2b03, "Cyclone V, GX/C7 or GT/D7", "cv_gx_c7" }, + { 0x2b04, "Cyclone V, GX/C9 or GT/D9", "cv_gx_c9" }, + /* Cyclone V SE/SX/ST */ + { 0x2d11, "Cyclone V, SE/A2 or SX/C2", "cv_se_a2" }, + { 0x2d01, "Cyclone V, SE/A4 or SX/C4", "cv_se_a4" }, + { 0x2d12, "Cyclone V, SE/A5 or SX/C5 or ST/D5", "cv_se_a5" }, + { 0x2d02, "Cyclone V, SE/A6 or SX/C6 or ST/D6", "cv_se_a6" }, + /* Arria V */ + { 0x2d03, "Arria V, D5", "av_d5" }, +}; + +static int socfpga_fpga_id(const bool print_id) +{ + const u32 altera_mi = 0x6e; + const u32 id = scan_mgr_get_fpga_id(); + + const u32 lsb = id & 0x00000001; + const u32 mi = (id >> 1) & 0x000007ff; + const u32 pn = (id >> 12) & 0x0000ffff; + const u32 version = (id >> 28) & 0x0000000f; + int i; + + if ((mi != altera_mi) || (lsb != 1)) { + printf("FPGA: Not Altera chip ID\n"); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(socfpga_fpga_model); i++) + if (pn == socfpga_fpga_model[i].pn) + break; + + if (i == ARRAY_SIZE(socfpga_fpga_model)) { + printf("FPGA: Unknown Altera chip, ID 0x%08x\n", id); + return -EINVAL; + } + + if (print_id) + printf("FPGA: Altera %s, version 0x%01x\n", + socfpga_fpga_model[i].name, version); + return i; +} + +#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{ + const u32 bsel = readl(&sysmgr_regs->bootinfo) & 0x7; + const int fpga_id = socfpga_fpga_id(0); + setenv("bootmode", bsel_str[bsel].mode); + if (fpga_id >= 0) + setenv("fpgatype", socfpga_fpga_model[fpga_id].var); + return socfpga_eth_reset(); +} +#endif + +/* + * Convert all NIC-301 AMBA slaves from secure to non-secure + */ +static void socfpga_nic301_slave_ns(void) +{ + writel(0x1, &nic301_regs->lwhps2fpgaregs); + writel(0x1, &nic301_regs->hps2fpgaregs); + writel(0x1, &nic301_regs->acp); + writel(0x1, &nic301_regs->rom); + writel(0x1, &nic301_regs->ocram); + writel(0x1, &nic301_regs->sdrdata); +} + +static uint32_t iswgrp_handoff[8]; + +int arch_early_init_r(void) +{ + int i; + + /* + * Write magic value into magic register to unlock support for + * issuing warm reset. The ancient kernel code expects this + * value to be written into the register by the bootloader, so + * to support that old code, we write it here instead of in the + * reset_cpu() function just before reseting the CPU. + */ + writel(0xae9efebc, &sysmgr_regs->romcodegrp_warmramgrp_enable); + + for (i = 0; i < 8; i++) /* Cache initial SW setting regs */ + iswgrp_handoff[i] = readl(&sysmgr_regs->iswgrp_handoff[i]); + + socfpga_bridges_reset(1); + socfpga_nic301_slave_ns(); + + /* + * Private components security: + * U-Boot : configure private timer, global timer and cpu component + * access as non secure for kernel stage (as required by Linux) + */ + setbits_le32(&scu_regs->sacr, 0xfff); + + /* Configure the L2 controller to make SDRAM start at 0 */ +#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET + writel(0x2, &nic301_regs->remap); +#else + writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ + writel(0x1, &pl310->pl310_addr_filter_start); +#endif + + /* Add device descriptor to FPGA device table */ + socfpga_fpga_add(); + +#ifdef CONFIG_DESIGNWARE_SPI + /* Get Designware SPI controller out of reset */ + socfpga_per_reset(SOCFPGA_RESET(SPIM0), 0); + socfpga_per_reset(SOCFPGA_RESET(SPIM1), 0); +#endif + +#ifdef CONFIG_NAND_DENALI + socfpga_per_reset(SOCFPGA_RESET(NAND), 0); +#endif + + return 0; +} + +static void socfpga_sdram_apply_static_cfg(void) +{ + const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c; + const uint32_t applymask = 0x8; + uint32_t val = readl(staticcfg) | applymask; + + /* + * SDRAM staticcfg register specific: + * When applying the register setting, the CPU must not access + * SDRAM. Luckily for us, we can abuse i-cache here to help us + * circumvent the SDRAM access issue. The idea is to make sure + * that the code is in one full i-cache line by branching past + * it and back. Once it is in the i-cache, we execute the core + * of the code and apply the register settings. + * + * The code below uses 7 instructions, while the Cortex-A9 has + * 32-byte cachelines, thus the limit is 8 instructions total. + */ + asm volatile( + ".align 5 \n" + " b 2f \n" + "1: str %0, [%1] \n" + " dsb \n" + " isb \n" + " b 3f \n" + "2: b 1b \n" + "3: nop \n" + : : "r"(val), "r"(staticcfg) : "memory", "cc"); +} + +int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc != 2) + return CMD_RET_USAGE; + + argv++; + + switch (*argv[0]) { + case 'e': /* Enable */ + writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module); + socfpga_sdram_apply_static_cfg(); + writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080); + writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); + writel(iswgrp_handoff[1], &nic301_regs->remap); + break; + case 'd': /* Disable */ + writel(0, &sysmgr_regs->fpgaintfgrp_module); + writel(0, SOCFPGA_SDR_ADDRESS + 0x5080); + socfpga_sdram_apply_static_cfg(); + writel(0, &reset_manager_base->brg_mod_reset); + writel(1, &nic301_regs->remap); + break; + default: + return CMD_RET_USAGE; + } + + return 0; +} + +U_BOOT_CMD( + bridge, 2, 1, do_bridge, + "SoCFPGA HPS FPGA bridge control", + "enable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" + "bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" + "" +); + +/* + * Print CPU information + */ +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + const u32 bsel = (readl(&sysmgr_regs->bootinfo) >> + SYSMGR_BOOTINFO_BSEL_SHIFT) & 0x7; + + puts("CPU: Altera SoCFPGA Platform\n"); + socfpga_fpga_id(1); + + printf("BOOT: %s\n", bsel_str[bsel].name); + return 0; +} +#endif

On Tue, 6 Dec 2016, Chee Tien Fong wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
The drivers is restructured such common functions, gen5 functions, and arria10 functions are moved to misc.c, misc_gen5 and misc_arria10 respectively.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com Cc: Marek Vasut marex@denx.de Cc: Dinh Nguyen dinguyen@kernel.org Cc: Chin Liang See chin.liang.see@intel.com Cc: Tien Fong skywindctf@gmail.com
arch/arm/mach-socfpga/Makefile | 4 +- arch/arm/mach-socfpga/include/mach/misc.h | 25 ++ arch/arm/mach-socfpga/misc.c | 429 +--------------------------- arch/arm/mach-socfpga/misc_arria10.c | 111 ++++++++ arch/arm/mach-socfpga/misc_gen5.c | 363 ++++++++++++++++++++++++ 5 files changed, 517 insertions(+), 415 deletions(-) create mode 100644 arch/arm/mach-socfpga/include/mach/misc.h create mode 100644 arch/arm/mach-socfpga/misc_arria10.c create mode 100644 arch/arm/mach-socfpga/misc_gen5.c
The previous patches in this series applied to Marek's 01-arria10 branch, but this patch does not apply at all:
error: patch failed: arch/arm/mach-socfpga/misc.c:361 error: arch/arm/mach-socfpga/misc.c: patch does not apply
Also, on the next revision, please add -C to git format-patch.
Dinh

On 12/06/2016 11:26 PM, dinguyen wrote:
On Tue, 6 Dec 2016, Chee Tien Fong wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
The drivers is restructured such common functions, gen5 functions, and arria10 functions are moved to misc.c, misc_gen5 and misc_arria10 respectively.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com Cc: Marek Vasut marex@denx.de Cc: Dinh Nguyen dinguyen@kernel.org Cc: Chin Liang See chin.liang.see@intel.com Cc: Tien Fong skywindctf@gmail.com
arch/arm/mach-socfpga/Makefile | 4 +- arch/arm/mach-socfpga/include/mach/misc.h | 25 ++ arch/arm/mach-socfpga/misc.c | 429 +--------------------------- arch/arm/mach-socfpga/misc_arria10.c | 111 ++++++++ arch/arm/mach-socfpga/misc_gen5.c | 363 ++++++++++++++++++++++++ 5 files changed, 517 insertions(+), 415 deletions(-) create mode 100644 arch/arm/mach-socfpga/include/mach/misc.h create mode 100644 arch/arm/mach-socfpga/misc_arria10.c create mode 100644 arch/arm/mach-socfpga/misc_gen5.c
The previous patches in this series applied to Marek's 01-arria10 branch, but this patch does not apply at all:
error: patch failed: arch/arm/mach-socfpga/misc.c:361 error: arch/arm/mach-socfpga/misc.c: patch does not apply
Also, on the next revision, please add -C to git format-patch.
I was tempted to discard that arria 10 patchset from the tree, I've been trying to keep it kinda in sync, but it's probably broken. If you plan to submit A10, just start on u-boot/master and -- if we all agree -- I'll discard the 01-arria10 branch. The current situation is chaos.

On 12/06/2016 05:41 PM, Marek Vasut wrote:
The previous patches in this series applied to Marek's 01-arria10 branch, but this patch does not apply at all:
error: patch failed: arch/arm/mach-socfpga/misc.c:361 error: arch/arm/mach-socfpga/misc.c: patch does not apply
Also, on the next revision, please add -C to git format-patch.
I was tempted to discard that arria 10 patchset from the tree, I've been trying to keep it kinda in sync, but it's probably broken. If you plan to submit A10, just start on u-boot/master and -- if we all agree -- I'll discard the 01-arria10 branch. The current situation is chaos.
I agree that it is a bit chaotic. I'll let you make the decision, since I have not been actively sending patches for A10. That is Tien Fong's and Chin Liang's job now.
BTW, really appreciate the work to keep the 01-arria10 branch alive for all this time.
Dinh

On 12/07/2016 04:05 PM, Dinh Nguyen wrote:
On 12/06/2016 05:41 PM, Marek Vasut wrote:
The previous patches in this series applied to Marek's 01-arria10 branch, but this patch does not apply at all:
error: patch failed: arch/arm/mach-socfpga/misc.c:361 error: arch/arm/mach-socfpga/misc.c: patch does not apply
Also, on the next revision, please add -C to git format-patch.
I was tempted to discard that arria 10 patchset from the tree, I've been trying to keep it kinda in sync, but it's probably broken. If you plan to submit A10, just start on u-boot/master and -- if we all agree -- I'll discard the 01-arria10 branch. The current situation is chaos.
I agree that it is a bit chaotic. I'll let you make the decision, since I have not been actively sending patches for A10. That is Tien Fong's and Chin Liang's job now.
Yeah :-)
BTW, really appreciate the work to keep the 01-arria10 branch alive for all this time.
No problem, although I think bitrot has set in .

On Sel, 2016-12-06 at 16:26 -0600, dinguyen wrote:
On Tue, 6 Dec 2016, Chee Tien Fong wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
The drivers is restructured such common functions, gen5 functions, and arria10 functions are moved to misc.c, misc_gen5 and misc_arria10 respectively.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com Cc: Marek Vasut marex@denx.de Cc: Dinh Nguyen dinguyen@kernel.org Cc: Chin Liang See chin.liang.see@intel.com Cc: Tien Fong skywindctf@gmail.com
arch/arm/mach-socfpga/Makefile | 4 +- arch/arm/mach-socfpga/include/mach/misc.h | 25 ++ arch/arm/mach-socfpga/misc.c | 429 +--------------
arch/arm/mach-socfpga/misc_arria10.c | 111 ++++++++ arch/arm/mach-socfpga/misc_gen5.c | 363 ++++++++++++++++++++++++ 5 files changed, 517 insertions(+), 415 deletions(-) create mode 100644 arch/arm/mach-socfpga/include/mach/misc.h create mode 100644 arch/arm/mach-socfpga/misc_arria10.c create mode 100644 arch/arm/mach-socfpga/misc_gen5.c
The previous patches in this series applied to Marek's 01-arria10 branch, but this patch does not apply at all:
error: patch failed: arch/arm/mach-socfpga/misc.c:361 error: arch/arm/mach-socfpga/misc.c: patch does not apply
Also, on the next revision, please add -C to git format-patch.
Dinh
Sorry to hear that. It is too weird the patch didn't applied, but i have no issue with this patch. Are you using git am command?

On 12/07/2016 06:04 AM, Chee, Tien Fong wrote:
The previous patches in this series applied to Marek's 01-arria10 branch, but this patch does not apply at all:
error: patch failed: arch/arm/mach-socfpga/misc.c:361 error: arch/arm/mach-socfpga/misc.c: patch does not apply
Also, on the next revision, please add -C to git format-patch.
Dinh
Sorry to hear that. It is too weird the patch didn't applied, but i have no issue with this patch. Are you using git am command?
I tried everything...git am and git apply. Perhaps you have some uncommitted changes in your branch?
Dinh
participants (5)
-
Chee Tien Fong
-
Chee, Tien Fong
-
dinguyen
-
Dinh Nguyen
-
Marek Vasut