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 0x18: 70 /* 71 * Configuration: 72 * SERDES: 2 73 * Lanes: A,B,C,D: SGMII 74 * Lanes: E,F: Aur 75 * Lanes: G,H: SRIO 76 */ 77 case 0x91: 78 /* 79 * Configuration: 80 * SERDES: 2 81 * Lanes: A,B: SGMII 82 * Lanes: C,D: SRIO2 83 * Lanes: E,F,G,H: XAUI2 84 */ 85 case 0x93: 86 /* 87 * Configuration: 88 * SERDES: 2 89 * Lanes: A,B,C,D: SGMII 90 * Lanes: E,F,G,H: XAUI2 91 */ 92 case 0x98: 93 /* 94 * Configuration: 95 * SERDES: 2 96 * Lanes: A,B,C,D: XAUI2 97 * Lanes: E,F,G,H: XAUI2 98 */ 99 case 0x9a: 100 /* 101 * Configuration: 102 * SERDES: 2 103 * Lanes: A,B: PCI 104 * Lanes: C,D: SGMII 105 * Lanes: E,F,G,H: XAUI2 106 */ 107 case 0x9e: 108 /* 109 * Configuration: 110 * SERDES: 2 111 * Lanes: A,B,C,D: PCI 112 * Lanes: E,F,G,H: XAUI2 113 */ 114 case 0xb2: 115 /* 116 * Configuration: 117 * SERDES: 2 118 * Lanes: A,B,C,D: PCI 119 * Lanes: E,F: SGMII 3&4 120 * Lanes: G,H: XFI 121 */ 122 case 0xc2: 123 /* 124 * Configuration: 125 * SERDES: 2 126 * Lanes: A,B: SGMII 127 * Lanes: C,D: SRIO2 128 * Lanes: E,F,G,H: XAUI2 129 */ 130 lane_to_slot[12] = 2; 131 lane_to_slot[13] = lane_to_slot[12]; 132 lane_to_slot[14] = lane_to_slot[12]; 133 lane_to_slot[15] = lane_to_slot[12]; 134 break; 135 136 default: 137 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 138 serdes2_prtcl); 139 break; 140 } 141 return; 142 } 143 144 #endif /* #ifdef CONFIG_FMAN_ENET */ 145 146 int board_eth_init(bd_t *bis) 147 { 148 #ifdef CONFIG_FMAN_ENET 149 struct memac_mdio_info memac_mdio_info; 150 struct memac_mdio_info tg_memac_mdio_info; 151 unsigned int i; 152 unsigned int serdes1_prtcl, serdes2_prtcl; 153 int qsgmii; 154 struct mii_dev *bus; 155 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 156 serdes1_prtcl = in_be32(&gur->rcwsr[4]) & 157 FSL_CORENET2_RCWSR4_SRDS1_PRTCL; 158 if (!serdes1_prtcl) { 159 printf("SERDES1 is not enabled\n"); 160 return 0; 161 } 162 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; 163 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl); 164 165 serdes2_prtcl = in_be32(&gur->rcwsr[4]) & 166 FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 167 if (!serdes2_prtcl) { 168 printf("SERDES2 is not enabled\n"); 169 return 0; 170 } 171 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 172 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl); 173 174 printf("Initializing Fman\n"); 175 176 initialize_lane_to_slot(); 177 178 memac_mdio_info.regs = 179 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR; 180 memac_mdio_info.name = DEFAULT_FM_MDIO_NAME; 181 182 /* Register the real 1G MDIO bus */ 183 fm_memac_mdio_init(bis, &memac_mdio_info); 184 185 tg_memac_mdio_info.regs = 186 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; 187 tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; 188 189 /* Register the real 10G MDIO bus */ 190 fm_memac_mdio_init(bis, &tg_memac_mdio_info); 191 192 /* 193 * Program the two on board DTSEC PHY addresses assuming that they are 194 * all SGMII. RGMII is not supported on this board. Setting SGMII 5 and 195 * 6 to on board SGMII phys 196 */ 197 fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); 198 fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 199 200 switch (serdes1_prtcl) { 201 case 0x2a: 202 /* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */ 203 debug("Setting phy addresses for FM1_DTSEC5: %x and" 204 "FM1_DTSEC6: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR, 205 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 206 fm_info_set_phy_address(FM1_DTSEC5, 207 CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); 208 fm_info_set_phy_address(FM1_DTSEC6, 209 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 210 break; 211 #ifdef CONFIG_PPC_B4420 212 case 0x18: 213 /* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */ 214 debug("Setting phy addresses for FM1_DTSEC3: %x and" 215 "FM1_DTSEC4: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR, 216 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 217 /* Fixing Serdes clock by programming FPGA register */ 218 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125); 219 fm_info_set_phy_address(FM1_DTSEC3, 220 CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); 221 fm_info_set_phy_address(FM1_DTSEC4, 222 CONFIG_SYS_FM1_DTSEC6_PHY_ADDR); 223 break; 224 #endif 225 default: 226 printf("Fman: Unsupported SerDes1 Protocol 0x%02x\n", 227 serdes1_prtcl); 228 break; 229 } 230 switch (serdes2_prtcl) { 231 case 0x18: 232 debug("Setting phy addresses on SGMII Riser card for" 233 "FM1_DTSEC ports: \n"); 234 fm_info_set_phy_address(FM1_DTSEC1, 235 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 236 fm_info_set_phy_address(FM1_DTSEC2, 237 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 238 fm_info_set_phy_address(FM1_DTSEC3, 239 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 240 fm_info_set_phy_address(FM1_DTSEC4, 241 CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR); 242 break; 243 case 0x49: 244 debug("Setting phy addresses on SGMII Riser card for" 245 "FM1_DTSEC ports: \n"); 246 fm_info_set_phy_address(FM1_DTSEC1, 247 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 248 fm_info_set_phy_address(FM1_DTSEC2, 249 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 250 fm_info_set_phy_address(FM1_DTSEC3, 251 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 252 break; 253 case 0x8d: 254 case 0xb2: 255 debug("Setting phy addresses on SGMII Riser card for" 256 "FM1_DTSEC ports: \n"); 257 fm_info_set_phy_address(FM1_DTSEC3, 258 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 259 fm_info_set_phy_address(FM1_DTSEC4, 260 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 261 break; 262 case 0x98: 263 /* XAUI in Slot1 and Slot2 */ 264 debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC1: %x\n", 265 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 266 fm_info_set_phy_address(FM1_10GEC1, 267 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 268 debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC2: %x\n", 269 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 270 fm_info_set_phy_address(FM1_10GEC2, 271 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 272 break; 273 case 0x9E: 274 /* XAUI in Slot2 */ 275 debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC2: %x\n", 276 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 277 fm_info_set_phy_address(FM1_10GEC2, 278 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 279 break; 280 default: 281 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 282 serdes2_prtcl); 283 break; 284 } 285 286 /*set PHY address for QSGMII Riser Card on slot2*/ 287 bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME); 288 qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM); 289 290 if (qsgmii) { 291 switch (serdes2_prtcl) { 292 case 0xb2: 293 case 0x8d: 294 fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR); 295 fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1); 296 break; 297 default: 298 break; 299 } 300 } 301 302 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 303 int idx = i - FM1_DTSEC1; 304 305 switch (fm_info_get_enet_if(i)) { 306 case PHY_INTERFACE_MODE_SGMII: 307 fm_info_set_mdio(i, 308 miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); 309 break; 310 case PHY_INTERFACE_MODE_NONE: 311 fm_info_set_phy_address(i, 0); 312 break; 313 default: 314 printf("Fman1: DTSEC%u set to unknown interface %i\n", 315 idx + 1, fm_info_get_enet_if(i)); 316 fm_info_set_phy_address(i, 0); 317 break; 318 } 319 } 320 321 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { 322 int idx = i - FM1_10GEC1; 323 324 switch (fm_info_get_enet_if(i)) { 325 case PHY_INTERFACE_MODE_XGMII: 326 fm_info_set_mdio(i, 327 miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME)); 328 break; 329 default: 330 printf("Fman1: 10GSEC%u set to unknown interface %i\n", 331 idx + 1, fm_info_get_enet_if(i)); 332 fm_info_set_phy_address(i, 0); 333 break; 334 } 335 } 336 337 338 cpu_eth_init(bis); 339 #endif 340 341 return pci_eth_init(bis); 342 } 343 344 void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, 345 enum fm_port port, int offset) 346 { 347 int phy; 348 char alias[32]; 349 350 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { 351 phy = fm_info_get_phy_address(port); 352 353 sprintf(alias, "phy_sgmii_%x", phy); 354 fdt_set_phy_handle(fdt, compat, addr, alias); 355 } 356 } 357 358 void fdt_fixup_board_enet(void *fdt) 359 { 360 int i; 361 char alias[32]; 362 363 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 364 switch (fm_info_get_enet_if(i)) { 365 case PHY_INTERFACE_MODE_NONE: 366 sprintf(alias, "ethernet%u", i); 367 fdt_status_disabled_by_alias(fdt, alias); 368 break; 369 default: 370 break; 371 } 372 } 373 } 374