uboot/board/freescale/b4860qds/eth_b4860qds.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2012 Freescale Semiconductor, Inc.
   4 * Author: Sandeep Kumar Singh <sandeep@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 */
  45static 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 */
  57static 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
 149int 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
 362void 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 */
 437void 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