1 /* 2 * Copyright 2012 Freescale Semiconductor, Inc. 3 * Author: Sandeep Kumar Singh <sandeep@freescale.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* This file is based on board/freescale/corenet_ds/eth_superhydra.c */ 9 10 /* 11 * This file handles the board muxing between the Fman Ethernet MACs and 12 * the RGMII/SGMII/XGMII PHYs on a Freescale B4860 "Centaur". The SGMII 13 * PHYs are the two on-board 1Gb ports. There are no RGMII PHY on board. 14 * The 10Gb XGMII PHY is provided via the XAUI riser card. There is only 15 * one Fman device on B4860. The SERDES configuration is used to determine 16 * where the SGMII and XAUI cards exist, and also which Fman MACs are routed 17 * to which PHYs. So for a given Fman MAC, there is one and only PHY it 18 * connects to. MACs cannot be routed to PHYs dynamically. This configuration 19 * is done at boot time by reading SERDES protocol from RCW. 20 */ 21 22 #include <common.h> 23 #include <netdev.h> 24 #include <asm/fsl_serdes.h> 25 #include <fm_eth.h> 26 #include <fsl_mdio.h> 27 #include <malloc.h> 28 #include <fdt_support.h> 29 #include <asm/fsl_dtsec.h> 30 31 #include "../common/ngpixis.h" 32 #include "../common/fman.h" 33 #include "../common/qixis.h" 34 #include "b4860qds_qixis.h" 35 36 #define EMI_NONE 0xFFFFFFFF 37 38 #ifdef CONFIG_FMAN_ENET 39 40 /* 41 * Mapping of all 16 SERDES lanes to board slots. A value n(>0) will mean that 42 * lane at index is mapped to slot number n. A value of '0' will mean 43 * that the mapping must be determined dynamically, or that the lane maps to 44 * something other than a board slot 45 */ 46 static u8 lane_to_slot[] = { 47 0, 0, 0, 0, 48 0, 0, 0, 0, 49 1, 1, 1, 1, 50 0, 0, 0, 0 51 }; 52 53 /* 54 * This function initializes the lane_to_slot[] array. It reads RCW to check 55 * if Serdes2{E,F,G,H} is configured as slot 2 or as SFP and initializes 56 * lane_to_slot[] accordingly 57 */ 58 static void initialize_lane_to_slot(void) 59 { 60 unsigned int serdes2_prtcl; 61 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 62 serdes2_prtcl = in_be32(&gur->rcwsr[4]) & 63 FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 64 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 65 debug("Initializing lane to slot: Serdes2 protocol: %x\n", 66 serdes2_prtcl); 67 68 switch (serdes2_prtcl) { 69 case 0x17: 70 case 0x18: 71 /* 72 * Configuration: 73 * SERDES: 2 74 * Lanes: A,B,C,D: SGMII 75 * Lanes: E,F: Aur 76 * Lanes: G,H: SRIO 77 */ 78 case 0x91: 79 /* 80 * Configuration: 81 * SERDES: 2 82 * Lanes: A,B: SGMII 83 * Lanes: C,D: SRIO2 84 * Lanes: E,F,G,H: XAUI2 85 */ 86 case 0x93: 87 /* 88 * Configuration: 89 * SERDES: 2 90 * Lanes: A,B,C,D: SGMII 91 * Lanes: E,F,G,H: XAUI2 92 */ 93 case 0x98: 94 /* 95 * Configuration: 96 * SERDES: 2 97 * Lanes: A,B,C,D: XAUI2 98 * Lanes: E,F,G,H: XAUI2 99 */ 100 case 0x9a: 101 /* 102 * Configuration: 103 * SERDES: 2 104 * Lanes: A,B: PCI 105 * Lanes: C,D: SGMII 106 * Lanes: E,F,G,H: XAUI2 107 */ 108 case 0x9e: 109 /* 110 * Configuration: 111 * SERDES: 2 112 * Lanes: A,B,C,D: PCI 113 * Lanes: E,F,G,H: XAUI2 114 */ 115 case 0xb2: 116 /* 117 * Configuration: 118 * SERDES: 2 119 * Lanes: A,B,C,D: PCI 120 * Lanes: E,F: SGMII 3&4 121 * Lanes: G,H: XFI 122 */ 123 case 0xc2: 124 /* 125 * Configuration: 126 * SERDES: 2 127 * Lanes: A,B: SGMII 128 * Lanes: C,D: SRIO2 129 * Lanes: E,F,G,H: XAUI2 130 */ 131 lane_to_slot[12] = 2; 132 lane_to_slot[13] = lane_to_slot[12]; 133 lane_to_slot[14] = lane_to_slot[12]; 134 lane_to_slot[15] = lane_to_slot[12]; 135 break; 136 137 default: 138 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 139 serdes2_prtcl); 140 break; 141 } 142 return; 143 } 144 145 #endif /* #ifdef CONFIG_FMAN_ENET */ 146 147 int board_eth_init(bd_t *bis) 148 { 149 #ifdef CONFIG_FMAN_ENET 150 struct memac_mdio_info memac_mdio_info; 151 struct memac_mdio_info tg_memac_mdio_info; 152 unsigned int i; 153 unsigned int serdes1_prtcl, serdes2_prtcl; 154 int qsgmii; 155 struct mii_dev *bus; 156 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 157 serdes1_prtcl = in_be32(&gur->rcwsr[4]) & 158 FSL_CORENET2_RCWSR4_SRDS1_PRTCL; 159 if (!serdes1_prtcl) { 160 printf("SERDES1 is not enabled\n"); 161 return 0; 162 } 163 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; 164 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl); 165 166 serdes2_prtcl = in_be32(&gur->rcwsr[4]) & 167 FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 168 if (!serdes2_prtcl) { 169 printf("SERDES2 is not enabled\n"); 170 return 0; 171 } 172 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 173 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl); 174 175 printf("Initializing Fman\n"); 176 177 initialize_lane_to_slot(); 178 179 memac_mdio_info.regs = 180 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR; 181 memac_mdio_info.name = DEFAULT_FM_MDIO_NAME; 182 183 /* Register the real 1G MDIO bus */ 184 fm_memac_mdio_init(bis, &memac_mdio_info); 185 186 tg_memac_mdio_info.regs = 187 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; 188 tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; 189 190 /* Register the real 10G MDIO bus */ 191 fm_memac_mdio_init(bis, &tg_memac_mdio_info); 192 193 /* 194 * Program the two on board DTSEC PHY addresses assuming that they are 195 * all SGMII. RGMII is not supported on this board. Setting SGMII 5 and 196 * 6 to on board SGMII phys 197 */ 198 fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); 199 fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 200 201 switch (serdes1_prtcl) { 202 case 0x29: 203 case 0x2a: 204 /* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */ 205 debug("Setting phy addresses for FM1_DTSEC5: %x and" 206 "FM1_DTSEC6: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR, 207 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 208 fm_info_set_phy_address(FM1_DTSEC5, 209 CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); 210 fm_info_set_phy_address(FM1_DTSEC6, 211 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 212 break; 213 #ifdef CONFIG_PPC_B4420 214 case 0x17: 215 case 0x18: 216 /* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */ 217 debug("Setting phy addresses for FM1_DTSEC3: %x and" 218 "FM1_DTSEC4: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR, 219 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 220 /* Fixing Serdes clock by programming FPGA register */ 221 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125); 222 fm_info_set_phy_address(FM1_DTSEC3, 223 CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); 224 fm_info_set_phy_address(FM1_DTSEC4, 225 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 226 break; 227 #endif 228 default: 229 printf("Fman: Unsupported SerDes1 Protocol 0x%02x\n", 230 serdes1_prtcl); 231 break; 232 } 233 switch (serdes2_prtcl) { 234 case 0x17: 235 case 0x18: 236 debug("Setting phy addresses on SGMII Riser card for" 237 "FM1_DTSEC ports: \n"); 238 fm_info_set_phy_address(FM1_DTSEC1, 239 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 240 fm_info_set_phy_address(FM1_DTSEC2, 241 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 242 fm_info_set_phy_address(FM1_DTSEC3, 243 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 244 fm_info_set_phy_address(FM1_DTSEC4, 245 CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR); 246 break; 247 case 0x48: 248 case 0x49: 249 debug("Setting phy addresses on SGMII Riser card for" 250 "FM1_DTSEC ports: \n"); 251 fm_info_set_phy_address(FM1_DTSEC1, 252 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 253 fm_info_set_phy_address(FM1_DTSEC2, 254 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 255 fm_info_set_phy_address(FM1_DTSEC3, 256 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 257 break; 258 case 0x8d: 259 case 0xb2: 260 debug("Setting phy addresses on SGMII Riser card for" 261 "FM1_DTSEC ports: \n"); 262 fm_info_set_phy_address(FM1_DTSEC3, 263 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 264 fm_info_set_phy_address(FM1_DTSEC4, 265 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 266 break; 267 case 0x98: 268 /* XAUI in Slot1 and Slot2 */ 269 debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC1: %x\n", 270 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 271 fm_info_set_phy_address(FM1_10GEC1, 272 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 273 debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC2: %x\n", 274 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 275 fm_info_set_phy_address(FM1_10GEC2, 276 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 277 break; 278 case 0x9E: 279 /* XAUI in Slot2 */ 280 debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC2: %x\n", 281 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 282 fm_info_set_phy_address(FM1_10GEC2, 283 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 284 break; 285 default: 286 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 287 serdes2_prtcl); 288 break; 289 } 290 291 /*set PHY address for QSGMII Riser Card on slot2*/ 292 bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME); 293 qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM); 294 295 if (qsgmii) { 296 switch (serdes2_prtcl) { 297 case 0xb2: 298 case 0x8d: 299 fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR); 300 fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1); 301 break; 302 default: 303 break; 304 } 305 } 306 307 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 308 int idx = i - FM1_DTSEC1; 309 310 switch (fm_info_get_enet_if(i)) { 311 case PHY_INTERFACE_MODE_SGMII: 312 fm_info_set_mdio(i, 313 miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); 314 break; 315 case PHY_INTERFACE_MODE_NONE: 316 fm_info_set_phy_address(i, 0); 317 break; 318 default: 319 printf("Fman1: DTSEC%u set to unknown interface %i\n", 320 idx + 1, fm_info_get_enet_if(i)); 321 fm_info_set_phy_address(i, 0); 322 break; 323 } 324 } 325 326 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { 327 int idx = i - FM1_10GEC1; 328 329 switch (fm_info_get_enet_if(i)) { 330 case PHY_INTERFACE_MODE_XGMII: 331 fm_info_set_mdio(i, 332 miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME)); 333 break; 334 default: 335 printf("Fman1: 10GSEC%u set to unknown interface %i\n", 336 idx + 1, fm_info_get_enet_if(i)); 337 fm_info_set_phy_address(i, 0); 338 break; 339 } 340 } 341 342 343 cpu_eth_init(bis); 344 #endif 345 346 return pci_eth_init(bis); 347 } 348 349 void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, 350 enum fm_port port, int offset) 351 { 352 int phy; 353 char alias[32]; 354 355 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { 356 phy = fm_info_get_phy_address(port); 357 358 sprintf(alias, "phy_sgmii_%x", phy); 359 fdt_set_phy_handle(fdt, compat, addr, alias); 360 } 361 } 362 363 void fdt_fixup_board_enet(void *fdt) 364 { 365 int i; 366 char alias[32]; 367 368 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 369 switch (fm_info_get_enet_if(i)) { 370 case PHY_INTERFACE_MODE_NONE: 371 sprintf(alias, "ethernet%u", i); 372 fdt_status_disabled_by_alias(fdt, alias); 373 break; 374 default: 375 break; 376 } 377 } 378 } 379