uboot/drivers/net/bcm6348-eth.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
   4 *
   5 * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
   6 *      Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
   7 */
   8
   9#include <common.h>
  10#include <clk.h>
  11#include <dm.h>
  12#include <dma.h>
  13#include <miiphy.h>
  14#include <net.h>
  15#include <phy.h>
  16#include <reset.h>
  17#include <wait_bit.h>
  18#include <asm/io.h>
  19
  20#define ETH_RX_DESC                     PKTBUFSRX
  21#define ETH_MAX_MTU_SIZE                1518
  22#define ETH_TIMEOUT                     100
  23#define ETH_TX_WATERMARK                32
  24
  25/* ETH Receiver Configuration register */
  26#define ETH_RXCFG_REG                   0x00
  27#define ETH_RXCFG_ENFLOW_SHIFT          5
  28#define ETH_RXCFG_ENFLOW_MASK           (1 << ETH_RXCFG_ENFLOW_SHIFT)
  29
  30/* ETH Receive Maximum Length register */
  31#define ETH_RXMAXLEN_REG                0x04
  32#define ETH_RXMAXLEN_SHIFT              0
  33#define ETH_RXMAXLEN_MASK               (0x7ff << ETH_RXMAXLEN_SHIFT)
  34
  35/* ETH Transmit Maximum Length register */
  36#define ETH_TXMAXLEN_REG                0x08
  37#define ETH_TXMAXLEN_SHIFT              0
  38#define ETH_TXMAXLEN_MASK               (0x7ff << ETH_TXMAXLEN_SHIFT)
  39
  40/* MII Status/Control register */
  41#define MII_SC_REG                      0x10
  42#define MII_SC_MDCFREQDIV_SHIFT         0
  43#define MII_SC_MDCFREQDIV_MASK          (0x7f << MII_SC_MDCFREQDIV_SHIFT)
  44#define MII_SC_PREAMBLE_EN_SHIFT        7
  45#define MII_SC_PREAMBLE_EN_MASK         (1 << MII_SC_PREAMBLE_EN_SHIFT)
  46
  47/* MII Data register */
  48#define MII_DAT_REG                     0x14
  49#define MII_DAT_DATA_SHIFT              0
  50#define MII_DAT_DATA_MASK               (0xffff << MII_DAT_DATA_SHIFT)
  51#define MII_DAT_TA_SHIFT                16
  52#define MII_DAT_TA_MASK                 (0x3 << MII_DAT_TA_SHIFT)
  53#define MII_DAT_REG_SHIFT               18
  54#define MII_DAT_REG_MASK                (0x1f << MII_DAT_REG_SHIFT)
  55#define MII_DAT_PHY_SHIFT               23
  56#define MII_DAT_PHY_MASK                (0x1f << MII_DAT_PHY_SHIFT)
  57#define MII_DAT_OP_SHIFT                28
  58#define MII_DAT_OP_WRITE                (0x5 << MII_DAT_OP_SHIFT)
  59#define MII_DAT_OP_READ                 (0x6 << MII_DAT_OP_SHIFT)
  60
  61/* ETH Interrupts Mask register */
  62#define ETH_IRMASK_REG                  0x18
  63
  64/* ETH Interrupts register */
  65#define ETH_IR_REG                      0x1c
  66#define ETH_IR_MII_SHIFT                0
  67#define ETH_IR_MII_MASK                 (1 << ETH_IR_MII_SHIFT)
  68
  69/* ETH Control register */
  70#define ETH_CTL_REG                     0x2c
  71#define ETH_CTL_ENABLE_SHIFT            0
  72#define ETH_CTL_ENABLE_MASK             (1 << ETH_CTL_ENABLE_SHIFT)
  73#define ETH_CTL_DISABLE_SHIFT           1
  74#define ETH_CTL_DISABLE_MASK            (1 << ETH_CTL_DISABLE_SHIFT)
  75#define ETH_CTL_RESET_SHIFT             2
  76#define ETH_CTL_RESET_MASK              (1 << ETH_CTL_RESET_SHIFT)
  77#define ETH_CTL_EPHY_SHIFT              3
  78#define ETH_CTL_EPHY_MASK               (1 << ETH_CTL_EPHY_SHIFT)
  79
  80/* ETH Transmit Control register */
  81#define ETH_TXCTL_REG                   0x30
  82#define ETH_TXCTL_FD_SHIFT              0
  83#define ETH_TXCTL_FD_MASK               (1 << ETH_TXCTL_FD_SHIFT)
  84
  85/* ETH Transmit Watermask register */
  86#define ETH_TXWMARK_REG                 0x34
  87#define ETH_TXWMARK_WM_SHIFT            0
  88#define ETH_TXWMARK_WM_MASK             (0x3f << ETH_TXWMARK_WM_SHIFT)
  89
  90/* MIB Control register */
  91#define MIB_CTL_REG                     0x38
  92#define MIB_CTL_RDCLEAR_SHIFT           0
  93#define MIB_CTL_RDCLEAR_MASK            (1 << MIB_CTL_RDCLEAR_SHIFT)
  94
  95/* ETH Perfect Match registers */
  96#define ETH_PM_CNT                      4
  97#define ETH_PML_REG(x)                  (0x58 + (x) * 0x8)
  98#define ETH_PMH_REG(x)                  (0x5c + (x) * 0x8)
  99#define ETH_PMH_VALID_SHIFT             16
 100#define ETH_PMH_VALID_MASK              (1 << ETH_PMH_VALID_SHIFT)
 101
 102/* MIB Counters registers */
 103#define MIB_REG_CNT                     55
 104#define MIB_REG(x)                      (0x200 + (x) * 4)
 105
 106/* ETH data */
 107struct bcm6348_eth_priv {
 108        void __iomem *base;
 109        /* DMA */
 110        struct dma rx_dma;
 111        struct dma tx_dma;
 112        /* PHY */
 113        int phy_id;
 114        struct phy_device *phy_dev;
 115};
 116
 117static void bcm6348_eth_mac_disable(struct bcm6348_eth_priv *priv)
 118{
 119        /* disable emac */
 120        clrsetbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK,
 121                        ETH_CTL_DISABLE_MASK);
 122
 123        /* wait until emac is disabled */
 124        if (wait_for_bit_be32(priv->base + ETH_CTL_REG,
 125                              ETH_CTL_DISABLE_MASK, false,
 126                              ETH_TIMEOUT, false))
 127                pr_err("%s: error disabling emac\n", __func__);
 128}
 129
 130static void bcm6348_eth_mac_enable(struct bcm6348_eth_priv *priv)
 131{
 132        setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK);
 133}
 134
 135static void bcm6348_eth_mac_reset(struct bcm6348_eth_priv *priv)
 136{
 137        /* reset emac */
 138        writel_be(ETH_CTL_RESET_MASK, priv->base + ETH_CTL_REG);
 139        wmb();
 140
 141        /* wait until emac is reset */
 142        if (wait_for_bit_be32(priv->base + ETH_CTL_REG,
 143                              ETH_CTL_RESET_MASK, false,
 144                              ETH_TIMEOUT, false))
 145                pr_err("%s: error resetting emac\n", __func__);
 146}
 147
 148static int bcm6348_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
 149{
 150        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 151
 152        return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
 153}
 154
 155static int bcm6348_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 156{
 157        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 158
 159        return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
 160}
 161
 162static int bcm6348_eth_send(struct udevice *dev, void *packet, int length)
 163{
 164        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 165
 166        return dma_send(&priv->tx_dma, packet, length, NULL);
 167}
 168
 169static int bcm6348_eth_adjust_link(struct udevice *dev,
 170                                   struct phy_device *phydev)
 171{
 172        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 173
 174        /* mac duplex parameters */
 175        if (phydev->duplex)
 176                setbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK);
 177        else
 178                clrbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK);
 179
 180        /* rx flow control (pause frame handling) */
 181        if (phydev->pause)
 182                setbits_be32(priv->base + ETH_RXCFG_REG,
 183                             ETH_RXCFG_ENFLOW_MASK);
 184        else
 185                clrbits_be32(priv->base + ETH_RXCFG_REG,
 186                             ETH_RXCFG_ENFLOW_MASK);
 187
 188        return 0;
 189}
 190
 191static int bcm6348_eth_start(struct udevice *dev)
 192{
 193        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 194        int ret, i;
 195
 196        /* prepare rx dma buffers */
 197        for (i = 0; i < ETH_RX_DESC; i++) {
 198                ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
 199                                          PKTSIZE_ALIGN);
 200                if (ret < 0)
 201                        break;
 202        }
 203
 204        /* enable dma rx channel */
 205        dma_enable(&priv->rx_dma);
 206
 207        /* enable dma tx channel */
 208        dma_enable(&priv->tx_dma);
 209
 210        ret = phy_startup(priv->phy_dev);
 211        if (ret) {
 212                pr_err("%s: could not initialize phy\n", __func__);
 213                return ret;
 214        }
 215
 216        if (!priv->phy_dev->link) {
 217                pr_err("%s: no phy link\n", __func__);
 218                return -EIO;
 219        }
 220
 221        bcm6348_eth_adjust_link(dev, priv->phy_dev);
 222
 223        /* zero mib counters */
 224        for (i = 0; i < MIB_REG_CNT; i++)
 225                writel_be(0, MIB_REG(i));
 226
 227        /* enable rx flow control */
 228        setbits_be32(priv->base + ETH_RXCFG_REG, ETH_RXCFG_ENFLOW_MASK);
 229
 230        /* set max rx/tx length */
 231        writel_be((ETH_MAX_MTU_SIZE << ETH_RXMAXLEN_SHIFT) &
 232                  ETH_RXMAXLEN_MASK, priv->base + ETH_RXMAXLEN_REG);
 233        writel_be((ETH_MAX_MTU_SIZE << ETH_TXMAXLEN_SHIFT) &
 234                  ETH_TXMAXLEN_MASK, priv->base + ETH_TXMAXLEN_REG);
 235
 236        /* set correct transmit fifo watermark */
 237        writel_be((ETH_TX_WATERMARK << ETH_TXWMARK_WM_SHIFT) &
 238                  ETH_TXWMARK_WM_MASK, priv->base + ETH_TXWMARK_REG);
 239
 240        /* enable emac */
 241        bcm6348_eth_mac_enable(priv);
 242
 243        /* clear interrupts */
 244        writel_be(0, priv->base + ETH_IRMASK_REG);
 245
 246        return 0;
 247}
 248
 249static void bcm6348_eth_stop(struct udevice *dev)
 250{
 251        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 252
 253        /* disable dma rx channel */
 254        dma_disable(&priv->rx_dma);
 255
 256        /* disable dma tx channel */
 257        dma_disable(&priv->tx_dma);
 258
 259        /* disable emac */
 260        bcm6348_eth_mac_disable(priv);
 261}
 262
 263static int bcm6348_eth_write_hwaddr(struct udevice *dev)
 264{
 265        struct eth_pdata *pdata = dev_get_platdata(dev);
 266        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 267        bool running = false;
 268
 269        /* check if emac is running */
 270        if (readl_be(priv->base + ETH_CTL_REG) & ETH_CTL_ENABLE_MASK)
 271                running = true;
 272
 273        /* disable emac */
 274        if (running)
 275                bcm6348_eth_mac_disable(priv);
 276
 277        /* set mac address */
 278        writel_be((pdata->enetaddr[2] << 24) | (pdata->enetaddr[3]) << 16 |
 279                  (pdata->enetaddr[4]) << 8 | (pdata->enetaddr[5]),
 280                  priv->base + ETH_PML_REG(0));
 281        writel_be((pdata->enetaddr[1]) | (pdata->enetaddr[0] << 8) |
 282                  ETH_PMH_VALID_MASK, priv->base + ETH_PMH_REG(0));
 283
 284        /* enable emac */
 285        if (running)
 286                bcm6348_eth_mac_enable(priv);
 287
 288        return 0;
 289}
 290
 291static const struct eth_ops bcm6348_eth_ops = {
 292        .free_pkt = bcm6348_eth_free_pkt,
 293        .recv = bcm6348_eth_recv,
 294        .send = bcm6348_eth_send,
 295        .start = bcm6348_eth_start,
 296        .stop = bcm6348_eth_stop,
 297        .write_hwaddr = bcm6348_eth_write_hwaddr,
 298};
 299
 300static const struct udevice_id bcm6348_eth_ids[] = {
 301        { .compatible = "brcm,bcm6348-enet", },
 302        { /* sentinel */ }
 303};
 304
 305static int bcm6348_mdio_op(void __iomem *base, uint32_t data)
 306{
 307        /* make sure mii interrupt status is cleared */
 308        writel_be(ETH_IR_MII_MASK, base + ETH_IR_REG);
 309
 310        /* issue mii op */
 311        writel_be(data, base + MII_DAT_REG);
 312
 313        /* wait until emac is disabled */
 314        return wait_for_bit_be32(base + ETH_IR_REG,
 315                                 ETH_IR_MII_MASK, true,
 316                                 ETH_TIMEOUT, false);
 317}
 318
 319static int bcm6348_mdio_read(struct mii_dev *bus, int addr, int devaddr,
 320                             int reg)
 321{
 322        void __iomem *base = bus->priv;
 323        uint32_t val;
 324
 325        val = MII_DAT_OP_READ;
 326        val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK;
 327        val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK;
 328        val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK;
 329
 330        if (bcm6348_mdio_op(base, val)) {
 331                pr_err("%s: timeout\n", __func__);
 332                return -EINVAL;
 333        }
 334
 335        val = readl_be(base + MII_DAT_REG) & MII_DAT_DATA_MASK;
 336        val >>= MII_DAT_DATA_SHIFT;
 337
 338        return val;
 339}
 340
 341static int bcm6348_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
 342                              int reg, u16 value)
 343{
 344        void __iomem *base = bus->priv;
 345        uint32_t val;
 346
 347        val = MII_DAT_OP_WRITE;
 348        val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK;
 349        val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK;
 350        val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK;
 351        val |= (value << MII_DAT_DATA_SHIFT) & MII_DAT_DATA_MASK;
 352
 353        if (bcm6348_mdio_op(base, val)) {
 354                pr_err("%s: timeout\n", __func__);
 355                return -EINVAL;
 356        }
 357
 358        return 0;
 359}
 360
 361static int bcm6348_mdio_init(const char *name, void __iomem *base)
 362{
 363        struct mii_dev *bus;
 364
 365        bus = mdio_alloc();
 366        if (!bus) {
 367                pr_err("%s: failed to allocate MDIO bus\n", __func__);
 368                return -ENOMEM;
 369        }
 370
 371        bus->read = bcm6348_mdio_read;
 372        bus->write = bcm6348_mdio_write;
 373        bus->priv = base;
 374        snprintf(bus->name, sizeof(bus->name), "%s", name);
 375
 376        return mdio_register(bus);
 377}
 378
 379static int bcm6348_phy_init(struct udevice *dev)
 380{
 381        struct eth_pdata *pdata = dev_get_platdata(dev);
 382        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 383        struct mii_dev *bus;
 384
 385        /* get mii bus */
 386        bus = miiphy_get_dev_by_name(dev->name);
 387
 388        /* phy connect */
 389        priv->phy_dev = phy_connect(bus, priv->phy_id, dev,
 390                                    pdata->phy_interface);
 391        if (!priv->phy_dev) {
 392                pr_err("%s: no phy device\n", __func__);
 393                return -ENODEV;
 394        }
 395
 396        priv->phy_dev->supported = (SUPPORTED_10baseT_Half |
 397                                    SUPPORTED_10baseT_Full |
 398                                    SUPPORTED_100baseT_Half |
 399                                    SUPPORTED_100baseT_Full |
 400                                    SUPPORTED_Autoneg |
 401                                    SUPPORTED_Pause |
 402                                    SUPPORTED_MII);
 403        priv->phy_dev->advertising = priv->phy_dev->supported;
 404
 405        /* phy config */
 406        phy_config(priv->phy_dev);
 407
 408        return 0;
 409}
 410
 411static int bcm6348_eth_probe(struct udevice *dev)
 412{
 413        struct eth_pdata *pdata = dev_get_platdata(dev);
 414        struct bcm6348_eth_priv *priv = dev_get_priv(dev);
 415        struct ofnode_phandle_args phy;
 416        const char *phy_mode;
 417        int ret, i;
 418
 419        /* get base address */
 420        priv->base = dev_remap_addr(dev);
 421        if (!priv->base)
 422                return -EINVAL;
 423        pdata->iobase = (phys_addr_t) priv->base;
 424
 425        /* get phy mode */
 426        pdata->phy_interface = PHY_INTERFACE_MODE_NONE;
 427        phy_mode = dev_read_string(dev, "phy-mode");
 428        if (phy_mode)
 429                pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 430        if (pdata->phy_interface == PHY_INTERFACE_MODE_NONE)
 431                return -ENODEV;
 432
 433        /* get phy */
 434        if (dev_read_phandle_with_args(dev, "phy", NULL, 0, 0, &phy))
 435                return -ENOENT;
 436        priv->phy_id = ofnode_read_u32_default(phy.node, "reg", -1);
 437
 438        /* get dma channels */
 439        ret = dma_get_by_name(dev, "tx", &priv->tx_dma);
 440        if (ret)
 441                return -EINVAL;
 442
 443        ret = dma_get_by_name(dev, "rx", &priv->rx_dma);
 444        if (ret)
 445                return -EINVAL;
 446
 447        /* try to enable clocks */
 448        for (i = 0; ; i++) {
 449                struct clk clk;
 450                int ret;
 451
 452                ret = clk_get_by_index(dev, i, &clk);
 453                if (ret < 0)
 454                        break;
 455
 456                ret = clk_enable(&clk);
 457                if (ret < 0) {
 458                        pr_err("%s: error enabling clock %d\n", __func__, i);
 459                        return ret;
 460                }
 461
 462                ret = clk_free(&clk);
 463                if (ret < 0) {
 464                        pr_err("%s: error freeing clock %d\n", __func__, i);
 465                        return ret;
 466                }
 467        }
 468
 469        /* try to perform resets */
 470        for (i = 0; ; i++) {
 471                struct reset_ctl reset;
 472                int ret;
 473
 474                ret = reset_get_by_index(dev, i, &reset);
 475                if (ret < 0)
 476                        break;
 477
 478                ret = reset_deassert(&reset);
 479                if (ret < 0) {
 480                        pr_err("%s: error deasserting reset %d\n", __func__, i);
 481                        return ret;
 482                }
 483
 484                ret = reset_free(&reset);
 485                if (ret < 0) {
 486                        pr_err("%s: error freeing reset %d\n", __func__, i);
 487                        return ret;
 488                }
 489        }
 490
 491        /* disable emac */
 492        bcm6348_eth_mac_disable(priv);
 493
 494        /* reset emac */
 495        bcm6348_eth_mac_reset(priv);
 496
 497        /* select correct mii interface */
 498        if (pdata->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
 499                clrbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK);
 500        else
 501                setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK);
 502
 503        /* turn on mdc clock */
 504        writel_be((0x1f << MII_SC_MDCFREQDIV_SHIFT) |
 505                  MII_SC_PREAMBLE_EN_MASK, priv->base + MII_SC_REG);
 506
 507        /* set mib counters to not clear when read */
 508        clrbits_be32(priv->base + MIB_CTL_REG, MIB_CTL_RDCLEAR_MASK);
 509
 510        /* initialize perfect match registers */
 511        for (i = 0; i < ETH_PM_CNT; i++) {
 512                writel_be(0, priv->base + ETH_PML_REG(i));
 513                writel_be(0, priv->base + ETH_PMH_REG(i));
 514        }
 515
 516        /* init mii bus */
 517        ret = bcm6348_mdio_init(dev->name, priv->base);
 518        if (ret)
 519                return ret;
 520
 521        /* init phy */
 522        ret = bcm6348_phy_init(dev);
 523        if (ret)
 524                return ret;
 525
 526        return 0;
 527}
 528
 529U_BOOT_DRIVER(bcm6348_eth) = {
 530        .name = "bcm6348_eth",
 531        .id = UCLASS_ETH,
 532        .of_match = bcm6348_eth_ids,
 533        .ops = &bcm6348_eth_ops,
 534        .platdata_auto_alloc_size = sizeof(struct eth_pdata),
 535        .priv_auto_alloc_size = sizeof(struct bcm6348_eth_priv),
 536        .probe = bcm6348_eth_probe,
 537};
 538