uboot/board/freescale/p2041rdb/eth.c
<<
>>
Prefs
   1/*
   2 * Copyright 2011 Freescale Semiconductor, Inc.
   3 * Author: Mingkai Hu <Mingkai.hu@freescale.com>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8/*
   9 * The RGMII PHYs are provided by the two on-board PHY. The SGMII PHYs
  10 * are provided by the three on-board PHY or by the standard Freescale
  11 * four-port SGMII riser card. We need to change the phy-handle in the
  12 * kernel dts file to point to the correct PHY according to serdes mux
  13 * and serdes protocol selection.
  14 */
  15
  16#include <common.h>
  17#include <netdev.h>
  18#include <asm/fsl_serdes.h>
  19#include <fm_eth.h>
  20#include <fsl_mdio.h>
  21#include <malloc.h>
  22#include <fsl_dtsec.h>
  23
  24#include "cpld.h"
  25#include "../common/fman.h"
  26
  27#ifdef CONFIG_FMAN_ENET
  28/*
  29 * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means
  30 * that the mapping must be determined dynamically, or that the lane maps to
  31 * something other than a board slot
  32 */
  33static u8 lane_to_slot[] = {
  34        0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0
  35};
  36
  37static int riser_phy_addr[] = {
  38        CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR,
  39        CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR,
  40        CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR,
  41        CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR,
  42};
  43
  44/*
  45 * Initialize the lane_to_slot[] array.
  46 *
  47 * On the P2040RDB board the mapping is controlled by CPLD register.
  48 */
  49static void initialize_lane_to_slot(void)
  50{
  51        u8 mux = CPLD_READ(serdes_mux);
  52
  53        lane_to_slot[6] = (mux & SERDES_MUX_LANE_6_MASK) ? 0 : 1;
  54        lane_to_slot[10] = (mux & SERDES_MUX_LANE_A_MASK) ? 0 : 2;
  55        lane_to_slot[12] = (mux & SERDES_MUX_LANE_C_MASK) ? 0 : 2;
  56        lane_to_slot[13] = (mux & SERDES_MUX_LANE_D_MASK) ? 0 : 2;
  57}
  58
  59/*
  60 * Given the following ...
  61 *
  62 * 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
  63 * compatible string and 'addr' physical address)
  64 *
  65 * 2) An Fman port
  66 *
  67 * ... update the phy-handle property of the Ethernet node to point to the
  68 * right PHY.  This assumes that we already know the PHY for each port.
  69 *
  70 * The offset of the Fman Ethernet node is also passed in for convenience, but
  71 * it is not used, and we recalculate the offset anyway.
  72 *
  73 * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC.
  74 * Inside the Fman, "ports" are things that connect to MACs.  We only call them
  75 * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs
  76 * and ports are the same thing.
  77 *
  78 */
  79void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
  80                              enum fm_port port, int offset)
  81{
  82        phy_interface_t intf = fm_info_get_enet_if(port);
  83        char phy[16];
  84
  85        /* The RGMII PHY is identified by the MAC connected to it */
  86        if (intf == PHY_INTERFACE_MODE_RGMII) {
  87                sprintf(phy, "phy_rgmii_%u", port == FM1_DTSEC5 ? 0 : 1);
  88                fdt_set_phy_handle(fdt, compat, addr, phy);
  89        }
  90
  91        /* The SGMII PHY is identified by the MAC connected to it */
  92        if (intf == PHY_INTERFACE_MODE_SGMII) {
  93                int lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + port);
  94                u8 slot;
  95                if (lane < 0)
  96                        return;
  97                slot = lane_to_slot[lane];
  98                if (slot) {
  99                        sprintf(phy, "phy_sgmii_%x",
 100                                        CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR
 101                                        + (port - FM1_DTSEC1));
 102                        fdt_set_phy_handle(fdt, compat, addr, phy);
 103                } else {
 104                        sprintf(phy, "phy_sgmii_%x",
 105                                        CONFIG_SYS_FM1_DTSEC1_PHY_ADDR
 106                                        + (port - FM1_DTSEC1));
 107                        fdt_set_phy_handle(fdt, compat, addr, phy);
 108                }
 109        }
 110
 111        if (intf == PHY_INTERFACE_MODE_XGMII) {
 112                /* XAUI */
 113                int lane = serdes_get_first_lane(XAUI_FM1);
 114                if (lane >= 0) {
 115                        /* The XAUI PHY is identified by the slot */
 116                        sprintf(phy, "phy_xgmii_%u", lane_to_slot[lane]);
 117                        fdt_set_phy_handle(fdt, compat, addr, phy);
 118                }
 119        }
 120}
 121#endif /* #ifdef CONFIG_FMAN_ENET */
 122
 123int board_eth_init(bd_t *bis)
 124{
 125#ifdef CONFIG_FMAN_ENET
 126        struct fsl_pq_mdio_info dtsec_mdio_info;
 127        struct tgec_mdio_info tgec_mdio_info;
 128        unsigned int i, slot;
 129        int lane;
 130
 131        printf("Initializing Fman\n");
 132
 133        initialize_lane_to_slot();
 134
 135        dtsec_mdio_info.regs =
 136                (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
 137        dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
 138
 139        /* Register the real 1G MDIO bus */
 140        fsl_pq_mdio_init(bis, &dtsec_mdio_info);
 141
 142        tgec_mdio_info.regs =
 143                (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
 144        tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
 145
 146        /* Register the real 10G MDIO bus */
 147        fm_tgec_mdio_init(bis, &tgec_mdio_info);
 148
 149        /*
 150         * Program the three on-board SGMII PHY addresses. If the SGMII Riser
 151         * card used, we'll override the PHY address later. For any DTSEC that
 152         * is RGMII, we'll also override its PHY address later. We assume that
 153         * DTSEC4 and DTSEC5 are used for RGMII.
 154         */
 155        fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
 156        fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
 157        fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR);
 158
 159        for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
 160                int idx = i - FM1_DTSEC1;
 161
 162                switch (fm_info_get_enet_if(i)) {
 163                case PHY_INTERFACE_MODE_SGMII:
 164                        lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
 165                        if (lane < 0)
 166                                break;
 167                        slot = lane_to_slot[lane];
 168                        if (slot)
 169                                fm_info_set_phy_address(i, riser_phy_addr[i]);
 170                        break;
 171                case PHY_INTERFACE_MODE_RGMII:
 172                        /* Only DTSEC4 and DTSEC5 can be routed to RGMII */
 173                        fm_info_set_phy_address(i, i == FM1_DTSEC5 ?
 174                                        CONFIG_SYS_FM1_DTSEC5_PHY_ADDR :
 175                                        CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
 176                        break;
 177                default:
 178                        printf("Fman1: DTSEC%u set to unknown interface %i\n",
 179                               idx + 1, fm_info_get_enet_if(i));
 180                        break;
 181                }
 182
 183                fm_info_set_mdio(i,
 184                        miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
 185        }
 186
 187        lane = serdes_get_first_lane(XAUI_FM1);
 188        if (lane >= 0) {
 189                slot = lane_to_slot[lane];
 190                if (slot)
 191                        fm_info_set_phy_address(FM1_10GEC1,
 192                                        CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
 193        }
 194
 195        fm_info_set_mdio(FM1_10GEC1,
 196                        miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME));
 197        cpu_eth_init(bis);
 198#endif
 199
 200        return pci_eth_init(bis);
 201}
 202