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