uboot/board/freescale/t102xqds/eth_t102xqds.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2014 Freescale Semiconductor, Inc.
   4 *
   5 * Shengzhou Liu <Shengzhou.Liu@freescale.com>
   6 */
   7
   8#include <common.h>
   9#include <command.h>
  10#include <fdt_support.h>
  11#include <log.h>
  12#include <net.h>
  13#include <netdev.h>
  14#include <asm/mmu.h>
  15#include <asm/processor.h>
  16#include <asm/immap_85xx.h>
  17#include <asm/fsl_law.h>
  18#include <asm/fsl_serdes.h>
  19#include <asm/fsl_portals.h>
  20#include <asm/fsl_liodn.h>
  21#include <malloc.h>
  22#include <fm_eth.h>
  23#include <fsl_mdio.h>
  24#include <miiphy.h>
  25#include <phy.h>
  26#include <fsl_dtsec.h>
  27#include <asm/fsl_serdes.h>
  28#include "../common/qixis.h"
  29#include "../common/fman.h"
  30#include "t102xqds_qixis.h"
  31
  32#define EMI_NONE        0xFFFFFFFF
  33#define EMI1_RGMII1     0
  34#define EMI1_RGMII2     1
  35#define EMI1_SLOT1      2
  36#define EMI1_SLOT2      3
  37#define EMI1_SLOT3      4
  38#define EMI1_SLOT4      5
  39#define EMI1_SLOT5      6
  40#define EMI2            7
  41
  42static int mdio_mux[NUM_FM_PORTS];
  43
  44static const char * const mdio_names[] = {
  45        "T1024QDS_MDIO_RGMII1",
  46        "T1024QDS_MDIO_RGMII2",
  47        "T1024QDS_MDIO_SLOT1",
  48        "T1024QDS_MDIO_SLOT2",
  49        "T1024QDS_MDIO_SLOT3",
  50        "T1024QDS_MDIO_SLOT4",
  51        "T1024QDS_MDIO_SLOT5",
  52        "T1024QDS_MDIO_10GC",
  53        "NULL",
  54};
  55
  56/* Map SerDes1 4 lanes to default slot, will be initialized dynamically */
  57static u8 lane_to_slot[] = {2, 3, 4, 5};
  58
  59static const char *t1024qds_mdio_name_for_muxval(u8 muxval)
  60{
  61        return mdio_names[muxval];
  62}
  63
  64struct mii_dev *mii_dev_for_muxval(u8 muxval)
  65{
  66        struct mii_dev *bus;
  67        const char *name;
  68
  69        if (muxval > EMI2)
  70                return NULL;
  71
  72        name = t1024qds_mdio_name_for_muxval(muxval);
  73
  74        if (!name) {
  75                printf("No bus for muxval %x\n", muxval);
  76                return NULL;
  77        }
  78
  79        bus = miiphy_get_dev_by_name(name);
  80
  81        if (!bus) {
  82                printf("No bus by name %s\n", name);
  83                return NULL;
  84        }
  85
  86        return bus;
  87}
  88
  89struct t1024qds_mdio {
  90        u8 muxval;
  91        struct mii_dev *realbus;
  92};
  93
  94static void t1024qds_mux_mdio(u8 muxval)
  95{
  96        u8 brdcfg4;
  97
  98        if (muxval < 7) {
  99                brdcfg4 = QIXIS_READ(brdcfg[4]);
 100                brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
 101                brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
 102                QIXIS_WRITE(brdcfg[4], brdcfg4);
 103        }
 104}
 105
 106static int t1024qds_mdio_read(struct mii_dev *bus, int addr, int devad,
 107                              int regnum)
 108{
 109        struct t1024qds_mdio *priv = bus->priv;
 110
 111        t1024qds_mux_mdio(priv->muxval);
 112
 113        return priv->realbus->read(priv->realbus, addr, devad, regnum);
 114}
 115
 116static int t1024qds_mdio_write(struct mii_dev *bus, int addr, int devad,
 117                               int regnum, u16 value)
 118{
 119        struct t1024qds_mdio *priv = bus->priv;
 120
 121        t1024qds_mux_mdio(priv->muxval);
 122
 123        return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
 124}
 125
 126static int t1024qds_mdio_reset(struct mii_dev *bus)
 127{
 128        struct t1024qds_mdio *priv = bus->priv;
 129
 130        return priv->realbus->reset(priv->realbus);
 131}
 132
 133static int t1024qds_mdio_init(char *realbusname, u8 muxval)
 134{
 135        struct t1024qds_mdio *pmdio;
 136        struct mii_dev *bus = mdio_alloc();
 137
 138        if (!bus) {
 139                printf("Failed to allocate t1024qds MDIO bus\n");
 140                return -1;
 141        }
 142
 143        pmdio = malloc(sizeof(*pmdio));
 144        if (!pmdio) {
 145                printf("Failed to allocate t1024qds private data\n");
 146                free(bus);
 147                return -1;
 148        }
 149
 150        bus->read = t1024qds_mdio_read;
 151        bus->write = t1024qds_mdio_write;
 152        bus->reset = t1024qds_mdio_reset;
 153        strcpy(bus->name, t1024qds_mdio_name_for_muxval(muxval));
 154
 155        pmdio->realbus = miiphy_get_dev_by_name(realbusname);
 156
 157        if (!pmdio->realbus) {
 158                printf("No bus with name %s\n", realbusname);
 159                free(bus);
 160                free(pmdio);
 161                return -1;
 162        }
 163
 164        pmdio->muxval = muxval;
 165        bus->priv = pmdio;
 166        return mdio_register(bus);
 167}
 168
 169void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
 170                              enum fm_port port, int offset)
 171{
 172        struct fixed_link f_link;
 173
 174        if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_RGMII) {
 175                if (port == FM1_DTSEC3) {
 176                        fdt_set_phy_handle(fdt, compat, addr, "rgmii_phy2");
 177                        fdt_setprop_string(fdt, offset, "phy-connection-type",
 178                                           "rgmii");
 179                        fdt_status_okay_by_alias(fdt, "emi1_rgmii1");
 180                }
 181        } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
 182                if (port == FM1_DTSEC1) {
 183                        fdt_set_phy_handle(fdt, compat, addr,
 184                                           "sgmii_vsc8234_phy_s5");
 185                } else if (port == FM1_DTSEC2) {
 186                        fdt_set_phy_handle(fdt, compat, addr,
 187                                           "sgmii_vsc8234_phy_s4");
 188                }
 189        } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII_2500) {
 190                if (port == FM1_DTSEC3) {
 191                        fdt_set_phy_handle(fdt, compat, addr,
 192                                           "sgmii_aqr105_phy_s3");
 193                }
 194        } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_QSGMII) {
 195                switch (port) {
 196                case FM1_DTSEC1:
 197                        fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p1");
 198                        break;
 199                case FM1_DTSEC2:
 200                        fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p2");
 201                        break;
 202                case FM1_DTSEC3:
 203                        fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p3");
 204                        break;
 205                case FM1_DTSEC4:
 206                        fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p4");
 207                        break;
 208                default:
 209                        break;
 210                }
 211                fdt_delprop(fdt, offset, "phy-connection-type");
 212                fdt_setprop_string(fdt, offset, "phy-connection-type",
 213                                   "qsgmii");
 214                fdt_status_okay_by_alias(fdt, "emi1_slot2");
 215        } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
 216                /* XFI interface */
 217                f_link.phy_id = port;
 218                f_link.duplex = 1;
 219                f_link.link_speed = 10000;
 220                f_link.pause = 0;
 221                f_link.asym_pause = 0;
 222                /* no PHY for XFI */
 223                fdt_delprop(fdt, offset, "phy-handle");
 224                fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link));
 225                fdt_setprop_string(fdt, offset, "phy-connection-type", "xgmii");
 226        }
 227}
 228
 229void fdt_fixup_board_enet(void *fdt)
 230{
 231}
 232
 233/*
 234 * This function reads RCW to check if Serdes1{A:D} is configured
 235 * to slot 1/2/3/4/5 and update the lane_to_slot[] array accordingly
 236 */
 237static void initialize_lane_to_slot(void)
 238{
 239        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 240        u32 srds_s1 = in_be32(&gur->rcwsr[4]) &
 241                                FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
 242
 243        srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
 244
 245        switch (srds_s1) {
 246        case 0x46:
 247        case 0x47:
 248                lane_to_slot[1] = 2;
 249                break;
 250        default:
 251                break;
 252        }
 253}
 254
 255int board_eth_init(bd_t *bis)
 256{
 257#if defined(CONFIG_FMAN_ENET)
 258        int i, idx, lane, slot, interface;
 259        struct memac_mdio_info dtsec_mdio_info;
 260        struct memac_mdio_info tgec_mdio_info;
 261        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 262        u32 srds_s1;
 263
 264        srds_s1 = in_be32(&gur->rcwsr[4]) &
 265                                        FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
 266        srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
 267
 268        initialize_lane_to_slot();
 269
 270        /* Initialize the mdio_mux array so we can recognize empty elements */
 271        for (i = 0; i < NUM_FM_PORTS; i++)
 272                mdio_mux[i] = EMI_NONE;
 273
 274        dtsec_mdio_info.regs =
 275                (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
 276
 277        dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
 278
 279        /* Register the 1G MDIO bus */
 280        fm_memac_mdio_init(bis, &dtsec_mdio_info);
 281
 282        tgec_mdio_info.regs =
 283                (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
 284        tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
 285
 286        /* Register the 10G MDIO bus */
 287        fm_memac_mdio_init(bis, &tgec_mdio_info);
 288
 289        /* Register the muxing front-ends to the MDIO buses */
 290        t1024qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
 291        t1024qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
 292        t1024qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
 293        t1024qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
 294        t1024qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
 295        t1024qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
 296        t1024qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
 297        t1024qds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);
 298
 299        /* Set the two on-board RGMII PHY address */
 300        fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY2_ADDR);
 301        fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY1_ADDR);
 302
 303        switch (srds_s1) {
 304        case 0xd5:
 305        case 0xd6:
 306                /* QSGMII in Slot2 */
 307                fm_info_set_phy_address(FM1_DTSEC1, 0x8);
 308                fm_info_set_phy_address(FM1_DTSEC2, 0x9);
 309                fm_info_set_phy_address(FM1_DTSEC3, 0xa);
 310                fm_info_set_phy_address(FM1_DTSEC4, 0xb);
 311                break;
 312        case 0x95:
 313        case 0x99:
 314                /*
 315                 * XFI does not need a PHY to work, but to avoid U-Boot use
 316                 * default PHY address which is zero to a MAC when it found
 317                 * a MAC has no PHY address, we give a PHY address to XFI
 318                 * MAC, and should not use a real XAUI PHY address, since
 319                 * MDIO can access it successfully, and then MDIO thinks the
 320                 * XAUI card is used for the XFI MAC, which will cause error.
 321                 */
 322                fm_info_set_phy_address(FM1_10GEC1, 4);
 323                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 324                break;
 325        case 0x6f:
 326                /* SGMII in Slot3, Slot4, Slot5 */
 327                fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_AQ_PHY_ADDR_S5);
 328                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_AQ_PHY_ADDR_S4);
 329                fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR);
 330                break;
 331        case 0x7f:
 332                fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_AQ_PHY_ADDR_S5);
 333                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_AQ_PHY_ADDR_S4);
 334                fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_AQ_PHY_ADDR_S3);
 335                break;
 336        case 0x47:
 337                fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
 338                break;
 339        case 0x77:
 340                fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
 341                fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_AQ_PHY_ADDR_S3);
 342                break;
 343        case 0x5a:
 344                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 345                break;
 346        case 0x6a:
 347                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 348                fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR);
 349                break;
 350        case 0x5b:
 351                fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
 352                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 353                break;
 354        case 0x6b:
 355                fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
 356                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 357                fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR);
 358                break;
 359        default:
 360                break;
 361        }
 362
 363        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 364                idx = i - FM1_DTSEC1;
 365                interface = fm_info_get_enet_if(i);
 366                switch (interface) {
 367                case PHY_INTERFACE_MODE_SGMII:
 368                case PHY_INTERFACE_MODE_SGMII_2500:
 369                case PHY_INTERFACE_MODE_QSGMII:
 370                        if (interface == PHY_INTERFACE_MODE_SGMII) {
 371                                lane = serdes_get_first_lane(FSL_SRDS_1,
 372                                                SGMII_FM1_DTSEC1 + idx);
 373                        } else if (interface == PHY_INTERFACE_MODE_SGMII_2500) {
 374                                lane = serdes_get_first_lane(FSL_SRDS_1,
 375                                                SGMII_2500_FM1_DTSEC1 + idx);
 376                        } else {
 377                                lane = serdes_get_first_lane(FSL_SRDS_1,
 378                                                QSGMII_FM1_A);
 379                        }
 380
 381                        if (lane < 0)
 382                                break;
 383
 384                        slot = lane_to_slot[lane];
 385                        debug("FM1@DTSEC%u expects SGMII in slot %u\n",
 386                              idx + 1, slot);
 387                        if (QIXIS_READ(present2) & (1 << (slot - 1)))
 388                                fm_disable_port(i);
 389
 390                        switch (slot) {
 391                        case 2:
 392                                mdio_mux[i] = EMI1_SLOT2;
 393                                fm_info_set_mdio(i, mii_dev_for_muxval(
 394                                                 mdio_mux[i]));
 395                                break;
 396                        case 3:
 397                                mdio_mux[i] = EMI1_SLOT3;
 398                                fm_info_set_mdio(i, mii_dev_for_muxval(
 399                                                 mdio_mux[i]));
 400                                break;
 401                        case 4:
 402                                mdio_mux[i] = EMI1_SLOT4;
 403                                fm_info_set_mdio(i, mii_dev_for_muxval(
 404                                                 mdio_mux[i]));
 405                                break;
 406                        case 5:
 407                                mdio_mux[i] = EMI1_SLOT5;
 408                                fm_info_set_mdio(i, mii_dev_for_muxval(
 409                                                 mdio_mux[i]));
 410                                break;
 411                        }
 412                        break;
 413                case PHY_INTERFACE_MODE_RGMII:
 414                        if (i == FM1_DTSEC3)
 415                                mdio_mux[i] = EMI1_RGMII2;
 416                        else if (i == FM1_DTSEC4)
 417                                mdio_mux[i] = EMI1_RGMII1;
 418                        fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 419                        break;
 420                default:
 421                        break;
 422                }
 423        }
 424
 425        for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
 426                idx = i - FM1_10GEC1;
 427                switch (fm_info_get_enet_if(i)) {
 428                case PHY_INTERFACE_MODE_XGMII:
 429                        lane = serdes_get_first_lane(FSL_SRDS_1,
 430                                                     XFI_FM1_MAC1 + idx);
 431                        if (lane < 0)
 432                                break;
 433                        mdio_mux[i] = EMI2;
 434                        fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 435                        break;
 436                default:
 437                        break;
 438                }
 439        }
 440
 441        cpu_eth_init(bis);
 442#endif /* CONFIG_FMAN_ENET */
 443
 444        return pci_eth_init(bis);
 445}
 446