uboot/board/freescale/t1040qds/eth.c
<<
>>
Prefs
   1/*
   2 * Copyright 2013 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7/*
   8 * The RGMII PHYs are provided by the two on-board PHY connected to
   9 * dTSEC instances 4 and 5. The SGMII PHYs are provided by one on-board
  10 * PHY or by the standard four-port SGMII riser card (VSC).
  11 */
  12
  13#include <common.h>
  14#include <netdev.h>
  15#include <asm/fsl_serdes.h>
  16#include <asm/immap_85xx.h>
  17#include <fm_eth.h>
  18#include <fsl_mdio.h>
  19#include <malloc.h>
  20#include <asm/fsl_dtsec.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        sprintf(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[7] = 7;
 220                break;
 221        case 0x8d:
 222                lane_to_slot[1] = 7;
 223                lane_to_slot[2] = 7;
 224                lane_to_slot[3] = 7;
 225                lane_to_slot[5] = 3;
 226                lane_to_slot[6] = 3;
 227                lane_to_slot[7] = 3;
 228                break;
 229        case 0x8F:
 230        case 0x85:
 231                lane_to_slot[1] = 7;
 232                lane_to_slot[2] = 6;
 233                lane_to_slot[3] = 5;
 234                lane_to_slot[6] = 3;
 235                lane_to_slot[7] = 3;
 236                break;
 237        case 0xA5:
 238                lane_to_slot[1] = 7;
 239                lane_to_slot[6] = 3;
 240                lane_to_slot[7] = 3;
 241                break;
 242        case 0xA7:
 243                lane_to_slot[1] = 7;
 244                lane_to_slot[2] = 6;
 245                lane_to_slot[3] = 5;
 246                lane_to_slot[7] = 7;
 247                break;
 248        case 0xAA:
 249                lane_to_slot[1] = 7;
 250                lane_to_slot[6] = 7;
 251                lane_to_slot[7] = 7;
 252                break;
 253        case 0x40:
 254                lane_to_slot[2] = 7;
 255                lane_to_slot[3] = 7;
 256                break;
 257        default:
 258                printf("qds: Fman: Unsupported SerDes Protocol 0x%02x\n",
 259                       serdes1_prtcl);
 260                break;
 261        }
 262}
 263
 264/*
 265 * Given the following ...
 266 *
 267 * 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
 268 * compatible string and 'addr' physical address)
 269 *
 270 * 2) An Fman port
 271 *
 272 * ... update the phy-handle property of the Ethernet node to point to the
 273 * right PHY. This assumes that we already know the PHY for each port.
 274 *
 275 * The offset of the Fman Ethernet node is also passed in for convenience, but
 276 * it is not used, and we recalculate the offset anyway.
 277 *
 278 * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC.
 279 * Inside the Fman, "ports" are things that connect to MACs. We only call them
 280 * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs
 281 * and ports are the same thing.
 282 *
 283 */
 284void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
 285                              enum fm_port port, int offset)
 286{
 287        phy_interface_t intf = fm_info_get_enet_if(port);
 288        char phy[16];
 289
 290        /* The RGMII PHY is identified by the MAC connected to it */
 291        if (intf == PHY_INTERFACE_MODE_RGMII) {
 292                sprintf(phy, "rgmii_phy%u", port == FM1_DTSEC4 ? 1 : 2);
 293                fdt_set_phy_handle(fdt, compat, addr, phy);
 294        }
 295
 296        /* The SGMII PHY is identified by the MAC connected to it */
 297        if (intf == PHY_INTERFACE_MODE_SGMII) {
 298                int lane = serdes_get_first_lane(FSL_SRDS_1, SGMII_FM1_DTSEC1
 299                                                 + port);
 300                u8 slot;
 301                if (lane < 0)
 302                        return;
 303                slot = lane_to_slot[lane];
 304                if (slot) {
 305                        /* Slot housing a SGMII riser card */
 306                        sprintf(phy, "phy_s%x_%02x", slot,
 307                                (fm_info_get_phy_address(port - FM1_DTSEC1)-
 308                                CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + 1));
 309                        fdt_set_phy_handle(fdt, compat, addr, phy);
 310                }
 311        }
 312}
 313
 314void fdt_fixup_board_enet(void *fdt)
 315{
 316        int i, lane, idx;
 317
 318        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 319                idx = i - FM1_DTSEC1;
 320                switch (fm_info_get_enet_if(i)) {
 321                case PHY_INTERFACE_MODE_SGMII:
 322                        lane = serdes_get_first_lane(FSL_SRDS_1,
 323                                                     SGMII_FM1_DTSEC1 + idx);
 324                        if (lane < 0)
 325                                break;
 326
 327                        switch (mdio_mux[i]) {
 328                        case EMI1_SLOT3:
 329                                fdt_status_okay_by_alias(fdt, "emi1_slot3");
 330                                break;
 331                        case EMI1_SLOT5:
 332                                fdt_status_okay_by_alias(fdt, "emi1_slot5");
 333                                break;
 334                        case EMI1_SLOT6:
 335                                fdt_status_okay_by_alias(fdt, "emi1_slot6");
 336                                break;
 337                        case EMI1_SLOT7:
 338                                fdt_status_okay_by_alias(fdt, "emi1_slot7");
 339                                break;
 340                        }
 341                break;
 342                case PHY_INTERFACE_MODE_RGMII:
 343                        if (i == FM1_DTSEC4)
 344                                fdt_status_okay_by_alias(fdt, "emi1_rgmii0");
 345
 346                        if (i == FM1_DTSEC5)
 347                                fdt_status_okay_by_alias(fdt, "emi1_rgmii1");
 348                        break;
 349                default:
 350                        break;
 351                }
 352        }
 353}
 354#endif /* #ifdef CONFIG_FMAN_ENET */
 355
 356static void set_brdcfg9_for_gtx_clk(void)
 357{
 358        u8 brdcfg9;
 359        brdcfg9 = QIXIS_READ(brdcfg[9]);
 360/* Initializing EPHY2 clock to RGMII mode */
 361        brdcfg9 &= ~(BRDCFG9_EPHY2_MASK);
 362        brdcfg9 |= (BRDCFG9_EPHY2_VAL);
 363        QIXIS_WRITE(brdcfg[9], brdcfg9);
 364}
 365
 366void t1040_handle_phy_interface_sgmii(int i)
 367{
 368        int lane, idx, slot;
 369        idx = i - FM1_DTSEC1;
 370        lane = serdes_get_first_lane(FSL_SRDS_1,
 371                        SGMII_FM1_DTSEC1 + idx);
 372
 373        if (lane < 0)
 374                return;
 375        slot = lane_to_slot[lane];
 376
 377        switch (slot) {
 378        case 1:
 379                mdio_mux[i] = EMI1_SLOT1;
 380                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 381                break;
 382        case 3:
 383                if (FM1_DTSEC4 == i)
 384                        fm_info_set_phy_address(i, riser_phy_addr[0]);
 385                if (FM1_DTSEC5 == i)
 386                        fm_info_set_phy_address(i, riser_phy_addr[1]);
 387
 388                mdio_mux[i] = EMI1_SLOT3;
 389
 390                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 391                break;
 392        case 4:
 393                mdio_mux[i] = EMI1_SLOT4;
 394                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 395                break;
 396        case 5:
 397                /* Slot housing a SGMII riser card? */
 398                fm_info_set_phy_address(i, riser_phy_addr[0]);
 399                mdio_mux[i] = EMI1_SLOT5;
 400                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 401                break;
 402        case 6:
 403                /* Slot housing a SGMII riser card? */
 404                fm_info_set_phy_address(i, riser_phy_addr[0]);
 405                mdio_mux[i] = EMI1_SLOT6;
 406                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 407                break;
 408        case 7:
 409                if (FM1_DTSEC1 == i)
 410                        fm_info_set_phy_address(i, riser_phy_addr[0]);
 411                if (FM1_DTSEC2 == i)
 412                        fm_info_set_phy_address(i, riser_phy_addr[1]);
 413                if (FM1_DTSEC3 == i)
 414                        fm_info_set_phy_address(i, riser_phy_addr[2]);
 415                if (FM1_DTSEC5 == i)
 416                        fm_info_set_phy_address(i, riser_phy_addr[3]);
 417
 418                mdio_mux[i] = EMI1_SLOT7;
 419                fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 420                break;
 421        default:
 422                break;
 423        }
 424        fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 425}
 426void t1040_handle_phy_interface_rgmii(int i)
 427{
 428        fm_info_set_phy_address(i, i == FM1_DTSEC5 ?
 429                        CONFIG_SYS_FM1_DTSEC5_PHY_ADDR :
 430                        CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
 431        mdio_mux[i] = (i == FM1_DTSEC5) ? EMI1_RGMII1 :
 432                EMI1_RGMII0;
 433        fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
 434}
 435
 436int board_eth_init(bd_t *bis)
 437{
 438#ifdef CONFIG_FMAN_ENET
 439        struct memac_mdio_info memac_mdio_info;
 440        unsigned int i;
 441
 442        printf("Initializing Fman\n");
 443        set_brdcfg9_for_gtx_clk();
 444
 445        initialize_lane_to_slot();
 446
 447        /* Initialize the mdio_mux array so we can recognize empty elements */
 448        for (i = 0; i < NUM_FM_PORTS; i++)
 449                mdio_mux[i] = EMI_NONE;
 450
 451        memac_mdio_info.regs =
 452                (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
 453        memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;
 454
 455        /* Register the real 1G MDIO bus */
 456        fm_memac_mdio_init(bis, &memac_mdio_info);
 457
 458        /* Register the muxing front-ends to the MDIO buses */
 459        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII0);
 460        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
 461        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
 462        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
 463        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
 464        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
 465        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6);
 466        t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7);
 467
 468        /*
 469         * Program on board RGMII PHY addresses. If the SGMII Riser
 470         * card used, we'll override the PHY address later. For any DTSEC that
 471         * is RGMII, we'll also override its PHY address later. We assume that
 472         * DTSEC4 and DTSEC5 are used for RGMII.
 473         */
 474        fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
 475        fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
 476
 477        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 478                switch (fm_info_get_enet_if(i)) {
 479                case PHY_INTERFACE_MODE_QSGMII:
 480                        break;
 481                case PHY_INTERFACE_MODE_SGMII:
 482                        t1040_handle_phy_interface_sgmii(i);
 483                        break;
 484
 485                case PHY_INTERFACE_MODE_RGMII:
 486                        /* Only DTSEC4 and DTSEC5 can be routed to RGMII */
 487                        t1040_handle_phy_interface_rgmii(i);
 488                        break;
 489                default:
 490                        break;
 491                }
 492        }
 493
 494        cpu_eth_init(bis);
 495#endif
 496
 497        return pci_eth_init(bis);
 498}
 499