// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2016-2018 Intel Corporation * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; /* * FPGA programming support for SoC FPGA Stratix 10 */ static Altera_desc altera_fpga[] = { { /* Family */ Intel_FPGA_Stratix10, /* Interface type */ secure_device_manager_mailbox, /* No limitation as additional data will be ignored */ -1, /* No device function table */ NULL, /* Base interface address specified in driver */ NULL, /* No cookie implementation */ 0 }, }; /* * DesignWare Ethernet initialization */ #ifdef CONFIG_ETH_DESIGNWARE static u32 socfpga_phymode_setup(u32 gmac_index, const char *phymode) { u32 modereg; if (!phymode) return -EINVAL; if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii") || !strcmp(phymode, "sgmii")) modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; else if (!strcmp(phymode, "rgmii")) modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; else if (!strcmp(phymode, "rmii")) modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; else return -EINVAL; clrsetbits_le32(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0 + (gmac_index * sizeof(u32)), SYSMGR_EMACGRP_CTRL_PHYSEL_MASK, modereg); return 0; } static int socfpga_set_phymode(void) { const void *fdt = gd->fdt_blob; struct fdtdec_phandle_args args; const char *phy_mode; u32 gmac_index; int nodes[3]; /* Max. 3 GMACs */ int ret, count; int i, node; 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; } gmac_index = args.args[0] - EMAC0_RESET; phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); ret = socfpga_phymode_setup(gmac_index, phy_mode); if (ret) { debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); continue; } } return 0; } #else static int socfpga_set_phymode(void) { return 0; }; #endif /* * Print CPU information */ #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo(void) { puts("CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A53)\n"); return 0; } #endif #ifdef CONFIG_ARCH_MISC_INIT int arch_misc_init(void) { char qspi_string[13]; sprintf(qspi_string, "<0x%08x>", cm_get_qspi_controller_clk_hz()); env_set("qspi_clock", qspi_string); socfpga_set_phymode(); return 0; } #endif int arch_early_init_r(void) { socfpga_fpga_add(&altera_fpga[0]); return 0; } /* Return 1 if FPGA is ready otherwise return 0 */ int is_fpga_config_ready(void) { return (readl(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_FPGA_CONFIG) & SYSMGR_FPGACONFIG_READY_MASK) == SYSMGR_FPGACONFIG_READY_MASK; } void do_bridge_reset(int enable, unsigned int mask) { /* Check FPGA status before bridge enable */ if (!is_fpga_config_ready()) { puts("FPGA not ready. Bridge reset aborted!\n"); return; } socfpga_bridges_reset(enable); }