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 0xb2:
 116                /*
 117                 * Configuration:
 118                 * SERDES: 2
 119                 * Lanes: A,B,C,D: PCI
 120                 * Lanes: E,F: SGMII 3&4
 121                 * Lanes: G,H: XFI
 122                 */
 123        case 0xc2:
 124                /*
 125                 * Configuration:
 126                 * SERDES: 2
 127                 * Lanes: A,B: SGMII
 128                 * Lanes: C,D: SRIO2
 129                 * Lanes: E,F,G,H: XAUI2
 130                 */
 131                lane_to_slot[12] = 2;
 132                lane_to_slot[13] = lane_to_slot[12];
 133                lane_to_slot[14] = lane_to_slot[12];
 134                lane_to_slot[15] = lane_to_slot[12];
 135                break;
 136
 137        default:
 138                printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
 139                                serdes2_prtcl);
 140                        break;
 141        }
 142        return;
 143}
 144
 145#endif /* #ifdef CONFIG_FMAN_ENET */
 146
 147int board_eth_init(bd_t *bis)
 148{
 149#ifdef CONFIG_FMAN_ENET
 150        struct memac_mdio_info memac_mdio_info;
 151        struct memac_mdio_info tg_memac_mdio_info;
 152        unsigned int i;
 153        unsigned int  serdes1_prtcl, serdes2_prtcl;
 154        int qsgmii;
 155        struct mii_dev *bus;
 156        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 157        serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
 158                FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
 159        if (!serdes1_prtcl) {
 160                printf("SERDES1 is not enabled\n");
 161                return 0;
 162        }
 163        serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
 164        debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
 165
 166        serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
 167                FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
 168        if (!serdes2_prtcl) {
 169                printf("SERDES2 is not enabled\n");
 170                return 0;
 171        }
 172        serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
 173        debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
 174
 175        printf("Initializing Fman\n");
 176
 177        initialize_lane_to_slot();
 178
 179        memac_mdio_info.regs =
 180                (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
 181        memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;
 182
 183        /* Register the real 1G MDIO bus */
 184        fm_memac_mdio_init(bis, &memac_mdio_info);
 185
 186        tg_memac_mdio_info.regs =
 187                (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
 188        tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
 189
 190        /* Register the real 10G MDIO bus */
 191        fm_memac_mdio_init(bis, &tg_memac_mdio_info);
 192
 193        /*
 194         * Program the two on board DTSEC PHY addresses assuming that they are
 195         * all SGMII. RGMII is not supported on this board. Setting SGMII 5 and
 196         * 6 to on board SGMII phys
 197         */
 198        fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
 199        fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_DTSEC6_PHY_ADDR);
 200
 201        switch (serdes1_prtcl) {
 202        case 0x29:
 203        case 0x2a:
 204                /* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */
 205                debug("Setting phy addresses for FM1_DTSEC5: %x and"
 206                        "FM1_DTSEC6: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR,
 207                        CONFIG_SYS_FM1_DTSEC6_PHY_ADDR);
 208                fm_info_set_phy_address(FM1_DTSEC5,
 209                                CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
 210                fm_info_set_phy_address(FM1_DTSEC6,
 211                                CONFIG_SYS_FM1_DTSEC6_PHY_ADDR);
 212                break;
 213#ifdef CONFIG_PPC_B4420
 214        case 0x17:
 215        case 0x18:
 216                /* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */
 217                debug("Setting phy addresses for FM1_DTSEC3: %x and"
 218                        "FM1_DTSEC4: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR,
 219                        CONFIG_SYS_FM1_DTSEC6_PHY_ADDR);
 220                /* Fixing Serdes clock by programming FPGA register */
 221                QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
 222                fm_info_set_phy_address(FM1_DTSEC3,
 223                                CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
 224                fm_info_set_phy_address(FM1_DTSEC4,
 225                                CONFIG_SYS_FM1_DTSEC6_PHY_ADDR);
 226                break;
 227#endif
 228        default:
 229                printf("Fman:  Unsupported SerDes1 Protocol 0x%02x\n",
 230                                serdes1_prtcl);
 231                break;
 232        }
 233        switch (serdes2_prtcl) {
 234        case 0x17:
 235        case 0x18:
 236                debug("Setting phy addresses on SGMII Riser card for"
 237                                "FM1_DTSEC ports: \n");
 238                fm_info_set_phy_address(FM1_DTSEC1,
 239                                CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
 240                fm_info_set_phy_address(FM1_DTSEC2,
 241                                CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
 242                fm_info_set_phy_address(FM1_DTSEC3,
 243                                CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
 244                fm_info_set_phy_address(FM1_DTSEC4,
 245                                CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR);
 246                break;
 247        case 0x48:
 248        case 0x49:
 249                debug("Setting phy addresses on SGMII Riser card for"
 250                                "FM1_DTSEC ports: \n");
 251                fm_info_set_phy_address(FM1_DTSEC1,
 252                                CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
 253                fm_info_set_phy_address(FM1_DTSEC2,
 254                                CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
 255                fm_info_set_phy_address(FM1_DTSEC3,
 256                                CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
 257                break;
 258        case 0x8d:
 259        case 0xb2:
 260                debug("Setting phy addresses on SGMII Riser card for"
 261                                "FM1_DTSEC ports: \n");
 262                fm_info_set_phy_address(FM1_DTSEC3,
 263                                CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
 264                fm_info_set_phy_address(FM1_DTSEC4,
 265                                CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
 266                break;
 267        case 0x98:
 268                /* XAUI in Slot1 and Slot2 */
 269                debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC1: %x\n",
 270                      CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
 271                fm_info_set_phy_address(FM1_10GEC1,
 272                                        CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
 273                debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC2: %x\n",
 274                      CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
 275                fm_info_set_phy_address(FM1_10GEC2,
 276                                        CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
 277                break;
 278        case 0x9E:
 279                /* XAUI in Slot2 */
 280                debug("Setting phy addresses on B4860 QDS AMC2PEX-2S for FM1_10GEC2: %x\n",
 281                      CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
 282                fm_info_set_phy_address(FM1_10GEC2,
 283                                        CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
 284                break;
 285        default:
 286                printf("Fman:  Unsupported SerDes2 Protocol 0x%02x\n",
 287                                serdes2_prtcl);
 288                break;
 289        }
 290
 291        /*set PHY address for QSGMII Riser Card on slot2*/
 292        bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);
 293        qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM);
 294
 295        if (qsgmii) {
 296                switch (serdes2_prtcl) {
 297                case 0xb2:
 298                case 0x8d:
 299                        fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR);
 300                        fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1);
 301                        break;
 302                default:
 303                        break;
 304                }
 305        }
 306
 307        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 308                int idx = i - FM1_DTSEC1;
 309
 310                switch (fm_info_get_enet_if(i)) {
 311                case PHY_INTERFACE_MODE_SGMII:
 312                        fm_info_set_mdio(i,
 313                                miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
 314                        break;
 315                case PHY_INTERFACE_MODE_NONE:
 316                        fm_info_set_phy_address(i, 0);
 317                        break;
 318                default:
 319                        printf("Fman1: DTSEC%u set to unknown interface %i\n",
 320                                        idx + 1, fm_info_get_enet_if(i));
 321                        fm_info_set_phy_address(i, 0);
 322                        break;
 323                }
 324        }
 325
 326        for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
 327                int idx = i - FM1_10GEC1;
 328
 329                switch (fm_info_get_enet_if(i)) {
 330                case PHY_INTERFACE_MODE_XGMII:
 331                        fm_info_set_mdio(i,
 332                                         miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME));
 333                        break;
 334                default:
 335                        printf("Fman1: 10GSEC%u set to unknown interface %i\n",
 336                               idx + 1, fm_info_get_enet_if(i));
 337                        fm_info_set_phy_address(i, 0);
 338                        break;
 339                }
 340        }
 341
 342
 343        cpu_eth_init(bis);
 344#endif
 345
 346        return pci_eth_init(bis);
 347}
 348
 349void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
 350                              enum fm_port port, int offset)
 351{
 352        int phy;
 353        char alias[32];
 354
 355        if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
 356                phy = fm_info_get_phy_address(port);
 357
 358                sprintf(alias, "phy_sgmii_%x", phy);
 359                fdt_set_phy_handle(fdt, compat, addr, alias);
 360        }
 361}
 362
 363void fdt_fixup_board_enet(void *fdt)
 364{
 365        int i;
 366        char alias[32];
 367
 368        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 369                switch (fm_info_get_enet_if(i)) {
 370                case PHY_INTERFACE_MODE_NONE:
 371                        sprintf(alias, "ethernet%u", i);
 372                        fdt_status_disabled_by_alias(fdt, alias);
 373                        break;
 374                default:
 375                        break;
 376                }
 377        }
 378}
 379