uboot/board/freescale/t1040qds/eth.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2013 Freescale Semiconductor, Inc.
   4 */
   5
   6/*
   7 * The RGMII PHYs are provided by the two on-board PHY connected to
   8 * dTSEC instances 4 and 5. The SGMII PHYs are provided by one on-board
   9 * PHY or by the standard four-port SGMII riser card (VSC).
  10 */
  11
  12#include <common.h>
  13#include <netdev.h>
  14#include <asm/fsl_serdes.h>
  15#include <asm/immap_85xx.h>
  16#include <fm_eth.h>
  17#include <fsl_mdio.h>
  18#include <malloc.h>
  19#include <fsl_dtsec.h>
  20#include <vsc9953.h>
  21
  22#include "../common/fman.h"
  23#include "../common/qixis.h"
  24
  25#include "t1040qds_qixis.h"
  26
  27#ifdef CONFIG_FMAN_ENET
  28 /* - In T1040 there are only 8 SERDES lanes, spread across 2 SERDES banks.
  29 *   Bank 1 -> Lanes A, B, C, D
  30 *   Bank 2 -> Lanes E, F, G, H
  31 */
  32
  33 /* Mapping of 8 SERDES lanes to T1040 QDS board slots. A value of '0' here
  34  * means that the mapping must be determined dynamically, or that the lane
  35  * maps to something other than a board slot.
  36  */
  37static u8 lane_to_slot[] = {
  38        0, 0, 0, 0, 0, 0, 0, 0
  39};
  40
  41/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
  42 * housed.
  43 */
  44static int riser_phy_addr[] = {
  45        CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR,
  46        CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR,
  47        CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR,
  48        CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR,
  49};
  50
  51/* Slot2 does not have EMI connections */
  52#define EMI_NONE        0xFFFFFFFF
  53#define EMI1_RGMII0     0
  54#define EMI1_RGMII1     1
  55#define EMI1_SLOT1      2
  56#define EMI1_SLOT3      3
  57#define EMI1_SLOT4      4
  58#define EMI1_SLOT5      5
  59#define EMI1_SLOT6      6
  60#define EMI1_SLOT7      7
  61#define EMI2            8
  62
  63static int mdio_mux[NUM_FM_PORTS];
  64
  65static const char * const mdio_names[] = {
  66        "T1040_QDS_MDIO0",
  67        "T1040_QDS_MDIO1",
  68        "T1040_QDS_MDIO2",
  69        "T1040_QDS_MDIO3",
  70        "T1040_QDS_MDIO4",
  71        "T1040_QDS_MDIO5",
  72        "T1040_QDS_MDIO6",
  73        "T1040_QDS_MDIO7",
  74};
  75
  76struct t1040_qds_mdio {
  77        u8 muxval;
  78        struct mii_dev *realbus;
  79};
  80
  81static const char *t1040_qds_mdio_name_for_muxval(u8 muxval)
  82{
  83        return mdio_names[muxval];
  84}
  85
  86struct mii_dev *mii_dev_for_muxval(u8 muxval)
  87{
  88        struct mii_dev *bus;
  89        const char *name = t1040_qds_mdio_name_for_muxval(muxval);
  90
  91        if (!name) {
  92                printf("No bus for muxval %x\n", muxval);
  93                return NULL;
  94        }
  95
  96        bus = miiphy_get_dev_by_name(name);
  97
  98        if (!bus) {
  99                printf("No bus by name %s\n", name);
 100                return NULL;
 101        }
 102
 103        return bus;
 104}
 105
 106static void t1040_qds_mux_mdio(u8 muxval)
 107{
 108        u8 brdcfg4;
 109        if (muxval <= 7) {
 110                brdcfg4 = QIXIS_READ(brdcfg[4]);
 111                brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
 112                brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
 113                QIXIS_WRITE(brdcfg[4], brdcfg4);
 114        }
 115}
 116
 117static int t1040_qds_mdio_read(struct mii_dev *bus, int addr, int devad,
 118                                int regnum)
 119{
 120        struct t1040_qds_mdio *priv = bus->priv;
 121
 122        t1040_qds_mux_mdio(priv->muxval);
 123
 124        return priv->realbus->read(priv->realbus, addr, devad, regnum);
 125}
 126
 127static int t1040_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
 128                                int regnum, u16 value)
 129{
 130        struct t1040_qds_mdio *priv = bus->priv;
 131
 132        t1040_qds_mux_mdio(priv->muxval);
 133
 134        return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
 135}
 136
 137static int t1040_qds_mdio_reset(struct mii_dev *bus)
 138{
 139        struct t1040_qds_mdio *priv = bus->priv;
 140
 141        return priv->realbus->reset(priv->realbus);
 142}
 143
 144static int t1040_qds_mdio_init(char *realbusname, u8 muxval)
 145{
 146        struct t1040_qds_mdio *pmdio;
 147        struct mii_dev *bus = mdio_alloc();
 148
 149        if (!bus) {
 150                printf("Failed to allocate t1040_qds MDIO bus\n");
 151                return -1;
 152        }
 153
 154        pmdio = malloc(sizeof(*pmdio));
 155        if (!pmdio) {
 156                printf("Failed to allocate t1040_qds private data\n");
 157                free(bus);
 158                return -1;
 159        }
 160
 161        bus->read = t1040_qds_mdio_read;
 162        bus->write = t1040_qds_mdio_write;
 163        bus->reset = t1040_qds_mdio_reset;
 164        strcpy(bus->name, t1040_qds_mdio_name_for_muxval(muxval));
 165
 166        pmdio->realbus = miiphy_get_dev_by_name(realbusname);
 167
 168        if (!pmdio->realbus) {
 169                printf("No bus with name %s\n", realbusname);
 170                free(bus);
 171                free(pmdio);
 172                return -1;
 173        }
 174
 175        pmdio->muxval = muxval;
 176        bus->priv = pmdio;
 177
 178        return mdio_register(bus);
 179}
 180
 181/*
 182 * Initialize the lane_to_slot[] array.
 183 *
 184 * On the T1040QDS board the mapping is controlled by ?? register.
 185 */
 186static void initialize_lane_to_slot(void)
 187{
 188        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
 189        int serdes1_prtcl = (in_be32(&gur->rcwsr[4]) &
 190                                FSL_CORENET2_RCWSR4_SRDS1_PRTCL)
 191                >> FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
 192
 193        QIXIS_WRITE(cms[0], 0x07);
 194
 195        switch (serdes1_prtcl) {
 196        case 0x60:
 197        case 0x66:
 198        case 0x67:
 199        case 0x69:
 200                lane_to_slot[1] = 7;
 201                lane_to_slot[2] = 6;
 202                lane_to_slot[3] = 5;
 203                break;
 204        case 0x86:
 205                lane_to_slot[1] = 7;
 206                lane_to_slot[2] = 7;
 207                lane_to_slot[3] = 7;
 208                break;
 209        case 0x87:
 210                lane_to_slot[1] = 7;
 211                lane_to_slot[2] = 7;
 212                lane_to_slot[3] = 7;
 213                lane_to_slot[7] = 7;
 214                break;
 215        case 0x89:
 216                lane_to_slot[1] = 7;
 217                lane_to_slot[2] = 7;
 218                lane_to_slot[3] = 7;
 219                lane_to_slot[6] = 7;
 220                lane_to_slot[7] = 7;
 221                break;
 222        case 0x8d:
 223                lane_to_slot[1] = 7;
 224                lane_to_slot[2] = 7;
 225                lane_to_slot[3] = 7;
 226                lane_to_slot[5] = 3;
 227                lane_to_slot[6] = 3;
 228                lane_to_slot[7] = 3;
 229                break;
 230        case 0x8F:
 231        case 0x85:
 232                lane_to_slot[1] = 7;
 233                lane_to_slot[2] = 6;
 234                lane_to_slot[3] = 5;
 235                lane_to_slot[6] = 3;
 236                lane_to_slot[7] = 3;
 237                break;
 238        case 0xA5:
 239                lane_to_slot[1] = 7;
 240                lane_to_slot[6] = 3;
 241                lane_to_slot[7] = 3;
 242                break;
 243        case 0xA7:
 244                lane_to_slot[1] = 7;
 245                lane_to_slot[2] = 6;
 246                lane_to_slot[3] = 5;
 247                lane_to_slot[7] = 7;
 248                break;
 249        case 0xAA:
 250                lane_to_slot[1] = 7;
 251                lane_to_slot[6] = 7;
 252                lane_to_slot[7] = 7;
 253                break;
 254        case 0x40:
 255                lane_to_slot[2] = 7;
 256                lane_to_slot[3] = 7;
 257                break;
 258        default:
 259                printf("qds: Fman: Unsupported SerDes Protocol 0x%02x\n",
 260                       serdes1_prtcl);
 261                break;
 262        }
 263}
 264
 265/*
 266 * Given the following ...
 267 *
 268 * 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
 269 * compatible string and 'addr' physical address)
 270 *
 271 * 2) An Fman port
 272 *
 273 * ... update the phy-handle property of the Ethernet node to point to the
 274 * right PHY. This assumes that we already know the PHY for each port.
 275 *
 276 * The offset of the Fman Ethernet node is also passed in for convenience, but
 277 * it is not used, and we recalculate the offset anyway.
 278 *
 279 * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC.
 280 * Inside the Fman, "ports" are things that connect to MACs. We only call them
 281 * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs
 282 * and ports are the same thing.
 283 *
 284 */
 285void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
 286                              enum fm_port port, int offset)
 287{
 288        phy_interface_t intf = fm_info_get_enet_if(port);
 289        char phy[16];
 290
 291        /* The RGMII PHY is identified by the MAC connected to it */
 292        if (intf == PHY_INTERFACE_MODE_RGMII) {
 293                sprintf(phy, "rgmii_phy%u", port == FM1_DTSEC4 ? 1 : 2);
 294                fdt_set_phy_handle(fdt, compat, addr, phy);
 295        }
 296
 297        /* The SGMII PHY is identified by the MAC connected to it */
 298        if (intf == PHY_INTERFACE_MODE_SGMII) {
 299                int lane = serdes_get_first_lane(FSL_SRDS_1, SGMII_FM1_DTSEC1
 300                                                 + port);
 301                u8 slot;
 302                if (lane < 0)
 303                        return;
 304                slot = lane_to_slot[lane];
 305                if (slot) {
 306                        /* Slot housing a SGMII riser card */
 307                        sprintf(phy, "phy_s%x_%02x", slot,
 308                                (fm_info_get_phy_address(port - FM1_DTSEC1)-
 309                                CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + 1));
 310                        fdt_set_phy_handle(fdt, compat, addr, phy);
 311                }
 312        }
 313}
 314
 315void fdt_fixup_board_enet(void *fdt)
 316{
 317        int i, lane, idx;
 318
 319        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 320                idx = i - FM1_DTSEC1;
 321                switch (fm_info_get_enet_if(i)) {
 322                case PHY_INTERFACE_MODE_SGMII:
 323                        lane = serdes_get_first_lane(FSL_SRDS_1,
 324                                                     SGMII_FM1_DTSEC1 + idx);
 325                        if (lane < 0)
 326                                break;
 327
 328                        switch (mdio_mux[i]) {
 329                        case EMI1_SLOT3:
 330                                fdt_status_okay_by_alias(fdt, "emi1_slot3");
 331                                break;
 332                        case EMI1_SLOT5:
 333                                fdt_status_okay_by_alias(fdt, "emi1_slot5");
 334                                break;
 335                        case EMI1_SLOT6:
 336                                fdt_status_okay_by_alias(fdt, "emi1_slot6");
 337                                break;
 338                        case EMI1_SLOT7:
 339                                fdt_status_okay_by_alias(fdt, "emi1_slot7");
 340                                break;
 341                        }
 342                break;
 343                case PHY_INTERFACE_MODE_RGMII:
 344                        if (i == FM1_DTSEC4)
 345                                fdt_status_okay_by_alias(fdt, "emi1_rgmii0");
 346
 347                        if (i == FM1_DTSEC5)
 348                                fdt_status_okay_by_alias(fdt, "emi1_rgmii1");
 349                        break;
 350                default:
 351                        break;
 352                }
 353        }
 354}
 355#endif /* #ifdef CONFIG_FMAN_ENET */
 356
 357static void set_brdcfg9_for_gtx_clk(void)
 358{
 359        u8 brdcfg9;
 360        brdcfg9 = QIXIS_READ(brdcfg[9]);
 361/* Initializing EPHY2 clock to RGMII mode */
 362        brdcfg9 &= ~(BRDCFG9_EPHY2_MASK);
 363        brdcfg9 |= (BRDCFG9_EPHY2_VAL);
 364        QIXIS_WRITE(brdcfg[9], brdcfg9);
 365}
 366
 367void t1040_handle_phy_interface_sgmii(int i)
 368{
 369        int lane, idx, slot;
 370        idx = i - FM1_DTSEC1;
 371        lane = serdes_get_first_lane(FSL_SRDS_1,
 372                        SGMII_FM1_DTSEC1 + idx);
 373
 374        if (lane < 0)
 375                return;
 376        slot = lane_to_slot[lane];
 377
 378        switch (slot) {
 379        case 1:
 380                mdio_mux[i] = EMI1_SLOT1;
 381                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 382                break;
 383        case 3:
 384                if (FM1_DTSEC4 == i)
 385                        fm_info_set_phy_address(i, riser_phy_addr[0]);
 386                if (FM1_DTSEC5 == i)
 387                        fm_info_set_phy_address(i, riser_phy_addr[1]);
 388
 389                mdio_mux[i] = EMI1_SLOT3;
 390
 391                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 392                break;
 393        case 4:
 394                mdio_mux[i] = EMI1_SLOT4;
 395                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 396                break;
 397        case 5:
 398                /* Slot housing a SGMII riser card? */
 399                fm_info_set_phy_address(i, riser_phy_addr[0]);
 400                mdio_mux[i] = EMI1_SLOT5;
 401                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 402                break;
 403        case 6:
 404                /* Slot housing a SGMII riser card? */
 405                fm_info_set_phy_address(i, riser_phy_addr[0]);
 406                mdio_mux[i] = EMI1_SLOT6;
 407                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 408                break;
 409        case 7:
 410                if (FM1_DTSEC1 == i)
 411                        fm_info_set_phy_address(i, riser_phy_addr[0]);
 412                if (FM1_DTSEC2 == i)
 413                        fm_info_set_phy_address(i, riser_phy_addr[1]);
 414                if (FM1_DTSEC3 == i)
 415                        fm_info_set_phy_address(i, riser_phy_addr[2]);
 416                if (FM1_DTSEC5 == i)
 417                        fm_info_set_phy_address(i, riser_phy_addr[3]);
 418
 419                mdio_mux[i] = EMI1_SLOT7;
 420                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 421                break;
 422        default:
 423                break;
 424        }
 425        fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 426}
 427void t1040_handle_phy_interface_rgmii(int i)
 428{
 429        fm_info_set_phy_address(i, i == FM1_DTSEC5 ?
 430                        CONFIG_SYS_FM1_DTSEC5_PHY_ADDR :
 431                        CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
 432        mdio_mux[i] = (i == FM1_DTSEC5) ? EMI1_RGMII1 :
 433                EMI1_RGMII0;
 434        fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 435}
 436
 437int board_eth_init(bd_t *bis)
 438{
 439#ifdef CONFIG_FMAN_ENET
 440        struct memac_mdio_info memac_mdio_info;
 441        unsigned int i;
 442#ifdef CONFIG_VSC9953
 443        int lane;
 444        int phy_addr;
 445        phy_interface_t phy_int;
 446        struct mii_dev *bus;
 447#endif
 448
 449        printf("Initializing Fman\n");
 450        set_brdcfg9_for_gtx_clk();
 451
 452        initialize_lane_to_slot();
 453
 454        /* Initialize the mdio_mux array so we can recognize empty elements */
 455        for (i = 0; i < NUM_FM_PORTS; i++)
 456                mdio_mux[i] = EMI_NONE;
 457
 458        memac_mdio_info.regs =
 459                (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
 460        memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;
 461
 462        /* Register the real 1G MDIO bus */
 463        fm_memac_mdio_init(bis, &memac_mdio_info);
 464
 465        /* Register the muxing front-ends to the MDIO buses */
 466        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII0);
 467        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
 468        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
 469        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
 470        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
 471        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
 472        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6);
 473        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7);
 474
 475        /*
 476         * Program on board RGMII PHY addresses. If the SGMII Riser
 477         * card used, we'll override the PHY address later. For any DTSEC that
 478         * is RGMII, we'll also override its PHY address later. We assume that
 479         * DTSEC4 and DTSEC5 are used for RGMII.
 480         */
 481        fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
 482        fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
 483
 484        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 485                switch (fm_info_get_enet_if(i)) {
 486                case PHY_INTERFACE_MODE_QSGMII:
 487                        fm_info_set_mdio(i, NULL);
 488                        break;
 489                case PHY_INTERFACE_MODE_SGMII:
 490                        t1040_handle_phy_interface_sgmii(i);
 491                        break;
 492
 493                case PHY_INTERFACE_MODE_RGMII:
 494                        /* Only DTSEC4 and DTSEC5 can be routed to RGMII */
 495                        t1040_handle_phy_interface_rgmii(i);
 496                        break;
 497                default:
 498                        break;
 499                }
 500        }
 501
 502#ifdef CONFIG_VSC9953
 503        for (i = 0; i < VSC9953_MAX_PORTS; i++) {
 504                lane = -1;
 505                phy_addr = 0;
 506                phy_int = PHY_INTERFACE_MODE_NONE;
 507                switch (i) {
 508                case 0:
 509                case 1:
 510                case 2:
 511                case 3:
 512                        lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_A);
 513                        /* PHYs connected over QSGMII */
 514                        if (lane >= 0) {
 515                                phy_addr = CONFIG_SYS_FM1_QSGMII21_PHY_ADDR +
 516                                                i;
 517                                phy_int = PHY_INTERFACE_MODE_QSGMII;
 518                                break;
 519                        }
 520                        lane = serdes_get_first_lane(FSL_SRDS_1,
 521                                        SGMII_SW1_MAC1 + i);
 522
 523                        if (lane < 0)
 524                                break;
 525
 526                        /* PHYs connected over QSGMII */
 527                        if (i != 3 || lane_to_slot[lane] == 7)
 528                                phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR
 529                                        + i;
 530                        else
 531                                phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR;
 532                        phy_int = PHY_INTERFACE_MODE_SGMII;
 533                        break;
 534                case 4:
 535                case 5:
 536                case 6:
 537                case 7:
 538                        lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_B);
 539                        /* PHYs connected over QSGMII */
 540                        if (lane >= 0) {
 541                                phy_addr = CONFIG_SYS_FM1_QSGMII11_PHY_ADDR +
 542                                                i - 4;
 543                                phy_int = PHY_INTERFACE_MODE_QSGMII;
 544                                break;
 545                        }
 546                        lane = serdes_get_first_lane(FSL_SRDS_1,
 547                                        SGMII_SW1_MAC1 + i);
 548                        /* PHYs connected over SGMII */
 549                        if (lane >= 0) {
 550                                phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR
 551                                                + i - 3;
 552                                phy_int = PHY_INTERFACE_MODE_SGMII;
 553                        }
 554                        break;
 555                case 8:
 556                        if (serdes_get_first_lane(FSL_SRDS_1,
 557                                                  SGMII_FM1_DTSEC1) < 0)
 558                                /* FM1@DTSEC1 is connected to SW1@PORT8 */
 559                                vsc9953_port_enable(i);
 560                        break;
 561                case 9:
 562                        if (serdes_get_first_lane(FSL_SRDS_1,
 563                                                  SGMII_FM1_DTSEC2) < 0) {
 564                                /* Enable L2 On MAC2 using SCFG */
 565                                struct ccsr_scfg *scfg = (struct ccsr_scfg *)
 566                                                CONFIG_SYS_MPC85xx_SCFG;
 567
 568                                out_be32(&scfg->esgmiiselcr,
 569                                         in_be32(&scfg->esgmiiselcr) |
 570                                         (0x80000000));
 571                                vsc9953_port_enable(i);
 572                        }
 573                        break;
 574                }
 575
 576                if (lane >= 0) {
 577                        bus = mii_dev_for_muxval(lane_to_slot[lane]);
 578                        vsc9953_port_info_set_mdio(i, bus);
 579                        vsc9953_port_enable(i);
 580                }
 581                vsc9953_port_info_set_phy_address(i, phy_addr);
 582                vsc9953_port_info_set_phy_int(i, phy_int);
 583        }
 584
 585#endif
 586        cpu_eth_init(bis);
 587#endif
 588
 589        return pci_eth_init(bis);
 590}
 591