uboot/board/freescale/ls1012aqds/eth.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2015-2016 Freescale Semiconductor, Inc.
   4 * Copyright 2017 NXP
   5 */
   6
   7#include <common.h>
   8#include <dm.h>
   9#include <asm/io.h>
  10#include <netdev.h>
  11#include <fm_eth.h>
  12#include <fsl_mdio.h>
  13#include <malloc.h>
  14#include <asm/types.h>
  15#include <fsl_dtsec.h>
  16#include <asm/arch/soc.h>
  17#include <asm/arch-fsl-layerscape/config.h>
  18#include <asm/arch-fsl-layerscape/immap_lsch2.h>
  19#include <asm/arch/fsl_serdes.h>
  20#include <linux/delay.h>
  21#include "../common/qixis.h"
  22#include <net/pfe_eth/pfe_eth.h>
  23#include <dm/platform_data/pfe_dm_eth.h>
  24#include "ls1012aqds_qixis.h"
  25
  26#define EMI_NONE        0xFF
  27#define EMI1_RGMII      1
  28#define EMI1_SLOT1      2
  29#define EMI1_SLOT2      3
  30
  31#define DEFAULT_PFE_MDIO_NAME "PFE_MDIO"
  32#define DEFAULT_PFE_MDIO1_NAME "PFE_MDIO1"
  33
  34static const char * const mdio_names[] = {
  35        "NULL",
  36        "LS1012AQDS_MDIO_RGMII",
  37        "LS1012AQDS_MDIO_SLOT1",
  38        "LS1012AQDS_MDIO_SLOT2",
  39        "NULL",
  40};
  41
  42static const char *ls1012aqds_mdio_name_for_muxval(u8 muxval)
  43{
  44        return mdio_names[muxval];
  45}
  46
  47struct ls1012aqds_mdio {
  48        u8 muxval;
  49        struct mii_dev *realbus;
  50};
  51
  52static void ls1012aqds_mux_mdio(u8 muxval)
  53{
  54        u8 brdcfg4;
  55
  56        if (muxval < 7) {
  57                brdcfg4 = QIXIS_READ(brdcfg[4]);
  58                brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
  59                brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
  60                QIXIS_WRITE(brdcfg[4], brdcfg4);
  61        }
  62}
  63
  64static int ls1012aqds_mdio_read(struct mii_dev *bus, int addr, int devad,
  65                                int regnum)
  66{
  67        struct ls1012aqds_mdio *priv = bus->priv;
  68
  69        ls1012aqds_mux_mdio(priv->muxval);
  70
  71        return priv->realbus->read(priv->realbus, addr, devad, regnum);
  72}
  73
  74static int ls1012aqds_mdio_write(struct mii_dev *bus, int addr, int devad,
  75                                 int regnum, u16 value)
  76{
  77        struct ls1012aqds_mdio *priv = bus->priv;
  78
  79        ls1012aqds_mux_mdio(priv->muxval);
  80
  81        return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
  82}
  83
  84static int ls1012aqds_mdio_reset(struct mii_dev *bus)
  85{
  86        struct ls1012aqds_mdio *priv = bus->priv;
  87
  88        if (priv->realbus->reset)
  89                return priv->realbus->reset(priv->realbus);
  90        else
  91                return -1;
  92}
  93
  94static int ls1012aqds_mdio_init(char *realbusname, u8 muxval)
  95{
  96        struct ls1012aqds_mdio *pmdio;
  97        struct mii_dev *bus = mdio_alloc();
  98
  99        if (!bus) {
 100                printf("Failed to allocate ls1012aqds MDIO bus\n");
 101                return -1;
 102        }
 103
 104        pmdio = malloc(sizeof(*pmdio));
 105        if (!pmdio) {
 106                printf("Failed to allocate ls1012aqds private data\n");
 107                free(bus);
 108                return -1;
 109        }
 110
 111        bus->read = ls1012aqds_mdio_read;
 112        bus->write = ls1012aqds_mdio_write;
 113        bus->reset = ls1012aqds_mdio_reset;
 114        sprintf(bus->name, ls1012aqds_mdio_name_for_muxval(muxval));
 115
 116        pmdio->realbus = miiphy_get_dev_by_name(realbusname);
 117
 118        if (!pmdio->realbus) {
 119                printf("No bus with name %s\n", realbusname);
 120                free(bus);
 121                free(pmdio);
 122                return -1;
 123        }
 124
 125        pmdio->muxval = muxval;
 126        bus->priv = pmdio;
 127        return mdio_register(bus);
 128}
 129
 130int pfe_eth_board_init(struct udevice *dev)
 131{
 132        static int init_done;
 133        struct mii_dev *bus;
 134        static const char *mdio_name;
 135        struct pfe_mdio_info mac_mdio_info;
 136        struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
 137        u8 data8;
 138        struct pfe_eth_dev *priv = dev_get_priv(dev);
 139
 140        int srds_s1 = in_be32(&gur->rcwsr[4]) &
 141                        FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
 142        srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
 143
 144        ls1012aqds_mux_mdio(EMI1_SLOT1);
 145
 146        if (!init_done) {
 147                mac_mdio_info.reg_base = (void *)EMAC1_BASE_ADDR;
 148                mac_mdio_info.name = DEFAULT_PFE_MDIO_NAME;
 149
 150                bus = pfe_mdio_init(&mac_mdio_info);
 151                if (!bus) {
 152                        printf("Failed to register mdio\n");
 153                        return -1;
 154                }
 155                init_done = 1;
 156        }
 157
 158        if (priv->gemac_port) {
 159                mac_mdio_info.reg_base = (void *)EMAC2_BASE_ADDR;
 160                mac_mdio_info.name = DEFAULT_PFE_MDIO1_NAME;
 161
 162                bus = pfe_mdio_init(&mac_mdio_info);
 163                if (!bus) {
 164                        printf("Failed to register mdio\n");
 165                        return -1;
 166                }
 167        }
 168
 169        switch (srds_s1) {
 170        case 0x3508:
 171                printf("ls1012aqds:supported SerDes PRCTL= %d\n", srds_s1);
 172#ifdef CONFIG_PFE_RGMII_RESET_WA
 173                /*
 174                 * Work around for FPGA registers initialization
 175                 * This is needed for RGMII to work.
 176                 */
 177                printf("Reset RGMII WA....\n");
 178                data8 = QIXIS_READ(rst_frc[0]);
 179                data8 |= 0x2;
 180                QIXIS_WRITE(rst_frc[0], data8);
 181                data8 = QIXIS_READ(rst_frc[0]);
 182
 183                data8 = QIXIS_READ(res8[6]);
 184                data8 |= 0xff;
 185                QIXIS_WRITE(res8[6], data8);
 186                data8 = QIXIS_READ(res8[6]);
 187#endif
 188        if (priv->gemac_port) {
 189                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_RGMII);
 190                if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_RGMII)
 191                    < 0) {
 192                        printf("Failed to register mdio for %s\n", mdio_name);
 193                }
 194
 195                /* MAC2 */
 196                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_RGMII);
 197                bus = miiphy_get_dev_by_name(mdio_name);
 198                pfe_set_mdio(priv->gemac_port, bus);
 199                pfe_set_phy_address_mode(priv->gemac_port,
 200                                         CONFIG_PFE_EMAC2_PHY_ADDR,
 201                                         PHY_INTERFACE_MODE_RGMII);
 202
 203        } else {
 204                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
 205                if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT1)
 206                < 0) {
 207                        printf("Failed to register mdio for %s\n", mdio_name);
 208                }
 209
 210                /* MAC1 */
 211                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
 212                bus = miiphy_get_dev_by_name(mdio_name);
 213                pfe_set_mdio(priv->gemac_port, bus);
 214                pfe_set_phy_address_mode(priv->gemac_port,
 215                                         CONFIG_PFE_EMAC1_PHY_ADDR,
 216                                         PHY_INTERFACE_MODE_SGMII);
 217        }
 218
 219                break;
 220
 221        case 0x2205:
 222                printf("ls1012aqds:supported SerDes PRCTL= %d\n", srds_s1);
 223                /*
 224                 * Work around for FPGA registers initialization
 225                 * This is needed for RGMII to work.
 226                 */
 227                printf("Reset SLOT1 SLOT2....\n");
 228                data8 = QIXIS_READ(rst_frc[2]);
 229                data8 |= 0xc0;
 230                QIXIS_WRITE(rst_frc[2], data8);
 231                mdelay(100);
 232                data8 = QIXIS_READ(rst_frc[2]);
 233                data8 &= 0x3f;
 234                QIXIS_WRITE(rst_frc[2], data8);
 235
 236        if (priv->gemac_port) {
 237                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT2);
 238                if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT2)
 239                < 0) {
 240                        printf("Failed to register mdio for %s\n", mdio_name);
 241                }
 242                /* MAC2 */
 243                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT2);
 244                bus = miiphy_get_dev_by_name(mdio_name);
 245                pfe_set_mdio(1, bus);
 246                pfe_set_phy_address_mode(1, CONFIG_PFE_SGMII_2500_PHY2_ADDR,
 247                                         PHY_INTERFACE_MODE_SGMII_2500);
 248
 249                data8 = QIXIS_READ(brdcfg[12]);
 250                data8 |= 0x20;
 251                QIXIS_WRITE(brdcfg[12], data8);
 252
 253        } else {
 254                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
 255                if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT1)
 256                    < 0) {
 257                        printf("Failed to register mdio for %s\n", mdio_name);
 258                }
 259
 260                /* MAC1 */
 261                mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
 262                bus = miiphy_get_dev_by_name(mdio_name);
 263                pfe_set_mdio(0, bus);
 264                pfe_set_phy_address_mode(0,
 265                                         CONFIG_PFE_SGMII_2500_PHY1_ADDR,
 266                                         PHY_INTERFACE_MODE_SGMII_2500);
 267        }
 268                break;
 269
 270        default:
 271                printf("ls1012aqds:unsupported SerDes PRCTL= %d\n", srds_s1);
 272                break;
 273        }
 274        return 0;
 275}
 276
 277static struct pfe_eth_pdata pfe_pdata0 = {
 278        .pfe_eth_pdata_mac = {
 279                .iobase = (phys_addr_t)EMAC1_BASE_ADDR,
 280                .phy_interface = 0,
 281        },
 282
 283        .pfe_ddr_addr = {
 284                .ddr_pfe_baseaddr = (void *)CONFIG_DDR_PFE_BASEADDR,
 285                .ddr_pfe_phys_baseaddr = CONFIG_DDR_PFE_PHYS_BASEADDR,
 286        },
 287};
 288
 289static struct pfe_eth_pdata pfe_pdata1 = {
 290        .pfe_eth_pdata_mac = {
 291                .iobase = (phys_addr_t)EMAC2_BASE_ADDR,
 292                .phy_interface = 1,
 293        },
 294
 295        .pfe_ddr_addr = {
 296                .ddr_pfe_baseaddr = (void *)CONFIG_DDR_PFE_BASEADDR,
 297                .ddr_pfe_phys_baseaddr = CONFIG_DDR_PFE_PHYS_BASEADDR,
 298        },
 299};
 300
 301U_BOOT_DEVICE(ls1012a_pfe0) = {
 302        .name = "pfe_eth",
 303        .platdata = &pfe_pdata0,
 304};
 305
 306U_BOOT_DEVICE(ls1012a_pfe1) = {
 307        .name = "pfe_eth",
 308        .platdata = &pfe_pdata1,
 309};
 310