1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2012 Freescale Semiconductor, Inc. 4 * Author: Sandeep Kumar Singh <sandeep (at) freescale.com> 5 */ 6 7 /* This file is based on board/freescale/corenet_ds/eth_superhydra.c */ 8 9 /* 10 * This file handles the board muxing between the Fman Ethernet MACs and 11 * the RGMII/SGMII/XGMII PHYs on a Freescale B4860 "Centaur". The SGMII 12 * PHYs are the two on-board 1Gb ports. There are no RGMII PHY on board. 13 * The 10Gb XGMII PHY is provided via the XAUI riser card. There is only 14 * one Fman device on B4860. The SERDES configuration is used to determine 15 * where the SGMII and XAUI cards exist, and also which Fman MACs are routed 16 * to which PHYs. So for a given Fman MAC, there is one and only PHY it 17 * connects to. MACs cannot be routed to PHYs dynamically. This configuration 18 * is done at boot time by reading SERDES protocol from RCW. 19 */ 20 21 #include <common.h> 22 #include <netdev.h> 23 #include <asm/fsl_serdes.h> 24 #include <fm_eth.h> 25 #include <fsl_mdio.h> 26 #include <malloc.h> 27 #include <fdt_support.h> 28 #include <fsl_dtsec.h> 29 30 #include "../common/ngpixis.h" 31 #include "../common/fman.h" 32 #include "../common/qixis.h" 33 #include "b4860qds_qixis.h" 34 35 #define EMI_NONE 0xFFFFFFFF 36 37 #ifdef CONFIG_FMAN_ENET 38 39 /* 40 * Mapping of all 16 SERDES lanes to board slots. A value n(>0) will mean that 41 * lane at index is mapped to slot number n. A value of '0' will mean 42 * that the mapping must be determined dynamically, or that the lane maps to 43 * something other than a board slot 44 */ 45 static u8 lane_to_slot[] = { 46 0, 0, 0, 0, 47 0, 0, 0, 0, 48 1, 1, 1, 1, 49 0, 0, 0, 0 50 }; 51 52 /* 53 * This function initializes the lane_to_slot[] array. It reads RCW to check 54 * if Serdes2{E,F,G,H} is configured as slot 2 or as SFP and initializes 55 * lane_to_slot[] accordingly 56 */ 57 static void initialize_lane_to_slot(void) 58 { 59 unsigned int serdes2_prtcl; 60 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 61 serdes2_prtcl = in_be32(&gur->rcwsr[4]) & 62 FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 63 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 64 debug("Initializing lane to slot: Serdes2 protocol: %x\n", 65 serdes2_prtcl); 66 67 switch (serdes2_prtcl) { 68 case 0x17: 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 0xb1: 115 case 0xb2: 116 case 0x8c: 117 case 0x8d: 118 /* 119 * Configuration: 120 * SERDES: 2 121 * Lanes: A,B,C,D: PCI 122 * Lanes: E,F: SGMII 3&4 123 * Lanes: G,H: XFI 124 */ 125 case 0xc2: 126 /* 127 * Configuration: 128 * SERDES: 2 129 * Lanes: A,B: SGMII 130 * Lanes: C,D: SRIO2 131 * Lanes: E,F,G,H: XAUI2 132 */ 133 lane_to_slot[12] = 2; 134 lane_to_slot[13] = lane_to_slot[12]; 135 lane_to_slot[14] = lane_to_slot[12]; 136 lane_to_slot[15] = lane_to_slot[12]; 137 break; 138 139 default: 140 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 141 serdes2_prtcl); 142 break; 143 } 144 return; 145 } 146 147 #endif /* #ifdef CONFIG_FMAN_ENET */ 148 149 int board_eth_init(bd_t *bis) 150 { 151 #ifdef CONFIG_FMAN_ENET 152 struct memac_mdio_info memac_mdio_info; 153 struct memac_mdio_info tg_memac_mdio_info; 154 unsigned int i; 155 unsigned int serdes1_prtcl, serdes2_prtcl; 156 int qsgmii; 157 struct mii_dev *bus; 158 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 159 serdes1_prtcl = in_be32(&gur->rcwsr[4]) & 160 FSL_CORENET2_RCWSR4_SRDS1_PRTCL; 161 if (!serdes1_prtcl) { 162 printf("SERDES1 is not enabled\n"); 163 return 0; 164 } 165 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; 166 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl); 167 168 serdes2_prtcl = in_be32(&gur->rcwsr[4]) & 169 FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 170 if (!serdes2_prtcl) { 171 printf("SERDES2 is not enabled\n"); 172 return 0; 173 } 174 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 175 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl); 176 177 printf("Initializing Fman\n"); 178 179 initialize_lane_to_slot(); 180 181 memac_mdio_info.regs = 182 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR; 183 memac_mdio_info.name = DEFAULT_FM_MDIO_NAME; 184 185 /* Register the real 1G MDIO bus */ 186 fm_memac_mdio_init(bis, &memac_mdio_info); 187 188 tg_memac_mdio_info.regs = 189 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; 190 tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; 191 192 /* Register the real 10G MDIO bus */ 193 fm_memac_mdio_init(bis, &tg_memac_mdio_info); 194 195 /* 196 * Program the two on board DTSEC PHY addresses assuming that they are 197 * all SGMII. RGMII is not supported on this board. Setting SGMII 5 and 198 * 6 to on board SGMII phys 199 */ 200 fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR); 201 fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 202 203 switch (serdes1_prtcl) { 204 case 0x29: 205 case 0x2a: 206 /* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */ 207 debug("Set phy addresses for FM1_DTSEC5:%x, FM1_DTSEC6:%x\n", 208 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR, 209 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 210 fm_info_set_phy_address(FM1_DTSEC5, 211 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR); 212 fm_info_set_phy_address(FM1_DTSEC6, 213 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 214 break; 215 #ifdef CONFIG_ARCH_B4420 216 case 0x17: 217 case 0x18: 218 /* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */ 219 debug("Set phy addresses for FM1_DTSEC3:%x, FM1_DTSEC4:%x\n", 220 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR, 221 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 222 /* Fixing Serdes clock by programming FPGA register */ 223 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125); 224 fm_info_set_phy_address(FM1_DTSEC3, 225 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR); 226 fm_info_set_phy_address(FM1_DTSEC4, 227 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR); 228 break; 229 #endif 230 default: 231 printf("Fman: Unsupported SerDes1 Protocol 0x%02x\n", 232 serdes1_prtcl); 233 break; 234 } 235 switch (serdes2_prtcl) { 236 case 0x17: 237 case 0x18: 238 debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n", 239 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 240 fm_info_set_phy_address(FM1_DTSEC1, 241 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 242 fm_info_set_phy_address(FM1_DTSEC2, 243 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 244 fm_info_set_phy_address(FM1_DTSEC3, 245 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 246 fm_info_set_phy_address(FM1_DTSEC4, 247 CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR); 248 break; 249 case 0x48: 250 case 0x49: 251 debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n", 252 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 253 fm_info_set_phy_address(FM1_DTSEC1, 254 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 255 fm_info_set_phy_address(FM1_DTSEC2, 256 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 257 fm_info_set_phy_address(FM1_DTSEC3, 258 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR); 259 break; 260 case 0xb1: 261 case 0xb2: 262 case 0x8c: 263 case 0x8d: 264 debug("Set phy addresses on SGMII Riser for FM1_DTSEC1:%x\n", 265 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 266 fm_info_set_phy_address(FM1_DTSEC3, 267 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR); 268 fm_info_set_phy_address(FM1_DTSEC4, 269 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR); 270 /* 271 * XFI does not need a PHY to work, but to make U-Boot 272 * happy, assign a fake PHY address for a XFI port. 273 */ 274 fm_info_set_phy_address(FM1_10GEC1, 0); 275 fm_info_set_phy_address(FM1_10GEC2, 1); 276 break; 277 case 0x98: 278 /* XAUI in Slot1 and Slot2 */ 279 debug("Set phy address of AMC2PEX-2S for FM1_10GEC1:%x\n", 280 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 281 fm_info_set_phy_address(FM1_10GEC1, 282 CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 283 debug("Set phy address of AMC2PEX-2S for FM1_10GEC2:%x\n", 284 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 285 fm_info_set_phy_address(FM1_10GEC2, 286 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 287 break; 288 case 0x9E: 289 /* XAUI in Slot2 */ 290 debug("Sett phy address of AMC2PEX-2S for FM1_10GEC2:%x\n", 291 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 292 fm_info_set_phy_address(FM1_10GEC2, 293 CONFIG_SYS_FM1_10GEC2_PHY_ADDR); 294 break; 295 default: 296 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n", 297 serdes2_prtcl); 298 break; 299 } 300 301 /*set PHY address for QSGMII Riser Card on slot2*/ 302 bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME); 303 qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM); 304 305 if (qsgmii) { 306 switch (serdes2_prtcl) { 307 case 0xb2: 308 case 0x8d: 309 fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR); 310 fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1); 311 break; 312 default: 313 break; 314 } 315 } 316 317 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 318 int idx = i - FM1_DTSEC1; 319 320 switch (fm_info_get_enet_if(i)) { 321 case PHY_INTERFACE_MODE_SGMII: 322 fm_info_set_mdio(i, 323 miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); 324 break; 325 case PHY_INTERFACE_MODE_NONE: 326 fm_info_set_phy_address(i, 0); 327 break; 328 default: 329 printf("Fman1: DTSEC%u set to unknown interface %i\n", 330 idx + 1, fm_info_get_enet_if(i)); 331 fm_info_set_phy_address(i, 0); 332 break; 333 } 334 } 335 336 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { 337 int idx = i - FM1_10GEC1; 338 339 switch (fm_info_get_enet_if(i)) { 340 case PHY_INTERFACE_MODE_XGMII: 341 fm_info_set_mdio(i, 342 miiphy_get_dev_by_name 343 (DEFAULT_FM_TGEC_MDIO_NAME)); 344 break; 345 case PHY_INTERFACE_MODE_NONE: 346 fm_info_set_phy_address(i, 0); 347 break; 348 default: 349 printf("Fman1: TGEC%u set to unknown interface %i\n", 350 idx + 1, fm_info_get_enet_if(i)); 351 fm_info_set_phy_address(i, 0); 352 break; 353 } 354 } 355 356 cpu_eth_init(bis); 357 #endif 358 359 return pci_eth_init(bis); 360 } 361 362 void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, 363 enum fm_port port, int offset) 364 { 365 int phy; 366 char alias[32]; 367 struct fixed_link f_link; 368 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 369 u32 prtcl2 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS2_PRTCL; 370 371 prtcl2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; 372 373 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { 374 phy = fm_info_get_phy_address(port); 375 376 sprintf(alias, "phy_sgmii_%x", phy); 377 fdt_set_phy_handle(fdt, compat, addr, alias); 378 fdt_status_okay_by_alias(fdt, alias); 379 } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) { 380 /* check if it's XFI interface for 10g */ 381 switch (prtcl2) { 382 case 0x80: 383 case 0x81: 384 case 0x82: 385 case 0x83: 386 case 0x84: 387 case 0x85: 388 case 0x86: 389 case 0x87: 390 case 0x88: 391 case 0x89: 392 case 0x8a: 393 case 0x8b: 394 case 0x8c: 395 case 0x8d: 396 case 0x8e: 397 case 0xb1: 398 case 0xb2: 399 f_link.phy_id = port; 400 f_link.duplex = 1; 401 f_link.link_speed = 10000; 402 f_link.pause = 0; 403 f_link.asym_pause = 0; 404 405 fdt_delprop(fdt, offset, "phy-handle"); 406 fdt_setprop(fdt, offset, "fixed-link", &f_link, 407 sizeof(f_link)); 408 break; 409 case 0x98: /* XAUI interface */ 410 strcpy(alias, "phy_xaui_slot1"); 411 fdt_status_okay_by_alias(fdt, alias); 412 413 strcpy(alias, "phy_xaui_slot2"); 414 fdt_status_okay_by_alias(fdt, alias); 415 break; 416 case 0x9e: /* XAUI interface */ 417 case 0x9a: 418 case 0x93: 419 case 0x91: 420 strcpy(alias, "phy_xaui_slot1"); 421 fdt_status_okay_by_alias(fdt, alias); 422 break; 423 case 0x97: /* XAUI interface */ 424 case 0xc3: 425 strcpy(alias, "phy_xaui_slot2"); 426 fdt_status_okay_by_alias(fdt, alias); 427 break; 428 default: 429 break; 430 } 431 } 432 } 433 434 /* 435 * Set status to disabled for unused ethernet node 436 */ 437 void fdt_fixup_board_enet(void *fdt) 438 { 439 int i; 440 char alias[32]; 441 442 for (i = FM1_DTSEC1; i <= FM1_10GEC2; i++) { 443 switch (fm_info_get_enet_if(i)) { 444 case PHY_INTERFACE_MODE_NONE: 445 sprintf(alias, "ethernet%u", i); 446 fdt_status_disabled_by_alias(fdt, alias); 447 break; 448 default: 449 break; 450 } 451 } 452 } 453