1 /* 2 * Copyright 2009-2011 Freescale Semiconductor, Inc. 3 * 4 * See file CREDITS for list of people who contributed to this 5 * project. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 */ 22 23 #include <common.h> 24 #include <command.h> 25 #include <netdev.h> 26 #include <asm/mmu.h> 27 #include <asm/processor.h> 28 #include <asm/cache.h> 29 #include <asm/immap_85xx.h> 30 #include <asm/fsl_law.h> 31 #include <asm/fsl_ddr_sdram.h> 32 #include <asm/fsl_serdes.h> 33 #include <asm/fsl_portals.h> 34 #include <asm/fsl_liodn.h> 35 #include <malloc.h> 36 #include <fm_eth.h> 37 #include <fsl_mdio.h> 38 #include <miiphy.h> 39 #include <phy.h> 40 41 #include "../common/ngpixis.h" 42 #include "../common/fman.h" 43 #include <asm/fsl_dtsec.h> 44 45 #define EMI_NONE 0xffffffff 46 #define EMI_MASK 0xf0000000 47 #define EMI1_RGMII 0x0 48 #define EMI1_SLOT3 0x80000000 /* bank1 EFGH */ 49 #define EMI1_SLOT4 0x40000000 /* bank2 ABCD */ 50 #define EMI1_SLOT5 0xc0000000 /* bank3 ABCD */ 51 #define EMI2_SLOT4 0x10000000 /* bank2 ABCD */ 52 #define EMI2_SLOT5 0x30000000 /* bank3 ABCD */ 53 #define EMI1_MASK 0xc0000000 54 #define EMI2_MASK 0x30000000 55 56 static int mdio_mux[NUM_FM_PORTS]; 57 58 static char *mdio_names[16] = { 59 "P4080DS_MDIO0", 60 "P4080DS_MDIO1", 61 NULL, 62 "P4080DS_MDIO3", 63 "P4080DS_MDIO4", 64 NULL, NULL, NULL, 65 "P4080DS_MDIO8", 66 NULL, NULL, NULL, 67 "P4080DS_MDIO12", 68 NULL, NULL, NULL, 69 }; 70 71 static char *p4080ds_mdio_name_for_muxval(u32 muxval) 72 { 73 return mdio_names[(muxval & EMI_MASK) >> 28]; 74 } 75 76 struct mii_dev *mii_dev_for_muxval(u32 muxval) 77 { 78 struct mii_dev *bus; 79 char *name = p4080ds_mdio_name_for_muxval(muxval); 80 81 if (!name) { 82 printf("No bus for muxval %x\n", muxval); 83 return NULL; 84 } 85 86 bus = miiphy_get_dev_by_name(name); 87 88 if (!bus) { 89 printf("No bus by name %s\n", name); 90 return NULL; 91 } 92 93 return bus; 94 } 95 96 #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9 97 int board_phy_config(struct phy_device *phydev) 98 { 99 /* 100 * If this is the 10G PHY, and we switched it to fiber, 101 * we need to reset the serdes link for SERDES9 102 */ 103 if ((phydev->port == PORT_FIBRE) && (phydev->drv->uid == 0x00a19410)) { 104 enum srds_prtcl device; 105 106 switch (phydev->addr) { 107 case 4: 108 device = XAUI_FM1; 109 break; 110 case 0: 111 device = XAUI_FM2; 112 break; 113 default: 114 device = NONE; 115 } 116 117 serdes_reset_rx(device); 118 } 119 120 return 0; 121 } 122 #endif 123 124 struct p4080ds_mdio { 125 u32 muxval; 126 struct mii_dev *realbus; 127 }; 128 129 static void p4080ds_mux_mdio(u32 muxval) 130 { 131 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 132 uint gpioval = in_be32(&pgpio->gpdat) & ~(EMI_MASK); 133 gpioval |= muxval; 134 135 out_be32(&pgpio->gpdat, gpioval); 136 } 137 138 static int p4080ds_mdio_read(struct mii_dev *bus, int addr, int devad, 139 int regnum) 140 { 141 struct p4080ds_mdio *priv = bus->priv; 142 143 p4080ds_mux_mdio(priv->muxval); 144 145 return priv->realbus->read(priv->realbus, addr, devad, regnum); 146 } 147 148 static int p4080ds_mdio_write(struct mii_dev *bus, int addr, int devad, 149 int regnum, u16 value) 150 { 151 struct p4080ds_mdio *priv = bus->priv; 152 153 p4080ds_mux_mdio(priv->muxval); 154 155 return priv->realbus->write(priv->realbus, addr, devad, regnum, value); 156 } 157 158 static int p4080ds_mdio_reset(struct mii_dev *bus) 159 { 160 struct p4080ds_mdio *priv = bus->priv; 161 162 return priv->realbus->reset(priv->realbus); 163 } 164 165 static int p4080ds_mdio_init(char *realbusname, u32 muxval) 166 { 167 struct p4080ds_mdio *pmdio; 168 struct mii_dev *bus = mdio_alloc(); 169 170 if (!bus) { 171 printf("Failed to allocate P4080DS MDIO bus\n"); 172 return -1; 173 } 174 175 pmdio = malloc(sizeof(*pmdio)); 176 if (!pmdio) { 177 printf("Failed to allocate P4080DS private data\n"); 178 free(bus); 179 return -1; 180 } 181 182 bus->read = p4080ds_mdio_read; 183 bus->write = p4080ds_mdio_write; 184 bus->reset = p4080ds_mdio_reset; 185 sprintf(bus->name, p4080ds_mdio_name_for_muxval(muxval)); 186 187 pmdio->realbus = miiphy_get_dev_by_name(realbusname); 188 189 if (!pmdio->realbus) { 190 printf("No bus with name %s\n", realbusname); 191 free(bus); 192 free(pmdio); 193 return -1; 194 } 195 196 pmdio->muxval = muxval; 197 bus->priv = pmdio; 198 199 return mdio_register(bus); 200 } 201 202 /* 203 * Sets the specified node's status to the value contained in "status" 204 * If the first character of the specified path is "/" then we use 205 * alias as a path. Otherwise, we look for an alias of that name 206 */ 207 static void fdt_set_node_status(void *fdt, const char *alias, 208 const char *status) 209 { 210 const char *path = fdt_get_alias(fdt, alias); 211 212 if (!path) 213 path = alias; 214 215 do_fixup_by_path(fdt, path, "status", status, strlen(status) + 1, 1); 216 } 217 218 void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, 219 enum fm_port port, int offset) 220 { 221 if (mdio_mux[port] == EMI1_RGMII) 222 fdt_set_phy_handle(blob, prop, pa, "phy_rgmii"); 223 224 if (mdio_mux[port] == EMI1_SLOT3) { 225 int idx = port - FM2_DTSEC1 + 5; 226 char phy[16]; 227 228 sprintf(phy, "phy%d_slot3", idx); 229 230 fdt_set_phy_handle(blob, prop, pa, phy); 231 } 232 } 233 234 void fdt_fixup_board_enet(void *fdt) 235 { 236 int i; 237 238 /* 239 * P4080DS can be configured in many different ways, supporting a number 240 * of combinations of ethernet devices and phy types. In order to 241 * have just one device tree for all of those configurations, we fix up 242 * the tree here. By default, the device tree configures FM1 and FM2 243 * for SGMII, and configures XAUI on both 10G interfaces. So we have 244 * a number of different variables to track: 245 * 246 * 1) Whether the device is configured at all. Whichever devices are 247 * not enabled should be disabled by setting the "status" property 248 * to "disabled". 249 * 2) What the PHY interface is. If this is an RGMII connection, 250 * we should change the "phy-connection-type" property to 251 * "rgmii" 252 * 3) Which PHY is being used. Because the MDIO buses are muxed, 253 * we need to redirect the "phy-handle" property to point at the 254 * PHY on the right slot/bus. 255 */ 256 257 /* We've got six MDIO nodes that may or may not need to exist */ 258 fdt_set_node_status(fdt, "emi1_slot3", "disabled"); 259 fdt_set_node_status(fdt, "emi1_slot4", "disabled"); 260 fdt_set_node_status(fdt, "emi1_slot5", "disabled"); 261 fdt_set_node_status(fdt, "emi2_slot4", "disabled"); 262 fdt_set_node_status(fdt, "emi2_slot5", "disabled"); 263 264 for (i = 0; i < NUM_FM_PORTS; i++) { 265 switch (mdio_mux[i]) { 266 case EMI1_SLOT3: 267 fdt_set_node_status(fdt, "emi1_slot3", "okay"); 268 break; 269 case EMI1_SLOT4: 270 fdt_set_node_status(fdt, "emi1_slot4", "okay"); 271 break; 272 case EMI1_SLOT5: 273 fdt_set_node_status(fdt, "emi1_slot5", "okay"); 274 break; 275 case EMI2_SLOT4: 276 fdt_set_node_status(fdt, "emi2_slot4", "okay"); 277 break; 278 case EMI2_SLOT5: 279 fdt_set_node_status(fdt, "emi2_slot5", "okay"); 280 break; 281 } 282 } 283 } 284 285 enum board_slots { 286 SLOT1 = 1, 287 SLOT2, 288 SLOT3, 289 SLOT4, 290 SLOT5, 291 SLOT6, 292 }; 293 294 int board_eth_init(bd_t *bis) 295 { 296 #ifdef CONFIG_FMAN_ENET 297 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 298 struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; 299 int i; 300 struct fsl_pq_mdio_info dtsec_mdio_info; 301 struct tgec_mdio_info tgec_mdio_info; 302 303 u8 lane_to_slot[] = { 304 SLOT1, /* 0 - Bank 1:A */ 305 SLOT1, /* 1 - Bank 1:B */ 306 SLOT2, /* 2 - Bank 1:C */ 307 SLOT2, /* 3 - Bank 1:D */ 308 SLOT3, /* 4 - Bank 1:E */ 309 SLOT3, /* 5 - Bank 1:F */ 310 SLOT3, /* 6 - Bank 1:G */ 311 SLOT3, /* 7 - Bank 1:H */ 312 SLOT6, /* 8 - Bank 1:I */ 313 SLOT6, /* 9 - Bank 1:J */ 314 SLOT4, /* 10 - Bank 2:A */ 315 SLOT4, /* 11 - Bank 2:B */ 316 SLOT4, /* 12 - Bank 2:C */ 317 SLOT4, /* 13 - Bank 2:D */ 318 SLOT5, /* 14 - Bank 3:A */ 319 SLOT5, /* 15 - Bank 3:B */ 320 SLOT5, /* 16 - Bank 3:C */ 321 SLOT5, /* 17 - Bank 3:D */ 322 }; 323 324 /* 325 * Set TBIPA on FM1@DTSEC1. This is needed for configurations 326 * where FM1@DTSEC1 isn't used directly, since it provides 327 * MDIO for other ports. 328 */ 329 out_be32(&tsec->tbipa, CONFIG_SYS_TBIPA_VALUE); 330 331 /* Initialize the mdio_mux array so we can recognize empty elements */ 332 for (i = 0; i < NUM_FM_PORTS; i++) 333 mdio_mux[i] = EMI_NONE; 334 335 /* The first 4 GPIOs are outputs to control MDIO bus muxing */ 336 out_be32(&pgpio->gpdir, EMI_MASK); 337 338 dtsec_mdio_info.regs = 339 (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; 340 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; 341 342 /* Register the 1G MDIO bus */ 343 fsl_pq_mdio_init(bis, &dtsec_mdio_info); 344 345 tgec_mdio_info.regs = 346 (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; 347 tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; 348 349 /* Register the 10G MDIO bus */ 350 fm_tgec_mdio_init(bis, &tgec_mdio_info); 351 352 /* Register the 6 muxing front-ends to the MDIO buses */ 353 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII); 354 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); 355 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4); 356 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5); 357 p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT4); 358 p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT5); 359 360 fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); 361 fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); 362 fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR); 363 fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); 364 fm_info_set_phy_address(FM1_10GEC1, CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 365 366 #if (CONFIG_SYS_NUM_FMAN == 2) 367 fm_info_set_phy_address(FM2_DTSEC1, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR); 368 fm_info_set_phy_address(FM2_DTSEC2, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR); 369 fm_info_set_phy_address(FM2_DTSEC3, CONFIG_SYS_FM2_DTSEC3_PHY_ADDR); 370 fm_info_set_phy_address(FM2_DTSEC4, CONFIG_SYS_FM2_DTSEC4_PHY_ADDR); 371 fm_info_set_phy_address(FM2_10GEC1, CONFIG_SYS_FM2_10GEC1_PHY_ADDR); 372 #endif 373 374 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 375 int idx = i - FM1_DTSEC1, lane, slot; 376 switch (fm_info_get_enet_if(i)) { 377 case PHY_INTERFACE_MODE_SGMII: 378 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); 379 if (lane < 0) 380 break; 381 slot = lane_to_slot[lane]; 382 switch (slot) { 383 case SLOT3: 384 mdio_mux[i] = EMI1_SLOT3; 385 fm_info_set_mdio(i, 386 mii_dev_for_muxval(mdio_mux[i])); 387 break; 388 case SLOT4: 389 mdio_mux[i] = EMI1_SLOT4; 390 fm_info_set_mdio(i, 391 mii_dev_for_muxval(mdio_mux[i])); 392 break; 393 case SLOT5: 394 mdio_mux[i] = EMI1_SLOT5; 395 fm_info_set_mdio(i, 396 mii_dev_for_muxval(mdio_mux[i])); 397 break; 398 }; 399 break; 400 case PHY_INTERFACE_MODE_RGMII: 401 fm_info_set_phy_address(i, 0); 402 mdio_mux[i] = EMI1_RGMII; 403 fm_info_set_mdio(i, 404 mii_dev_for_muxval(mdio_mux[i])); 405 break; 406 default: 407 break; 408 } 409 } 410 411 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { 412 int idx = i - FM1_10GEC1, lane, slot; 413 switch (fm_info_get_enet_if(i)) { 414 case PHY_INTERFACE_MODE_XGMII: 415 lane = serdes_get_first_lane(XAUI_FM1 + idx); 416 if (lane < 0) 417 break; 418 slot = lane_to_slot[lane]; 419 switch (slot) { 420 case SLOT4: 421 mdio_mux[i] = EMI2_SLOT4; 422 fm_info_set_mdio(i, 423 mii_dev_for_muxval(mdio_mux[i])); 424 break; 425 case SLOT5: 426 mdio_mux[i] = EMI2_SLOT5; 427 fm_info_set_mdio(i, 428 mii_dev_for_muxval(mdio_mux[i])); 429 break; 430 }; 431 break; 432 default: 433 break; 434 } 435 } 436 437 #if (CONFIG_SYS_NUM_FMAN == 2) 438 for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { 439 int idx = i - FM2_DTSEC1, lane, slot; 440 switch (fm_info_get_enet_if(i)) { 441 case PHY_INTERFACE_MODE_SGMII: 442 lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); 443 if (lane < 0) 444 break; 445 slot = lane_to_slot[lane]; 446 switch (slot) { 447 case SLOT3: 448 mdio_mux[i] = EMI1_SLOT3; 449 fm_info_set_mdio(i, 450 mii_dev_for_muxval(mdio_mux[i])); 451 break; 452 case SLOT4: 453 mdio_mux[i] = EMI1_SLOT4; 454 fm_info_set_mdio(i, 455 mii_dev_for_muxval(mdio_mux[i])); 456 break; 457 case SLOT5: 458 mdio_mux[i] = EMI1_SLOT5; 459 fm_info_set_mdio(i, 460 mii_dev_for_muxval(mdio_mux[i])); 461 break; 462 }; 463 break; 464 case PHY_INTERFACE_MODE_RGMII: 465 fm_info_set_phy_address(i, 0); 466 mdio_mux[i] = EMI1_RGMII; 467 fm_info_set_mdio(i, 468 mii_dev_for_muxval(mdio_mux[i])); 469 break; 470 default: 471 break; 472 } 473 } 474 475 for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) { 476 int idx = i - FM2_10GEC1, lane, slot; 477 switch (fm_info_get_enet_if(i)) { 478 case PHY_INTERFACE_MODE_XGMII: 479 lane = serdes_get_first_lane(XAUI_FM2 + idx); 480 if (lane < 0) 481 break; 482 slot = lane_to_slot[lane]; 483 switch (slot) { 484 case SLOT4: 485 mdio_mux[i] = EMI2_SLOT4; 486 fm_info_set_mdio(i, 487 mii_dev_for_muxval(mdio_mux[i])); 488 break; 489 case SLOT5: 490 mdio_mux[i] = EMI2_SLOT5; 491 fm_info_set_mdio(i, 492 mii_dev_for_muxval(mdio_mux[i])); 493 break; 494 }; 495 break; 496 default: 497 break; 498 } 499 } 500 #endif 501 502 cpu_eth_init(bis); 503 #endif /* CONFIG_FMAN_ENET */ 504 505 return pci_eth_init(bis); 506 } 507