uboot/drivers/net/designware.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2010
   4 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
   5 */
   6
   7/*
   8 * Designware ethernet IP driver for U-Boot
   9 */
  10
  11#include <common.h>
  12#include <clk.h>
  13#include <cpu_func.h>
  14#include <dm.h>
  15#include <errno.h>
  16#include <log.h>
  17#include <miiphy.h>
  18#include <malloc.h>
  19#include <net.h>
  20#include <pci.h>
  21#include <reset.h>
  22#include <asm/cache.h>
  23#include <dm/device_compat.h>
  24#include <dm/devres.h>
  25#include <linux/compiler.h>
  26#include <linux/delay.h>
  27#include <linux/err.h>
  28#include <linux/kernel.h>
  29#include <asm/io.h>
  30#include <power/regulator.h>
  31#include "designware.h"
  32
  33static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
  34{
  35#ifdef CONFIG_DM_ETH
  36        struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
  37        struct eth_mac_regs *mac_p = priv->mac_regs_p;
  38#else
  39        struct eth_mac_regs *mac_p = bus->priv;
  40#endif
  41        ulong start;
  42        u16 miiaddr;
  43        int timeout = CONFIG_MDIO_TIMEOUT;
  44
  45        miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
  46                  ((reg << MIIREGSHIFT) & MII_REGMSK);
  47
  48        writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
  49
  50        start = get_timer(0);
  51        while (get_timer(start) < timeout) {
  52                if (!(readl(&mac_p->miiaddr) & MII_BUSY))
  53                        return readl(&mac_p->miidata);
  54                udelay(10);
  55        };
  56
  57        return -ETIMEDOUT;
  58}
  59
  60static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
  61                        u16 val)
  62{
  63#ifdef CONFIG_DM_ETH
  64        struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
  65        struct eth_mac_regs *mac_p = priv->mac_regs_p;
  66#else
  67        struct eth_mac_regs *mac_p = bus->priv;
  68#endif
  69        ulong start;
  70        u16 miiaddr;
  71        int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT;
  72
  73        writel(val, &mac_p->miidata);
  74        miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
  75                  ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
  76
  77        writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
  78
  79        start = get_timer(0);
  80        while (get_timer(start) < timeout) {
  81                if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
  82                        ret = 0;
  83                        break;
  84                }
  85                udelay(10);
  86        };
  87
  88        return ret;
  89}
  90
  91#if defined(CONFIG_DM_ETH) && CONFIG_IS_ENABLED(DM_GPIO)
  92static int dw_mdio_reset(struct mii_dev *bus)
  93{
  94        struct udevice *dev = bus->priv;
  95        struct dw_eth_dev *priv = dev_get_priv(dev);
  96        struct dw_eth_pdata *pdata = dev_get_platdata(dev);
  97        int ret;
  98
  99        if (!dm_gpio_is_valid(&priv->reset_gpio))
 100                return 0;
 101
 102        /* reset the phy */
 103        ret = dm_gpio_set_value(&priv->reset_gpio, 0);
 104        if (ret)
 105                return ret;
 106
 107        udelay(pdata->reset_delays[0]);
 108
 109        ret = dm_gpio_set_value(&priv->reset_gpio, 1);
 110        if (ret)
 111                return ret;
 112
 113        udelay(pdata->reset_delays[1]);
 114
 115        ret = dm_gpio_set_value(&priv->reset_gpio, 0);
 116        if (ret)
 117                return ret;
 118
 119        udelay(pdata->reset_delays[2]);
 120
 121        return 0;
 122}
 123#endif
 124
 125static int dw_mdio_init(const char *name, void *priv)
 126{
 127        struct mii_dev *bus = mdio_alloc();
 128
 129        if (!bus) {
 130                printf("Failed to allocate MDIO bus\n");
 131                return -ENOMEM;
 132        }
 133
 134        bus->read = dw_mdio_read;
 135        bus->write = dw_mdio_write;
 136        snprintf(bus->name, sizeof(bus->name), "%s", name);
 137#if defined(CONFIG_DM_ETH) && CONFIG_IS_ENABLED(DM_GPIO)
 138        bus->reset = dw_mdio_reset;
 139#endif
 140
 141        bus->priv = priv;
 142
 143        return mdio_register(bus);
 144}
 145
 146static void tx_descs_init(struct dw_eth_dev *priv)
 147{
 148        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 149        struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
 150        char *txbuffs = &priv->txbuffs[0];
 151        struct dmamacdescr *desc_p;
 152        u32 idx;
 153
 154        for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
 155                desc_p = &desc_table_p[idx];
 156                desc_p->dmamac_addr = (ulong)&txbuffs[idx * CONFIG_ETH_BUFSIZE];
 157                desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1];
 158
 159#if defined(CONFIG_DW_ALTDESCRIPTOR)
 160                desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
 161                                DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS |
 162                                DESC_TXSTS_TXCHECKINSCTRL |
 163                                DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
 164
 165                desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
 166                desc_p->dmamac_cntl = 0;
 167                desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
 168#else
 169                desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
 170                desc_p->txrx_status = 0;
 171#endif
 172        }
 173
 174        /* Correcting the last pointer of the chain */
 175        desc_p->dmamac_next = (ulong)&desc_table_p[0];
 176
 177        /* Flush all Tx buffer descriptors at once */
 178        flush_dcache_range((ulong)priv->tx_mac_descrtable,
 179                           (ulong)priv->tx_mac_descrtable +
 180                           sizeof(priv->tx_mac_descrtable));
 181
 182        writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
 183        priv->tx_currdescnum = 0;
 184}
 185
 186static void rx_descs_init(struct dw_eth_dev *priv)
 187{
 188        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 189        struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
 190        char *rxbuffs = &priv->rxbuffs[0];
 191        struct dmamacdescr *desc_p;
 192        u32 idx;
 193
 194        /* Before passing buffers to GMAC we need to make sure zeros
 195         * written there right after "priv" structure allocation were
 196         * flushed into RAM.
 197         * Otherwise there's a chance to get some of them flushed in RAM when
 198         * GMAC is already pushing data to RAM via DMA. This way incoming from
 199         * GMAC data will be corrupted. */
 200        flush_dcache_range((ulong)rxbuffs, (ulong)rxbuffs + RX_TOTAL_BUFSIZE);
 201
 202        for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
 203                desc_p = &desc_table_p[idx];
 204                desc_p->dmamac_addr = (ulong)&rxbuffs[idx * CONFIG_ETH_BUFSIZE];
 205                desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1];
 206
 207                desc_p->dmamac_cntl =
 208                        (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) |
 209                                      DESC_RXCTRL_RXCHAIN;
 210
 211                desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
 212        }
 213
 214        /* Correcting the last pointer of the chain */
 215        desc_p->dmamac_next = (ulong)&desc_table_p[0];
 216
 217        /* Flush all Rx buffer descriptors at once */
 218        flush_dcache_range((ulong)priv->rx_mac_descrtable,
 219                           (ulong)priv->rx_mac_descrtable +
 220                           sizeof(priv->rx_mac_descrtable));
 221
 222        writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
 223        priv->rx_currdescnum = 0;
 224}
 225
 226static int _dw_write_hwaddr(struct dw_eth_dev *priv, u8 *mac_id)
 227{
 228        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 229        u32 macid_lo, macid_hi;
 230
 231        macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) +
 232                   (mac_id[3] << 24);
 233        macid_hi = mac_id[4] + (mac_id[5] << 8);
 234
 235        writel(macid_hi, &mac_p->macaddr0hi);
 236        writel(macid_lo, &mac_p->macaddr0lo);
 237
 238        return 0;
 239}
 240
 241static int dw_adjust_link(struct dw_eth_dev *priv, struct eth_mac_regs *mac_p,
 242                          struct phy_device *phydev)
 243{
 244        u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN;
 245
 246        if (!phydev->link) {
 247                printf("%s: No link.\n", phydev->dev->name);
 248                return 0;
 249        }
 250
 251        if (phydev->speed != 1000)
 252                conf |= MII_PORTSELECT;
 253        else
 254                conf &= ~MII_PORTSELECT;
 255
 256        if (phydev->speed == 100)
 257                conf |= FES_100;
 258
 259        if (phydev->duplex)
 260                conf |= FULLDPLXMODE;
 261
 262        writel(conf, &mac_p->conf);
 263
 264        printf("Speed: %d, %s duplex%s\n", phydev->speed,
 265               (phydev->duplex) ? "full" : "half",
 266               (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
 267
 268        return 0;
 269}
 270
 271static void _dw_eth_halt(struct dw_eth_dev *priv)
 272{
 273        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 274        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 275
 276        writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf);
 277        writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode);
 278
 279        phy_shutdown(priv->phydev);
 280}
 281
 282int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
 283{
 284        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 285        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 286        unsigned int start;
 287        int ret;
 288
 289        writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
 290
 291        /*
 292         * When a MII PHY is used, we must set the PS bit for the DMA
 293         * reset to succeed.
 294         */
 295        if (priv->phydev->interface == PHY_INTERFACE_MODE_MII)
 296                writel(readl(&mac_p->conf) | MII_PORTSELECT, &mac_p->conf);
 297        else
 298                writel(readl(&mac_p->conf) & ~MII_PORTSELECT, &mac_p->conf);
 299
 300        start = get_timer(0);
 301        while (readl(&dma_p->busmode) & DMAMAC_SRST) {
 302                if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) {
 303                        printf("DMA reset timeout\n");
 304                        return -ETIMEDOUT;
 305                }
 306
 307                mdelay(100);
 308        };
 309
 310        /*
 311         * Soft reset above clears HW address registers.
 312         * So we have to set it here once again.
 313         */
 314        _dw_write_hwaddr(priv, enetaddr);
 315
 316        rx_descs_init(priv);
 317        tx_descs_init(priv);
 318
 319        writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode);
 320
 321#ifndef CONFIG_DW_MAC_FORCE_THRESHOLD_MODE
 322        writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD,
 323               &dma_p->opmode);
 324#else
 325        writel(readl(&dma_p->opmode) | FLUSHTXFIFO,
 326               &dma_p->opmode);
 327#endif
 328
 329        writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode);
 330
 331#ifdef CONFIG_DW_AXI_BURST_LEN
 332        writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus);
 333#endif
 334
 335        /* Start up the PHY */
 336        ret = phy_startup(priv->phydev);
 337        if (ret) {
 338                printf("Could not initialize PHY %s\n",
 339                       priv->phydev->dev->name);
 340                return ret;
 341        }
 342
 343        ret = dw_adjust_link(priv, mac_p, priv->phydev);
 344        if (ret)
 345                return ret;
 346
 347        return 0;
 348}
 349
 350int designware_eth_enable(struct dw_eth_dev *priv)
 351{
 352        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 353
 354        if (!priv->phydev->link)
 355                return -EIO;
 356
 357        writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
 358
 359        return 0;
 360}
 361
 362#define ETH_ZLEN        60
 363
 364static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length)
 365{
 366        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 367        u32 desc_num = priv->tx_currdescnum;
 368        struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
 369        ulong desc_start = (ulong)desc_p;
 370        ulong desc_end = desc_start +
 371                roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
 372        ulong data_start = desc_p->dmamac_addr;
 373        ulong data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
 374        /*
 375         * Strictly we only need to invalidate the "txrx_status" field
 376         * for the following check, but on some platforms we cannot
 377         * invalidate only 4 bytes, so we flush the entire descriptor,
 378         * which is 16 bytes in total. This is safe because the
 379         * individual descriptors in the array are each aligned to
 380         * ARCH_DMA_MINALIGN and padded appropriately.
 381         */
 382        invalidate_dcache_range(desc_start, desc_end);
 383
 384        /* Check if the descriptor is owned by CPU */
 385        if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
 386                printf("CPU not owner of tx frame\n");
 387                return -EPERM;
 388        }
 389
 390        memcpy((void *)data_start, packet, length);
 391        if (length < ETH_ZLEN) {
 392                memset(&((char *)data_start)[length], 0, ETH_ZLEN - length);
 393                length = ETH_ZLEN;
 394        }
 395
 396        /* Flush data to be sent */
 397        flush_dcache_range(data_start, data_end);
 398
 399#if defined(CONFIG_DW_ALTDESCRIPTOR)
 400        desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
 401        desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) |
 402                              ((length << DESC_TXCTRL_SIZE1SHFT) &
 403                              DESC_TXCTRL_SIZE1MASK);
 404
 405        desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
 406        desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
 407#else
 408        desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) |
 409                              ((length << DESC_TXCTRL_SIZE1SHFT) &
 410                              DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST |
 411                              DESC_TXCTRL_TXFIRST;
 412
 413        desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
 414#endif
 415
 416        /* Flush modified buffer descriptor */
 417        flush_dcache_range(desc_start, desc_end);
 418
 419        /* Test the wrap-around condition. */
 420        if (++desc_num >= CONFIG_TX_DESCR_NUM)
 421                desc_num = 0;
 422
 423        priv->tx_currdescnum = desc_num;
 424
 425        /* Start the transmission */
 426        writel(POLL_DATA, &dma_p->txpolldemand);
 427
 428        return 0;
 429}
 430
 431static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp)
 432{
 433        u32 status, desc_num = priv->rx_currdescnum;
 434        struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
 435        int length = -EAGAIN;
 436        ulong desc_start = (ulong)desc_p;
 437        ulong desc_end = desc_start +
 438                roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
 439        ulong data_start = desc_p->dmamac_addr;
 440        ulong data_end;
 441
 442        /* Invalidate entire buffer descriptor */
 443        invalidate_dcache_range(desc_start, desc_end);
 444
 445        status = desc_p->txrx_status;
 446
 447        /* Check  if the owner is the CPU */
 448        if (!(status & DESC_RXSTS_OWNBYDMA)) {
 449
 450                length = (status & DESC_RXSTS_FRMLENMSK) >>
 451                         DESC_RXSTS_FRMLENSHFT;
 452
 453                /* Invalidate received data */
 454                data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
 455                invalidate_dcache_range(data_start, data_end);
 456                *packetp = (uchar *)(ulong)desc_p->dmamac_addr;
 457        }
 458
 459        return length;
 460}
 461
 462static int _dw_free_pkt(struct dw_eth_dev *priv)
 463{
 464        u32 desc_num = priv->rx_currdescnum;
 465        struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
 466        ulong desc_start = (ulong)desc_p;
 467        ulong desc_end = desc_start +
 468                roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
 469
 470        /*
 471         * Make the current descriptor valid again and go to
 472         * the next one
 473         */
 474        desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
 475
 476        /* Flush only status field - others weren't changed */
 477        flush_dcache_range(desc_start, desc_end);
 478
 479        /* Test the wrap-around condition. */
 480        if (++desc_num >= CONFIG_RX_DESCR_NUM)
 481                desc_num = 0;
 482        priv->rx_currdescnum = desc_num;
 483
 484        return 0;
 485}
 486
 487static int dw_phy_init(struct dw_eth_dev *priv, void *dev)
 488{
 489        struct phy_device *phydev;
 490        int phy_addr = -1, ret;
 491
 492#ifdef CONFIG_PHY_ADDR
 493        phy_addr = CONFIG_PHY_ADDR;
 494#endif
 495
 496        phydev = phy_connect(priv->bus, phy_addr, dev, priv->interface);
 497        if (!phydev)
 498                return -ENODEV;
 499
 500        phydev->supported &= PHY_GBIT_FEATURES;
 501        if (priv->max_speed) {
 502                ret = phy_set_supported(phydev, priv->max_speed);
 503                if (ret)
 504                        return ret;
 505        }
 506        phydev->advertising = phydev->supported;
 507
 508        priv->phydev = phydev;
 509        phy_config(phydev);
 510
 511        return 0;
 512}
 513
 514#ifndef CONFIG_DM_ETH
 515static int dw_eth_init(struct eth_device *dev, struct bd_info *bis)
 516{
 517        int ret;
 518
 519        ret = designware_eth_init(dev->priv, dev->enetaddr);
 520        if (!ret)
 521                ret = designware_eth_enable(dev->priv);
 522
 523        return ret;
 524}
 525
 526static int dw_eth_send(struct eth_device *dev, void *packet, int length)
 527{
 528        return _dw_eth_send(dev->priv, packet, length);
 529}
 530
 531static int dw_eth_recv(struct eth_device *dev)
 532{
 533        uchar *packet;
 534        int length;
 535
 536        length = _dw_eth_recv(dev->priv, &packet);
 537        if (length == -EAGAIN)
 538                return 0;
 539        net_process_received_packet(packet, length);
 540
 541        _dw_free_pkt(dev->priv);
 542
 543        return 0;
 544}
 545
 546static void dw_eth_halt(struct eth_device *dev)
 547{
 548        return _dw_eth_halt(dev->priv);
 549}
 550
 551static int dw_write_hwaddr(struct eth_device *dev)
 552{
 553        return _dw_write_hwaddr(dev->priv, dev->enetaddr);
 554}
 555
 556int designware_initialize(ulong base_addr, u32 interface)
 557{
 558        struct eth_device *dev;
 559        struct dw_eth_dev *priv;
 560
 561        dev = (struct eth_device *) malloc(sizeof(struct eth_device));
 562        if (!dev)
 563                return -ENOMEM;
 564
 565        /*
 566         * Since the priv structure contains the descriptors which need a strict
 567         * buswidth alignment, memalign is used to allocate memory
 568         */
 569        priv = (struct dw_eth_dev *) memalign(ARCH_DMA_MINALIGN,
 570                                              sizeof(struct dw_eth_dev));
 571        if (!priv) {
 572                free(dev);
 573                return -ENOMEM;
 574        }
 575
 576        if ((phys_addr_t)priv + sizeof(*priv) > (1ULL << 32)) {
 577                printf("designware: buffers are outside DMA memory\n");
 578                return -EINVAL;
 579        }
 580
 581        memset(dev, 0, sizeof(struct eth_device));
 582        memset(priv, 0, sizeof(struct dw_eth_dev));
 583
 584        sprintf(dev->name, "dwmac.%lx", base_addr);
 585        dev->iobase = (int)base_addr;
 586        dev->priv = priv;
 587
 588        priv->dev = dev;
 589        priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
 590        priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
 591                        DW_DMA_BASE_OFFSET);
 592
 593        dev->init = dw_eth_init;
 594        dev->send = dw_eth_send;
 595        dev->recv = dw_eth_recv;
 596        dev->halt = dw_eth_halt;
 597        dev->write_hwaddr = dw_write_hwaddr;
 598
 599        eth_register(dev);
 600
 601        priv->interface = interface;
 602
 603        dw_mdio_init(dev->name, priv->mac_regs_p);
 604        priv->bus = miiphy_get_dev_by_name(dev->name);
 605
 606        return dw_phy_init(priv, dev);
 607}
 608#endif
 609
 610#ifdef CONFIG_DM_ETH
 611static int designware_eth_start(struct udevice *dev)
 612{
 613        struct eth_pdata *pdata = dev_get_platdata(dev);
 614        struct dw_eth_dev *priv = dev_get_priv(dev);
 615        int ret;
 616
 617        ret = designware_eth_init(priv, pdata->enetaddr);
 618        if (ret)
 619                return ret;
 620        ret = designware_eth_enable(priv);
 621        if (ret)
 622                return ret;
 623
 624        return 0;
 625}
 626
 627int designware_eth_send(struct udevice *dev, void *packet, int length)
 628{
 629        struct dw_eth_dev *priv = dev_get_priv(dev);
 630
 631        return _dw_eth_send(priv, packet, length);
 632}
 633
 634int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 635{
 636        struct dw_eth_dev *priv = dev_get_priv(dev);
 637
 638        return _dw_eth_recv(priv, packetp);
 639}
 640
 641int designware_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
 642{
 643        struct dw_eth_dev *priv = dev_get_priv(dev);
 644
 645        return _dw_free_pkt(priv);
 646}
 647
 648void designware_eth_stop(struct udevice *dev)
 649{
 650        struct dw_eth_dev *priv = dev_get_priv(dev);
 651
 652        return _dw_eth_halt(priv);
 653}
 654
 655int designware_eth_write_hwaddr(struct udevice *dev)
 656{
 657        struct eth_pdata *pdata = dev_get_platdata(dev);
 658        struct dw_eth_dev *priv = dev_get_priv(dev);
 659
 660        return _dw_write_hwaddr(priv, pdata->enetaddr);
 661}
 662
 663static int designware_eth_bind(struct udevice *dev)
 664{
 665#ifdef CONFIG_DM_PCI
 666        static int num_cards;
 667        char name[20];
 668
 669        /* Create a unique device name for PCI type devices */
 670        if (device_is_on_pci_bus(dev)) {
 671                sprintf(name, "eth_designware#%u", num_cards++);
 672                device_set_name(dev, name);
 673        }
 674#endif
 675
 676        return 0;
 677}
 678
 679int designware_eth_probe(struct udevice *dev)
 680{
 681        struct eth_pdata *pdata = dev_get_platdata(dev);
 682        struct dw_eth_dev *priv = dev_get_priv(dev);
 683        u32 iobase = pdata->iobase;
 684        ulong ioaddr;
 685        int ret, err;
 686        struct reset_ctl_bulk reset_bulk;
 687#ifdef CONFIG_CLK
 688        int i, clock_nb;
 689
 690        priv->clock_count = 0;
 691        clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells",
 692                                               0);
 693        if (clock_nb > 0) {
 694                priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
 695                                            GFP_KERNEL);
 696                if (!priv->clocks)
 697                        return -ENOMEM;
 698
 699                for (i = 0; i < clock_nb; i++) {
 700                        err = clk_get_by_index(dev, i, &priv->clocks[i]);
 701                        if (err < 0)
 702                                break;
 703
 704                        err = clk_enable(&priv->clocks[i]);
 705                        if (err && err != -ENOSYS && err != -ENOTSUPP) {
 706                                pr_err("failed to enable clock %d\n", i);
 707                                clk_free(&priv->clocks[i]);
 708                                goto clk_err;
 709                        }
 710                        priv->clock_count++;
 711                }
 712        } else if (clock_nb != -ENOENT) {
 713                pr_err("failed to get clock phandle(%d)\n", clock_nb);
 714                return clock_nb;
 715        }
 716#endif
 717
 718#if defined(CONFIG_DM_REGULATOR)
 719        struct udevice *phy_supply;
 720
 721        ret = device_get_supply_regulator(dev, "phy-supply",
 722                                          &phy_supply);
 723        if (ret) {
 724                debug("%s: No phy supply\n", dev->name);
 725        } else {
 726                ret = regulator_set_enable(phy_supply, true);
 727                if (ret) {
 728                        puts("Error enabling phy supply\n");
 729                        return ret;
 730                }
 731        }
 732#endif
 733
 734        ret = reset_get_bulk(dev, &reset_bulk);
 735        if (ret)
 736                dev_warn(dev, "Can't get reset: %d\n", ret);
 737        else
 738                reset_deassert_bulk(&reset_bulk);
 739
 740#ifdef CONFIG_DM_PCI
 741        /*
 742         * If we are on PCI bus, either directly attached to a PCI root port,
 743         * or via a PCI bridge, fill in platdata before we probe the hardware.
 744         */
 745        if (device_is_on_pci_bus(dev)) {
 746                dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase);
 747                iobase &= PCI_BASE_ADDRESS_MEM_MASK;
 748                iobase = dm_pci_mem_to_phys(dev, iobase);
 749
 750                pdata->iobase = iobase;
 751                pdata->phy_interface = PHY_INTERFACE_MODE_RMII;
 752        }
 753#endif
 754
 755        debug("%s, iobase=%x, priv=%p\n", __func__, iobase, priv);
 756        ioaddr = iobase;
 757        priv->mac_regs_p = (struct eth_mac_regs *)ioaddr;
 758        priv->dma_regs_p = (struct eth_dma_regs *)(ioaddr + DW_DMA_BASE_OFFSET);
 759        priv->interface = pdata->phy_interface;
 760        priv->max_speed = pdata->max_speed;
 761
 762        ret = dw_mdio_init(dev->name, dev);
 763        if (ret) {
 764                err = ret;
 765                goto mdio_err;
 766        }
 767        priv->bus = miiphy_get_dev_by_name(dev->name);
 768
 769        ret = dw_phy_init(priv, dev);
 770        debug("%s, ret=%d\n", __func__, ret);
 771        if (!ret)
 772                return 0;
 773
 774        /* continue here for cleanup if no PHY found */
 775        err = ret;
 776        mdio_unregister(priv->bus);
 777        mdio_free(priv->bus);
 778mdio_err:
 779
 780#ifdef CONFIG_CLK
 781clk_err:
 782        ret = clk_release_all(priv->clocks, priv->clock_count);
 783        if (ret)
 784                pr_err("failed to disable all clocks\n");
 785
 786#endif
 787        return err;
 788}
 789
 790static int designware_eth_remove(struct udevice *dev)
 791{
 792        struct dw_eth_dev *priv = dev_get_priv(dev);
 793
 794        free(priv->phydev);
 795        mdio_unregister(priv->bus);
 796        mdio_free(priv->bus);
 797
 798#ifdef CONFIG_CLK
 799        return clk_release_all(priv->clocks, priv->clock_count);
 800#else
 801        return 0;
 802#endif
 803}
 804
 805const struct eth_ops designware_eth_ops = {
 806        .start                  = designware_eth_start,
 807        .send                   = designware_eth_send,
 808        .recv                   = designware_eth_recv,
 809        .free_pkt               = designware_eth_free_pkt,
 810        .stop                   = designware_eth_stop,
 811        .write_hwaddr           = designware_eth_write_hwaddr,
 812};
 813
 814int designware_eth_ofdata_to_platdata(struct udevice *dev)
 815{
 816        struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
 817#if CONFIG_IS_ENABLED(DM_GPIO)
 818        struct dw_eth_dev *priv = dev_get_priv(dev);
 819#endif
 820        struct eth_pdata *pdata = &dw_pdata->eth_pdata;
 821        const char *phy_mode;
 822#if CONFIG_IS_ENABLED(DM_GPIO)
 823        int reset_flags = GPIOD_IS_OUT;
 824#endif
 825        int ret = 0;
 826
 827        pdata->iobase = dev_read_addr(dev);
 828        pdata->phy_interface = -1;
 829        phy_mode = dev_read_string(dev, "phy-mode");
 830        if (phy_mode)
 831                pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 832        if (pdata->phy_interface == -1) {
 833                debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
 834                return -EINVAL;
 835        }
 836
 837        pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
 838
 839#if CONFIG_IS_ENABLED(DM_GPIO)
 840        if (dev_read_bool(dev, "snps,reset-active-low"))
 841                reset_flags |= GPIOD_ACTIVE_LOW;
 842
 843        ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
 844                &priv->reset_gpio, reset_flags);
 845        if (ret == 0) {
 846                ret = dev_read_u32_array(dev, "snps,reset-delays-us",
 847                                         dw_pdata->reset_delays, 3);
 848        } else if (ret == -ENOENT) {
 849                ret = 0;
 850        }
 851#endif
 852
 853        return ret;
 854}
 855
 856static const struct udevice_id designware_eth_ids[] = {
 857        { .compatible = "allwinner,sun7i-a20-gmac" },
 858        { .compatible = "amlogic,meson6-dwmac" },
 859        { .compatible = "amlogic,meson-gx-dwmac" },
 860        { .compatible = "amlogic,meson-gxbb-dwmac" },
 861        { .compatible = "amlogic,meson-axg-dwmac" },
 862        { .compatible = "st,stm32-dwmac" },
 863        { .compatible = "snps,arc-dwmac-3.70a" },
 864        { }
 865};
 866
 867U_BOOT_DRIVER(eth_designware) = {
 868        .name   = "eth_designware",
 869        .id     = UCLASS_ETH,
 870        .of_match = designware_eth_ids,
 871        .ofdata_to_platdata = designware_eth_ofdata_to_platdata,
 872        .bind   = designware_eth_bind,
 873        .probe  = designware_eth_probe,
 874        .remove = designware_eth_remove,
 875        .ops    = &designware_eth_ops,
 876        .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
 877        .platdata_auto_alloc_size = sizeof(struct dw_eth_pdata),
 878        .flags = DM_FLAG_ALLOC_PRIV_DMA,
 879};
 880
 881static struct pci_device_id supported[] = {
 882        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_EMAC) },
 883        { }
 884};
 885
 886U_BOOT_PCI_DEVICE(eth_designware, supported);
 887#endif
 888