1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2016-2018 Intel Corporation <www.intel.com> 4 * 5 */ 6 7 #include <altera.h> 8 #include <common.h> 9 #include <errno.h> 10 #include <fdtdec.h> 11 #include <miiphy.h> 12 #include <netdev.h> 13 #include <asm/io.h> 14 #include <asm/arch/reset_manager.h> 15 #include <asm/arch/system_manager.h> 16 #include <asm/arch/misc.h> 17 #include <asm/pl310.h> 18 #include <linux/libfdt.h> 19 20 #include <dt-bindings/reset/altr,rst-mgr-s10.h> 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 static struct socfpga_system_manager *sysmgr_regs = 25 (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; 26 27 /* 28 * FPGA programming support for SoC FPGA Stratix 10 29 */ 30 static Altera_desc altera_fpga[] = { 31 { 32 /* Family */ 33 Intel_FPGA_Stratix10, 34 /* Interface type */ 35 secure_device_manager_mailbox, 36 /* No limitation as additional data will be ignored */ 37 -1, 38 /* No device function table */ 39 NULL, 40 /* Base interface address specified in driver */ 41 NULL, 42 /* No cookie implementation */ 43 0 44 }, 45 }; 46 47 /* 48 * DesignWare Ethernet initialization 49 */ 50 #ifdef CONFIG_ETH_DESIGNWARE 51 52 static u32 socfpga_phymode_setup(u32 gmac_index, const char *phymode) 53 { 54 u32 modereg; 55 56 if (!phymode) 57 return -EINVAL; 58 59 if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii") || 60 !strcmp(phymode, "sgmii")) 61 modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 62 else if (!strcmp(phymode, "rgmii")) 63 modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; 64 else if (!strcmp(phymode, "rmii")) 65 modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; 66 else 67 return -EINVAL; 68 69 clrsetbits_le32(&sysmgr_regs->emac0 + gmac_index, 70 SYSMGR_EMACGRP_CTRL_PHYSEL_MASK, 71 modereg); 72 73 return 0; 74 } 75 76 static int socfpga_set_phymode(void) 77 { 78 const void *fdt = gd->fdt_blob; 79 struct fdtdec_phandle_args args; 80 const char *phy_mode; 81 u32 gmac_index; 82 int nodes[3]; /* Max. 3 GMACs */ 83 int ret, count; 84 int i, node; 85 86 count = fdtdec_find_aliases_for_id(fdt, "ethernet", 87 COMPAT_ALTERA_SOCFPGA_DWMAC, 88 nodes, ARRAY_SIZE(nodes)); 89 for (i = 0; i < count; i++) { 90 node = nodes[i]; 91 if (node <= 0) 92 continue; 93 94 ret = fdtdec_parse_phandle_with_args(fdt, node, "resets", 95 "#reset-cells", 1, 0, 96 &args); 97 if (ret || args.args_count != 1) { 98 debug("GMAC%i: Failed to parse DT 'resets'!\n", i); 99 continue; 100 } 101 102 gmac_index = args.args[0] - EMAC0_RESET; 103 104 phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); 105 ret = socfpga_phymode_setup(gmac_index, phy_mode); 106 if (ret) { 107 debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); 108 continue; 109 } 110 } 111 112 return 0; 113 } 114 #else 115 static int socfpga_set_phymode(void) 116 { 117 return 0; 118 }; 119 #endif 120 121 /* 122 * Print CPU information 123 */ 124 #if defined(CONFIG_DISPLAY_CPUINFO) 125 int print_cpuinfo(void) 126 { 127 puts("CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A53)\n"); 128 129 return 0; 130 } 131 #endif 132 133 #ifdef CONFIG_ARCH_MISC_INIT 134 int arch_misc_init(void) 135 { 136 char qspi_string[13]; 137 138 sprintf(qspi_string, "<0x%08x>", cm_get_qspi_controller_clk_hz()); 139 env_set("qspi_clock", qspi_string); 140 141 socfpga_set_phymode(); 142 return 0; 143 } 144 #endif 145 146 int arch_early_init_r(void) 147 { 148 socfpga_fpga_add(&altera_fpga[0]); 149 150 return 0; 151 } 152 153 void do_bridge_reset(int enable) 154 { 155 socfpga_bridges_reset(enable); 156 } 157