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