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 <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 0xb1: 116 case 0xb2: 117 case 0x8c: 118 case 0x8d: 119 /* 120 * Configuration: 121 * SERDES: 2 122 * Lanes: A,B,C,D: PCI 123 * Lanes: E,F: SGMII 3&4 124 * Lanes: G,H: XFI 125 */ 126 case 0xc2: 127 /* 128 * Configuration: 129 * SERDES: 2 130 * Lanes: A,B: SGMII 131 * Lanes: C,D: SRIO2 132 * Lanes: E,F,G,H: XAUI2 133 */ 134 lane_to_slot[12] = 2; 135 lane_to_slot[13] = lane_to_slot[12]; 136 lane_to_slot[14] = lane_to_slot[12]; 137 lane_to_slot[15] = lane_to_slot[12]; 138 break; 139 140 default: 141 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 142 serdes2_prtcl); 143 break; 144 } 145 return; 146 } 147 148 #endif /* #ifdef CONFIG_FMAN_ENET */ 149 150 int board_eth_init(bd_t *bis) 151 { 152 #ifdef CONFIG_FMAN_ENET 153 struct memac_mdio_info memac_mdio_info; 154 struct memac_mdio_info tg_memac_mdio_info; 155 unsigned int i; 156 unsigned int serdes1_prtcl, serdes2_prtcl; 157 int qsgmii; 158 struct mii_dev *bus; 159 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 160 serdes1_prtcl = in_be32(&gur->rcwsr[4]) & 161 FSL_CORENET2_RCWSR4_SRDS1_PRTCL; 162 if (!serdes1_prtcl) { 163 printf("SERDES1 is not enabled\n"); 164 return 0; 165 } 166 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; 167 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl); 168 169 serdes2_prtcl = in_be32(&gur->rcwsr[4]) & 170 FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 171 if (!serdes2_prtcl) { 172 printf("SERDES2 is not enabled\n"); 173 return 0; 174 } 175 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 176 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl); 177 178 printf("Initializing Fman\n"); 179 180 initialize_lane_to_slot(); 181 182 memac_mdio_info.regs = 183 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR; 184 memac_mdio_info.name = DEFAULT_FM_MDIO_NAME; 185 186 /* Register the real 1G MDIO bus */ 187 fm_memac_mdio_init(bis, &memac_mdio_info); 188 189 tg_memac_mdio_info.regs = 190 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; 191 tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; 192 193 /* Register the real 10G MDIO bus */ 194 fm_memac_mdio_init(bis, &tg_memac_mdio_info); 195 196 /* 197 * Program the two on board DTSEC PHY addresses assuming that they are 198 * all SGMII. RGMII is not supported on this board. Setting SGMII 5 and 199 * 6 to on board SGMII phys 200 */ 201 fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR); 202 fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 203 204 switch (serdes1_prtcl) { 205 case 0x29: 206 case 0x2a: 207 /* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */ 208 debug("Set phy addresses for FM1_DTSEC5:%x, FM1_DTSEC6:%x\n", 209 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR, 210 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 211 fm_info_set_phy_address(FM1_DTSEC5, 212 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR); 213 fm_info_set_phy_address(FM1_DTSEC6, 214 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 215 break; 216 #ifdef CONFIG_PPC_B4420 217 case 0x17: 218 case 0x18: 219 /* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */ 220 debug("Set phy addresses for FM1_DTSEC3:%x, FM1_DTSEC4:%x\n", 221 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR, 222 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 223 /* Fixing Serdes clock by programming FPGA register */ 224 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125); 225 fm_info_set_phy_address(FM1_DTSEC3, 226 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR); 227 fm_info_set_phy_address(FM1_DTSEC4, 228 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 229 break; 230 #endif 231 default: 232 printf("Fman: Unsupported SerDes1 Protocol 0x%02x\n", 233 serdes1_prtcl); 234 break; 235 } 236 switch (serdes2_prtcl) { 237 case 0x17: 238 case 0x18: 239 debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n", 240 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 241 fm_info_set_phy_address(FM1_DTSEC1, 242 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 243 fm_info_set_phy_address(FM1_DTSEC2, 244 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 245 fm_info_set_phy_address(FM1_DTSEC3, 246 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 247 fm_info_set_phy_address(FM1_DTSEC4, 248 CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR); 249 break; 250 case 0x48: 251 case 0x49: 252 debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n", 253 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 254 fm_info_set_phy_address(FM1_DTSEC1, 255 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 256 fm_info_set_phy_address(FM1_DTSEC2, 257 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 258 fm_info_set_phy_address(FM1_DTSEC3, 259 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 260 break; 261 case 0xb1: 262 case 0xb2: 263 case 0x8c: 264 case 0x8d: 265 debug("Set phy addresses on SGMII Riser for FM1_DTSEC1:%x\n", 266 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 267 fm_info_set_phy_address(FM1_DTSEC3, 268 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 269 fm_info_set_phy_address(FM1_DTSEC4, 270 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 271 /* 272 * XFI does not need a PHY to work, but to make U-boot 273 * happy, assign a fake PHY address for a XFI port. 274 */ 275 fm_info_set_phy_address(FM1_10GEC1, 0); 276 fm_info_set_phy_address(FM1_10GEC2, 1); 277 break; 278 case 0x98: 279 /* XAUI in Slot1 and Slot2 */ 280 debug("Set phy address of AMC2PEX-2S for FM1_10GEC1:%x\n", 281 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 282 fm_info_set_phy_address(FM1_10GEC1, 283 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 284 debug("Set phy address of AMC2PEX-2S for FM1_10GEC2:%x\n", 285 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 286 fm_info_set_phy_address(FM1_10GEC2, 287 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 288 break; 289 case 0x9E: 290 /* XAUI in Slot2 */ 291 debug("Sett phy address of AMC2PEX-2S for FM1_10GEC2:%x\n", 292 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 293 fm_info_set_phy_address(FM1_10GEC2, 294 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 295 break; 296 default: 297 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 298 serdes2_prtcl); 299 break; 300 } 301 302 /*set PHY address for QSGMII Riser Card on slot2*/ 303 bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME); 304 qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM); 305 306 if (qsgmii) { 307 switch (serdes2_prtcl) { 308 case 0xb2: 309 case 0x8d: 310 fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR); 311 fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1); 312 break; 313 default: 314 break; 315 } 316 } 317 318 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 319 int idx = i - FM1_DTSEC1; 320 321 switch (fm_info_get_enet_if(i)) { 322 case PHY_INTERFACE_MODE_SGMII: 323 fm_info_set_mdio(i, 324 miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); 325 break; 326 case PHY_INTERFACE_MODE_NONE: 327 fm_info_set_phy_address(i, 0); 328 break; 329 default: 330 printf("Fman1: DTSEC%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 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { 338 int idx = i - FM1_10GEC1; 339 340 switch (fm_info_get_enet_if(i)) { 341 case PHY_INTERFACE_MODE_XGMII: 342 fm_info_set_mdio(i, 343 miiphy_get_dev_by_name 344 (DEFAULT_FM_TGEC_MDIO_NAME)); 345 break; 346 case PHY_INTERFACE_MODE_NONE: 347 fm_info_set_phy_address(i, 0); 348 break; 349 default: 350 printf("Fman1: TGEC%u set to unknown interface %i\n", 351 idx + 1, fm_info_get_enet_if(i)); 352 fm_info_set_phy_address(i, 0); 353 break; 354 } 355 } 356 357 cpu_eth_init(bis); 358 #endif 359 360 return pci_eth_init(bis); 361 } 362 363 void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, 364 enum fm_port port, int offset) 365 { 366 int phy; 367 char alias[32]; 368 struct fixed_link f_link; 369 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 370 u32 prtcl2 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 371 372 prtcl2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 373 374 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { 375 phy = fm_info_get_phy_address(port); 376 377 sprintf(alias, "phy_sgmii_%x", phy); 378 fdt_set_phy_handle(fdt, compat, addr, alias); 379 fdt_status_okay_by_alias(fdt, alias); 380 } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) { 381 /* check if it's XFI interface for 10g */ 382 switch (prtcl2) { 383 case 0x80: 384 case 0x81: 385 case 0x82: 386 case 0x83: 387 case 0x84: 388 case 0x85: 389 case 0x86: 390 case 0x87: 391 case 0x88: 392 case 0x89: 393 case 0x8a: 394 case 0x8b: 395 case 0x8c: 396 case 0x8d: 397 case 0x8e: 398 case 0xb1: 399 case 0xb2: 400 f_link.phy_id = port; 401 f_link.duplex = 1; 402 f_link.link_speed = 10000; 403 f_link.pause = 0; 404 f_link.asym_pause = 0; 405 406 fdt_delprop(fdt, offset, "phy-handle"); 407 fdt_setprop(fdt, offset, "fixed-link", &f_link, 408 sizeof(f_link)); 409 break; 410 case 0x98: /* XAUI interface */ 411 strcpy(alias, "phy_xaui_slot1"); 412 fdt_status_okay_by_alias(fdt, alias); 413 414 strcpy(alias, "phy_xaui_slot2"); 415 fdt_status_okay_by_alias(fdt, alias); 416 break; 417 case 0x9e: /* XAUI interface */ 418 case 0x9a: 419 case 0x93: 420 case 0x91: 421 strcpy(alias, "phy_xaui_slot1"); 422 fdt_status_okay_by_alias(fdt, alias); 423 break; 424 case 0x97: /* XAUI interface */ 425 case 0xc3: 426 strcpy(alias, "phy_xaui_slot2"); 427 fdt_status_okay_by_alias(fdt, alias); 428 break; 429 default: 430 break; 431 } 432 } 433 } 434 435 /* 436 * Set status to disabled for unused ethernet node 437 */ 438 void fdt_fixup_board_enet(void *fdt) 439 { 440 int i; 441 char alias[32]; 442 443 for (i = FM1_DTSEC1; i <= FM1_10GEC2; i++) { 444 switch (fm_info_get_enet_if(i)) { 445 case PHY_INTERFACE_MODE_NONE: 446 sprintf(alias, "ethernet%u", i); 447 fdt_status_disabled_by_alias(fdt, alias); 448 break; 449 default: 450 break; 451 } 452 } 453 } 454