uboot/board/freescale/b4860qds/eth_b4860qds.c
<<
>>
Prefs
   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 */
  46static 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 */
  58static 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
 150int 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
 363void 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                        sprintf(alias, "phy_xaui_slot1");
 412                        fdt_status_okay_by_alias(fdt, alias);
 413
 414                        sprintf(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                        sprintf(alias, "phy_xaui_slot1");
 422                        fdt_status_okay_by_alias(fdt, alias);
 423                        break;
 424                case 0x97: /* XAUI interface */
 425                case 0xc3:
 426                        sprintf(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 */
 438void 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