uboot/board/freescale/ls1043aqds/eth.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <asm/io.h>
   9#include <netdev.h>
  10#include <fdt_support.h>
  11#include <fm_eth.h>
  12#include <fsl_mdio.h>
  13#include <fsl_dtsec.h>
  14#include <libfdt.h>
  15#include <malloc.h>
  16#include <asm/arch/fsl_serdes.h>
  17
  18#include "../common/qixis.h"
  19#include "../common/fman.h"
  20#include "ls1043aqds_qixis.h"
  21
  22#define EMI_NONE        0xFF
  23#define EMI1_RGMII1     0
  24#define EMI1_RGMII2     1
  25#define EMI1_SLOT1      2
  26#define EMI1_SLOT2      3
  27#define EMI1_SLOT3      4
  28#define EMI1_SLOT4      5
  29#define EMI2            6
  30
  31static int mdio_mux[NUM_FM_PORTS];
  32
  33static const char * const mdio_names[] = {
  34        "LS1043AQDS_MDIO_RGMII1",
  35        "LS1043AQDS_MDIO_RGMII2",
  36        "LS1043AQDS_MDIO_SLOT1",
  37        "LS1043AQDS_MDIO_SLOT2",
  38        "LS1043AQDS_MDIO_SLOT3",
  39        "LS1043AQDS_MDIO_SLOT4",
  40        "NULL",
  41};
  42
  43/* Map SerDes1 4 lanes to default slot, will be initialized dynamically */
  44static u8 lane_to_slot[] = {1, 2, 3, 4};
  45
  46static const char *ls1043aqds_mdio_name_for_muxval(u8 muxval)
  47{
  48        return mdio_names[muxval];
  49}
  50
  51struct mii_dev *mii_dev_for_muxval(u8 muxval)
  52{
  53        struct mii_dev *bus;
  54        const char *name;
  55
  56        if (muxval > EMI2)
  57                return NULL;
  58
  59        name = ls1043aqds_mdio_name_for_muxval(muxval);
  60
  61        if (!name) {
  62                printf("No bus for muxval %x\n", muxval);
  63                return NULL;
  64        }
  65
  66        bus = miiphy_get_dev_by_name(name);
  67
  68        if (!bus) {
  69                printf("No bus by name %s\n", name);
  70                return NULL;
  71        }
  72
  73        return bus;
  74}
  75
  76struct ls1043aqds_mdio {
  77        u8 muxval;
  78        struct mii_dev *realbus;
  79};
  80
  81static void ls1043aqds_mux_mdio(u8 muxval)
  82{
  83        u8 brdcfg4;
  84
  85        if (muxval < 7) {
  86                brdcfg4 = QIXIS_READ(brdcfg[4]);
  87                brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
  88                brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
  89                QIXIS_WRITE(brdcfg[4], brdcfg4);
  90        }
  91}
  92
  93static int ls1043aqds_mdio_read(struct mii_dev *bus, int addr, int devad,
  94                              int regnum)
  95{
  96        struct ls1043aqds_mdio *priv = bus->priv;
  97
  98        ls1043aqds_mux_mdio(priv->muxval);
  99
 100        return priv->realbus->read(priv->realbus, addr, devad, regnum);
 101}
 102
 103static int ls1043aqds_mdio_write(struct mii_dev *bus, int addr, int devad,
 104                               int regnum, u16 value)
 105{
 106        struct ls1043aqds_mdio *priv = bus->priv;
 107
 108        ls1043aqds_mux_mdio(priv->muxval);
 109
 110        return priv->realbus->write(priv->realbus, addr, devad,
 111                                    regnum, value);
 112}
 113
 114static int ls1043aqds_mdio_reset(struct mii_dev *bus)
 115{
 116        struct ls1043aqds_mdio *priv = bus->priv;
 117
 118        return priv->realbus->reset(priv->realbus);
 119}
 120
 121static int ls1043aqds_mdio_init(char *realbusname, u8 muxval)
 122{
 123        struct ls1043aqds_mdio *pmdio;
 124        struct mii_dev *bus = mdio_alloc();
 125
 126        if (!bus) {
 127                printf("Failed to allocate ls1043aqds MDIO bus\n");
 128                return -1;
 129        }
 130
 131        pmdio = malloc(sizeof(*pmdio));
 132        if (!pmdio) {
 133                printf("Failed to allocate ls1043aqds private data\n");
 134                free(bus);
 135                return -1;
 136        }
 137
 138        bus->read = ls1043aqds_mdio_read;
 139        bus->write = ls1043aqds_mdio_write;
 140        bus->reset = ls1043aqds_mdio_reset;
 141        strcpy(bus->name, ls1043aqds_mdio_name_for_muxval(muxval));
 142
 143        pmdio->realbus = miiphy_get_dev_by_name(realbusname);
 144
 145        if (!pmdio->realbus) {
 146                printf("No bus with name %s\n", realbusname);
 147                free(bus);
 148                free(pmdio);
 149                return -1;
 150        }
 151
 152        pmdio->muxval = muxval;
 153        bus->priv = pmdio;
 154        return mdio_register(bus);
 155}
 156
 157void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
 158                              enum fm_port port, int offset)
 159{
 160        struct fixed_link f_link;
 161
 162        if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
 163                if (port == FM1_DTSEC9) {
 164                        fdt_set_phy_handle(fdt, compat, addr,
 165                                           "sgmii_riser_s1_p1");
 166                } else if (port == FM1_DTSEC2) {
 167                        fdt_set_phy_handle(fdt, compat, addr,
 168                                           "sgmii_riser_s2_p1");
 169                } else if (port == FM1_DTSEC5) {
 170                        fdt_set_phy_handle(fdt, compat, addr,
 171                                           "sgmii_riser_s3_p1");
 172                } else if (port == FM1_DTSEC6) {
 173                        fdt_set_phy_handle(fdt, compat, addr,
 174                                           "sgmii_riser_s4_p1");
 175                }
 176        } else if (fm_info_get_enet_if(port) ==
 177                   PHY_INTERFACE_MODE_SGMII_2500) {
 178                /* 2.5G SGMII interface */
 179                f_link.phy_id = cpu_to_fdt32(port);
 180                f_link.duplex = cpu_to_fdt32(1);
 181                f_link.link_speed = cpu_to_fdt32(1000);
 182                f_link.pause = 0;
 183                f_link.asym_pause = 0;
 184                /* no PHY for 2.5G SGMII */
 185                fdt_delprop(fdt, offset, "phy-handle");
 186                fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link));
 187                fdt_setprop_string(fdt, offset, "phy-connection-type",
 188                                   "sgmii-2500");
 189        } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_QSGMII) {
 190                switch (mdio_mux[port]) {
 191                case EMI1_SLOT1:
 192                        switch (port) {
 193                        case FM1_DTSEC1:
 194                                fdt_set_phy_handle(fdt, compat, addr,
 195                                                   "qsgmii_s1_p1");
 196                                break;
 197                        case FM1_DTSEC2:
 198                                fdt_set_phy_handle(fdt, compat, addr,
 199                                                   "qsgmii_s1_p2");
 200                                break;
 201                        case FM1_DTSEC5:
 202                                fdt_set_phy_handle(fdt, compat, addr,
 203                                                   "qsgmii_s1_p3");
 204                                break;
 205                        case FM1_DTSEC6:
 206                                fdt_set_phy_handle(fdt, compat, addr,
 207                                                   "qsgmii_s1_p4");
 208                                break;
 209                        default:
 210                                break;
 211                        }
 212                        break;
 213                case EMI1_SLOT2:
 214                        switch (port) {
 215                        case FM1_DTSEC1:
 216                                fdt_set_phy_handle(fdt, compat, addr,
 217                                                   "qsgmii_s2_p1");
 218                                break;
 219                        case FM1_DTSEC2:
 220                                fdt_set_phy_handle(fdt, compat, addr,
 221                                                   "qsgmii_s2_p2");
 222                                break;
 223                        case FM1_DTSEC5:
 224                                fdt_set_phy_handle(fdt, compat, addr,
 225                                                   "qsgmii_s2_p3");
 226                                break;
 227                        case FM1_DTSEC6:
 228                                fdt_set_phy_handle(fdt, compat, addr,
 229                                                   "qsgmii_s2_p4");
 230                                break;
 231                        default:
 232                                break;
 233                        }
 234                        break;
 235                default:
 236                        break;
 237                }
 238                fdt_delprop(fdt, offset, "phy-connection-type");
 239                fdt_setprop_string(fdt, offset, "phy-connection-type",
 240                                   "qsgmii");
 241        } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII &&
 242                   port == FM1_10GEC1) {
 243                /* XFI interface */
 244                f_link.phy_id = cpu_to_fdt32(port);
 245                f_link.duplex = cpu_to_fdt32(1);
 246                f_link.link_speed = cpu_to_fdt32(10000);
 247                f_link.pause = 0;
 248                f_link.asym_pause = 0;
 249                /* no PHY for XFI */
 250                fdt_delprop(fdt, offset, "phy-handle");
 251                fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link));
 252                fdt_setprop_string(fdt, offset, "phy-connection-type", "xgmii");
 253        }
 254}
 255
 256void fdt_fixup_board_enet(void *fdt)
 257{
 258        int i;
 259        struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 260        u32 srds_s1;
 261
 262        srds_s1 = in_be32(&gur->rcwsr[4]) &
 263                        FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
 264        srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
 265
 266        for (i = FM1_DTSEC1; i < NUM_FM_PORTS; i++) {
 267                switch (fm_info_get_enet_if(i)) {
 268                case PHY_INTERFACE_MODE_SGMII:
 269                case PHY_INTERFACE_MODE_QSGMII:
 270                        switch (mdio_mux[i]) {
 271                        case EMI1_SLOT1:
 272                                fdt_status_okay_by_alias(fdt, "emi1_slot1");
 273                                break;
 274                        case EMI1_SLOT2:
 275                                fdt_status_okay_by_alias(fdt, "emi1_slot2");
 276                                break;
 277                        case EMI1_SLOT3:
 278                                fdt_status_okay_by_alias(fdt, "emi1_slot3");
 279                                break;
 280                        case EMI1_SLOT4:
 281                                fdt_status_okay_by_alias(fdt, "emi1_slot4");
 282                                break;
 283                        default:
 284                                break;
 285                        }
 286                        break;
 287                case PHY_INTERFACE_MODE_XGMII:
 288                        break;
 289                default:
 290                        break;
 291                }
 292        }
 293}
 294
 295int board_eth_init(bd_t *bis)
 296{
 297#ifdef CONFIG_FMAN_ENET
 298        int i, idx, lane, slot, interface;
 299        struct memac_mdio_info dtsec_mdio_info;
 300        struct memac_mdio_info tgec_mdio_info;
 301        struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 302        u32 srds_s1;
 303
 304        srds_s1 = in_be32(&gur->rcwsr[4]) &
 305                        FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
 306        srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
 307
 308        /* Initialize the mdio_mux array so we can recognize empty elements */
 309        for (i = 0; i < NUM_FM_PORTS; i++)
 310                mdio_mux[i] = EMI_NONE;
 311
 312        dtsec_mdio_info.regs =
 313                (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
 314
 315        dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
 316
 317        /* Register the 1G MDIO bus */
 318        fm_memac_mdio_init(bis, &dtsec_mdio_info);
 319
 320        tgec_mdio_info.regs =
 321                (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
 322        tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
 323
 324        /* Register the 10G MDIO bus */
 325        fm_memac_mdio_init(bis, &tgec_mdio_info);
 326
 327        /* Register the muxing front-ends to the MDIO buses */
 328        ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
 329        ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
 330        ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
 331        ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
 332        ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
 333        ls1043aqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
 334        ls1043aqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);
 335
 336        /* Set the two on-board RGMII PHY address */
 337        fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR);
 338        fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR);
 339
 340        switch (srds_s1) {
 341        case 0x2555:
 342                /* 2.5G SGMII on lane A, MAC 9 */
 343                fm_info_set_phy_address(FM1_DTSEC9, 9);
 344                break;
 345        case 0x4555:
 346        case 0x4558:
 347                /* QSGMII on lane A, MAC 1/2/5/6 */
 348                fm_info_set_phy_address(FM1_DTSEC1,
 349                                        QSGMII_CARD_PORT1_PHY_ADDR_S1);
 350                fm_info_set_phy_address(FM1_DTSEC2,
 351                                        QSGMII_CARD_PORT2_PHY_ADDR_S1);
 352                fm_info_set_phy_address(FM1_DTSEC5,
 353                                        QSGMII_CARD_PORT3_PHY_ADDR_S1);
 354                fm_info_set_phy_address(FM1_DTSEC6,
 355                                        QSGMII_CARD_PORT4_PHY_ADDR_S1);
 356                break;
 357        case 0x1355:
 358                /* SGMII on lane B, MAC 2*/
 359                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 360                break;
 361        case 0x2355:
 362                /* 2.5G SGMII on lane A, MAC 9 */
 363                fm_info_set_phy_address(FM1_DTSEC9, 9);
 364                /* SGMII on lane B, MAC 2*/
 365                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 366                break;
 367        case 0x3335:
 368                /* SGMII on lane C, MAC 5 */
 369                fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT1_PHY_ADDR);
 370        case 0x3355:
 371        case 0x3358:
 372                /* SGMII on lane B, MAC 2 */
 373                fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
 374        case 0x3555:
 375        case 0x3558:
 376                /* SGMII on lane A, MAC 9 */
 377                fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
 378                break;
 379        case 0x1455:
 380                /* QSGMII on lane B, MAC 1/2/5/6 */
 381                fm_info_set_phy_address(FM1_DTSEC1,
 382                                        QSGMII_CARD_PORT1_PHY_ADDR_S2);
 383                fm_info_set_phy_address(FM1_DTSEC2,
 384                                        QSGMII_CARD_PORT2_PHY_ADDR_S2);
 385                fm_info_set_phy_address(FM1_DTSEC5,
 386                                        QSGMII_CARD_PORT3_PHY_ADDR_S2);
 387                fm_info_set_phy_address(FM1_DTSEC6,
 388                                        QSGMII_CARD_PORT4_PHY_ADDR_S2);
 389                break;
 390        case 0x2455:
 391                /* 2.5G SGMII on lane A, MAC 9 */
 392                fm_info_set_phy_address(FM1_DTSEC9, 9);
 393                /* QSGMII on lane B, MAC 1/2/5/6 */
 394                fm_info_set_phy_address(FM1_DTSEC1,
 395                                        QSGMII_CARD_PORT1_PHY_ADDR_S2);
 396                fm_info_set_phy_address(FM1_DTSEC2,
 397                                        QSGMII_CARD_PORT2_PHY_ADDR_S2);
 398                fm_info_set_phy_address(FM1_DTSEC5,
 399                                        QSGMII_CARD_PORT3_PHY_ADDR_S2);
 400                fm_info_set_phy_address(FM1_DTSEC6,
 401                                        QSGMII_CARD_PORT4_PHY_ADDR_S2);
 402                break;
 403        case 0x2255:
 404                /* 2.5G SGMII on lane A, MAC 9 */
 405                fm_info_set_phy_address(FM1_DTSEC9, 9);
 406                /* 2.5G SGMII on lane B, MAC 2 */
 407                fm_info_set_phy_address(FM1_DTSEC2, 2);
 408                break;
 409        case 0x3333:
 410                /* SGMII on lane A/B/C/D, MAC 9/2/5/6 */
 411                fm_info_set_phy_address(FM1_DTSEC9,
 412                                        SGMII_CARD_PORT1_PHY_ADDR);
 413                fm_info_set_phy_address(FM1_DTSEC2,
 414                                        SGMII_CARD_PORT1_PHY_ADDR);
 415                fm_info_set_phy_address(FM1_DTSEC5,
 416                                        SGMII_CARD_PORT1_PHY_ADDR);
 417                fm_info_set_phy_address(FM1_DTSEC6,
 418                                        SGMII_CARD_PORT1_PHY_ADDR);
 419                break;
 420        default:
 421                printf("Invalid SerDes protocol 0x%x for LS1043AQDS\n",
 422                       srds_s1);
 423                break;
 424        }
 425
 426        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 427                idx = i - FM1_DTSEC1;
 428                interface = fm_info_get_enet_if(i);
 429                switch (interface) {
 430                case PHY_INTERFACE_MODE_SGMII:
 431                case PHY_INTERFACE_MODE_SGMII_2500:
 432                case PHY_INTERFACE_MODE_QSGMII:
 433                        if (interface == PHY_INTERFACE_MODE_SGMII) {
 434                                lane = serdes_get_first_lane(FSL_SRDS_1,
 435                                                SGMII_FM1_DTSEC1 + idx);
 436                        } else if (interface == PHY_INTERFACE_MODE_SGMII_2500) {
 437                                lane = serdes_get_first_lane(FSL_SRDS_1,
 438                                                SGMII_2500_FM1_DTSEC1 + idx);
 439                        } else {
 440                                lane = serdes_get_first_lane(FSL_SRDS_1,
 441                                                QSGMII_FM1_A);
 442                        }
 443
 444                        if (lane < 0)
 445                                break;
 446
 447                        slot = lane_to_slot[lane];
 448                        debug("FM1@DTSEC%u expects SGMII in slot %u\n",
 449                              idx + 1, slot);
 450                        if (QIXIS_READ(present2) & (1 << (slot - 1)))
 451                                fm_disable_port(i);
 452
 453                        switch (slot) {
 454                        case 1:
 455                                mdio_mux[i] = EMI1_SLOT1;
 456                                fm_info_set_mdio(i, mii_dev_for_muxval(
 457                                                 mdio_mux[i]));
 458                                break;
 459                        case 2:
 460                                mdio_mux[i] = EMI1_SLOT2;
 461                                fm_info_set_mdio(i, mii_dev_for_muxval(
 462                                                 mdio_mux[i]));
 463                                break;
 464                        case 3:
 465                                mdio_mux[i] = EMI1_SLOT3;
 466                                fm_info_set_mdio(i, mii_dev_for_muxval(
 467                                                 mdio_mux[i]));
 468                                break;
 469                        case 4:
 470                                mdio_mux[i] = EMI1_SLOT4;
 471                                fm_info_set_mdio(i, mii_dev_for_muxval(
 472                                                 mdio_mux[i]));
 473                                break;
 474                        default:
 475                                break;
 476                        }
 477                        break;
 478                case PHY_INTERFACE_MODE_RGMII:
 479                        if (i == FM1_DTSEC3)
 480                                mdio_mux[i] = EMI1_RGMII1;
 481                        else if (i == FM1_DTSEC4)
 482                                mdio_mux[i] = EMI1_RGMII2;
 483                        fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 484                        break;
 485                default:
 486                        break;
 487                }
 488        }
 489
 490        cpu_eth_init(bis);
 491#endif /* CONFIG_FMAN_ENET */
 492
 493        return pci_eth_init(bis);
 494}
 495