1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> 4 */ 5 6 #include <common.h> 7 #include <asm/io.h> 8 #include <errno.h> 9 #include <fdtdec.h> 10 #include <linux/libfdt.h> 11 #include <altera.h> 12 #include <miiphy.h> 13 #include <netdev.h> 14 #include <watchdog.h> 15 #include <asm/arch/misc.h> 16 #include <asm/arch/reset_manager.h> 17 #include <asm/arch/scan_manager.h> 18 #include <asm/arch/system_manager.h> 19 #include <asm/arch/nic301.h> 20 #include <asm/arch/scu.h> 21 #include <asm/pl310.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 #ifdef CONFIG_SYS_L2_PL310 26 static const struct pl310_regs *const pl310 = 27 (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 28 #endif 29 30 struct bsel bsel_str[] = { 31 { "rsvd", "Reserved", }, 32 { "fpga", "FPGA (HPS2FPGA Bridge)", }, 33 { "nand", "NAND Flash (1.8V)", }, 34 { "nand", "NAND Flash (3.0V)", }, 35 { "sd", "SD/MMC External Transceiver (1.8V)", }, 36 { "sd", "SD/MMC Internal Transceiver (3.0V)", }, 37 { "qspi", "QSPI Flash (1.8V)", }, 38 { "qspi", "QSPI Flash (3.0V)", }, 39 }; 40 41 int dram_init(void) 42 { 43 if (fdtdec_setup_mem_size_base() != 0) 44 return -EINVAL; 45 46 return 0; 47 } 48 49 void enable_caches(void) 50 { 51 #ifndef CONFIG_SYS_ICACHE_OFF 52 icache_enable(); 53 #endif 54 #ifndef CONFIG_SYS_DCACHE_OFF 55 dcache_enable(); 56 #endif 57 } 58 59 #ifdef CONFIG_SYS_L2_PL310 60 void v7_outer_cache_enable(void) 61 { 62 /* Disable the L2 cache */ 63 clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 64 65 /* enable BRESP, instruction and data prefetch, full line of zeroes */ 66 setbits_le32(&pl310->pl310_aux_ctrl, 67 L310_AUX_CTRL_DATA_PREFETCH_MASK | 68 L310_AUX_CTRL_INST_PREFETCH_MASK | 69 L310_SHARED_ATT_OVERRIDE_ENABLE); 70 71 /* Enable the L2 cache */ 72 setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 73 } 74 75 void v7_outer_cache_disable(void) 76 { 77 /* Disable the L2 cache */ 78 clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 79 } 80 #endif 81 82 #if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ 83 defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) 84 int overwrite_console(void) 85 { 86 return 0; 87 } 88 #endif 89 90 #ifdef CONFIG_FPGA 91 /* 92 * FPGA programming support for SoC FPGA Cyclone V 93 */ 94 static Altera_desc altera_fpga[] = { 95 { 96 /* Family */ 97 Altera_SoCFPGA, 98 /* Interface type */ 99 fast_passive_parallel, 100 /* No limitation as additional data will be ignored */ 101 -1, 102 /* No device function table */ 103 NULL, 104 /* Base interface address specified in driver */ 105 NULL, 106 /* No cookie implementation */ 107 0 108 }, 109 }; 110 111 /* add device descriptor to FPGA device table */ 112 void socfpga_fpga_add(void) 113 { 114 int i; 115 fpga_init(); 116 for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) 117 fpga_add(fpga_altera, &altera_fpga[i]); 118 } 119 #endif 120 121 int arch_cpu_init(void) 122 { 123 #ifdef CONFIG_HW_WATCHDOG 124 /* 125 * In case the watchdog is enabled, make sure to (re-)configure it 126 * so that the defined timeout is valid. Otherwise the SPL (Perloader) 127 * timeout value is still active which might too short for Linux 128 * booting. 129 */ 130 hw_watchdog_init(); 131 #else 132 /* 133 * If the HW watchdog is NOT enabled, make sure it is not running, 134 * for example because it was enabled in the preloader. This might 135 * trigger a watchdog-triggered reboot of Linux kernel later. 136 * Toggle watchdog reset, so watchdog in not running state. 137 */ 138 socfpga_per_reset(SOCFPGA_RESET(L4WD0), 1); 139 socfpga_per_reset(SOCFPGA_RESET(L4WD0), 0); 140 #endif 141 142 return 0; 143 } 144 145 #ifdef CONFIG_ETH_DESIGNWARE 146 static int dwmac_phymode_to_modereg(const char *phymode, u32 *modereg) 147 { 148 if (!phymode) 149 return -EINVAL; 150 151 if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) { 152 *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 153 return 0; 154 } 155 156 if (!strcmp(phymode, "rgmii")) { 157 *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; 158 return 0; 159 } 160 161 if (!strcmp(phymode, "rmii")) { 162 *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; 163 return 0; 164 } 165 166 return -EINVAL; 167 } 168 169 int socfpga_eth_reset_common(void (*resetfn)(const u8 of_reset_id, 170 const u8 phymode)) 171 { 172 const void *fdt = gd->fdt_blob; 173 struct fdtdec_phandle_args args; 174 const char *phy_mode; 175 u32 phy_modereg; 176 int nodes[2]; /* Max. two GMACs */ 177 int ret, count; 178 int i, node; 179 180 count = fdtdec_find_aliases_for_id(fdt, "ethernet", 181 COMPAT_ALTERA_SOCFPGA_DWMAC, 182 nodes, ARRAY_SIZE(nodes)); 183 for (i = 0; i < count; i++) { 184 node = nodes[i]; 185 if (node <= 0) 186 continue; 187 188 ret = fdtdec_parse_phandle_with_args(fdt, node, "resets", 189 "#reset-cells", 1, 0, 190 &args); 191 if (ret || (args.args_count != 1)) { 192 debug("GMAC%i: Failed to parse DT 'resets'!\n", i); 193 continue; 194 } 195 196 phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); 197 ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg); 198 if (ret) { 199 debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); 200 continue; 201 } 202 203 resetfn(args.args[0], phy_modereg); 204 } 205 206 return 0; 207 } 208 #endif 209 210 #ifndef CONFIG_SPL_BUILD 211 static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 212 { 213 if (argc != 2) 214 return CMD_RET_USAGE; 215 216 argv++; 217 218 switch (*argv[0]) { 219 case 'e': /* Enable */ 220 do_bridge_reset(1); 221 break; 222 case 'd': /* Disable */ 223 do_bridge_reset(0); 224 break; 225 default: 226 return CMD_RET_USAGE; 227 } 228 229 return 0; 230 } 231 232 U_BOOT_CMD(bridge, 2, 1, do_bridge, 233 "SoCFPGA HPS FPGA bridge control", 234 "enable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" 235 "bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" 236 "" 237 ); 238 239 #endif 240