uboot/drivers/net/sunxi_emac.c
<<
>>
Prefs
   1/*
   2 * sunxi_emac.c -- Allwinner A10 ethernet driver
   3 *
   4 * (C) Copyright 2012, Stefan Roese <sr@denx.de>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <linux/err.h>
  12#include <malloc.h>
  13#include <miiphy.h>
  14#include <net.h>
  15#include <asm/io.h>
  16#include <asm/arch/clock.h>
  17#include <asm/arch/gpio.h>
  18
  19/* EMAC register  */
  20struct emac_regs {
  21        u32 ctl;        /* 0x00 */
  22        u32 tx_mode;    /* 0x04 */
  23        u32 tx_flow;    /* 0x08 */
  24        u32 tx_ctl0;    /* 0x0c */
  25        u32 tx_ctl1;    /* 0x10 */
  26        u32 tx_ins;     /* 0x14 */
  27        u32 tx_pl0;     /* 0x18 */
  28        u32 tx_pl1;     /* 0x1c */
  29        u32 tx_sta;     /* 0x20 */
  30        u32 tx_io_data; /* 0x24 */
  31        u32 tx_io_data1;/* 0x28 */
  32        u32 tx_tsvl0;   /* 0x2c */
  33        u32 tx_tsvh0;   /* 0x30 */
  34        u32 tx_tsvl1;   /* 0x34 */
  35        u32 tx_tsvh1;   /* 0x38 */
  36        u32 rx_ctl;     /* 0x3c */
  37        u32 rx_hash0;   /* 0x40 */
  38        u32 rx_hash1;   /* 0x44 */
  39        u32 rx_sta;     /* 0x48 */
  40        u32 rx_io_data; /* 0x4c */
  41        u32 rx_fbc;     /* 0x50 */
  42        u32 int_ctl;    /* 0x54 */
  43        u32 int_sta;    /* 0x58 */
  44        u32 mac_ctl0;   /* 0x5c */
  45        u32 mac_ctl1;   /* 0x60 */
  46        u32 mac_ipgt;   /* 0x64 */
  47        u32 mac_ipgr;   /* 0x68 */
  48        u32 mac_clrt;   /* 0x6c */
  49        u32 mac_maxf;   /* 0x70 */
  50        u32 mac_supp;   /* 0x74 */
  51        u32 mac_test;   /* 0x78 */
  52        u32 mac_mcfg;   /* 0x7c */
  53        u32 mac_mcmd;   /* 0x80 */
  54        u32 mac_madr;   /* 0x84 */
  55        u32 mac_mwtd;   /* 0x88 */
  56        u32 mac_mrdd;   /* 0x8c */
  57        u32 mac_mind;   /* 0x90 */
  58        u32 mac_ssrr;   /* 0x94 */
  59        u32 mac_a0;     /* 0x98 */
  60        u32 mac_a1;     /* 0x9c */
  61};
  62
  63/* SRAMC register  */
  64struct sunxi_sramc_regs {
  65        u32 ctrl0;
  66        u32 ctrl1;
  67};
  68
  69/* 0: Disable       1: Aborted frame enable(default) */
  70#define EMAC_TX_AB_M            (0x1 << 0)
  71/* 0: CPU           1: DMA(default) */
  72#define EMAC_TX_TM              (0x1 << 1)
  73
  74#define EMAC_TX_SETUP           (0)
  75
  76/* 0: DRQ asserted  1: DRQ automatically(default) */
  77#define EMAC_RX_DRQ_MODE        (0x1 << 1)
  78/* 0: CPU           1: DMA(default) */
  79#define EMAC_RX_TM              (0x1 << 2)
  80/* 0: Normal(default)        1: Pass all Frames */
  81#define EMAC_RX_PA              (0x1 << 4)
  82/* 0: Normal(default)        1: Pass Control Frames */
  83#define EMAC_RX_PCF             (0x1 << 5)
  84/* 0: Normal(default)        1: Pass Frames with CRC Error */
  85#define EMAC_RX_PCRCE           (0x1 << 6)
  86/* 0: Normal(default)        1: Pass Frames with Length Error */
  87#define EMAC_RX_PLE             (0x1 << 7)
  88/* 0: Normal                 1: Pass Frames length out of range(default) */
  89#define EMAC_RX_POR             (0x1 << 8)
  90/* 0: Not accept             1: Accept unicast Packets(default) */
  91#define EMAC_RX_UCAD            (0x1 << 16)
  92/* 0: Normal(default)        1: DA Filtering */
  93#define EMAC_RX_DAF             (0x1 << 17)
  94/* 0: Not accept             1: Accept multicast Packets(default) */
  95#define EMAC_RX_MCO             (0x1 << 20)
  96/* 0: Disable(default)       1: Enable Hash filter */
  97#define EMAC_RX_MHF             (0x1 << 21)
  98/* 0: Not accept             1: Accept Broadcast Packets(default) */
  99#define EMAC_RX_BCO             (0x1 << 22)
 100/* 0: Disable(default)       1: Enable SA Filtering */
 101#define EMAC_RX_SAF             (0x1 << 24)
 102/* 0: Normal(default)        1: Inverse Filtering */
 103#define EMAC_RX_SAIF            (0x1 << 25)
 104
 105#define EMAC_RX_SETUP           (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \
 106                                 EMAC_RX_MCO | EMAC_RX_BCO)
 107
 108/* 0: Disable                1: Enable Receive Flow Control(default) */
 109#define EMAC_MAC_CTL0_RFC       (0x1 << 2)
 110/* 0: Disable                1: Enable Transmit Flow Control(default) */
 111#define EMAC_MAC_CTL0_TFC       (0x1 << 3)
 112
 113#define EMAC_MAC_CTL0_SETUP     (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC)
 114
 115/* 0: Disable                1: Enable MAC Frame Length Checking(default) */
 116#define EMAC_MAC_CTL1_FLC       (0x1 << 1)
 117/* 0: Disable(default)       1: Enable Huge Frame */
 118#define EMAC_MAC_CTL1_HF        (0x1 << 2)
 119/* 0: Disable(default)       1: Enable MAC Delayed CRC */
 120#define EMAC_MAC_CTL1_DCRC      (0x1 << 3)
 121/* 0: Disable                1: Enable MAC CRC(default) */
 122#define EMAC_MAC_CTL1_CRC       (0x1 << 4)
 123/* 0: Disable                1: Enable MAC PAD Short frames(default) */
 124#define EMAC_MAC_CTL1_PC        (0x1 << 5)
 125/* 0: Disable(default)       1: Enable MAC PAD Short frames and append CRC */
 126#define EMAC_MAC_CTL1_VC        (0x1 << 6)
 127/* 0: Disable(default)       1: Enable MAC auto detect Short frames */
 128#define EMAC_MAC_CTL1_ADP       (0x1 << 7)
 129/* 0: Disable(default)       1: Enable */
 130#define EMAC_MAC_CTL1_PRE       (0x1 << 8)
 131/* 0: Disable(default)       1: Enable */
 132#define EMAC_MAC_CTL1_LPE       (0x1 << 9)
 133/* 0: Disable(default)       1: Enable no back off */
 134#define EMAC_MAC_CTL1_NB        (0x1 << 12)
 135/* 0: Disable(default)       1: Enable */
 136#define EMAC_MAC_CTL1_BNB       (0x1 << 13)
 137/* 0: Disable(default)       1: Enable */
 138#define EMAC_MAC_CTL1_ED        (0x1 << 14)
 139
 140#define EMAC_MAC_CTL1_SETUP     (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \
 141                                 EMAC_MAC_CTL1_PC)
 142
 143#define EMAC_MAC_IPGT           0x15
 144
 145#define EMAC_MAC_NBTB_IPG1      0xc
 146#define EMAC_MAC_NBTB_IPG2      0x12
 147
 148#define EMAC_MAC_CW             0x37
 149#define EMAC_MAC_RM             0xf
 150
 151#define EMAC_MAC_MFL            0x0600
 152
 153/* Receive status */
 154#define EMAC_CRCERR             (0x1 << 4)
 155#define EMAC_LENERR             (0x3 << 5)
 156
 157#define EMAC_RX_BUFSIZE         2000
 158
 159struct emac_eth_dev {
 160        struct emac_regs *regs;
 161        struct mii_dev *bus;
 162        struct phy_device *phydev;
 163        int link_printed;
 164#ifdef CONFIG_DM_ETH
 165        uchar rx_buf[EMAC_RX_BUFSIZE];
 166#endif
 167};
 168
 169struct emac_rxhdr {
 170        s16 rx_len;
 171        u16 rx_status;
 172};
 173
 174static void emac_inblk_32bit(void *reg, void *data, int count)
 175{
 176        int cnt = (count + 3) >> 2;
 177
 178        if (cnt) {
 179                u32 *buf = data;
 180
 181                do {
 182                        u32 x = readl(reg);
 183                        *buf++ = x;
 184                } while (--cnt);
 185        }
 186}
 187
 188static void emac_outblk_32bit(void *reg, void *data, int count)
 189{
 190        int cnt = (count + 3) >> 2;
 191
 192        if (cnt) {
 193                const u32 *buf = data;
 194
 195                do {
 196                        writel(*buf++, reg);
 197                } while (--cnt);
 198        }
 199}
 200
 201/* Read a word from phyxcer */
 202static int emac_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 203{
 204        struct emac_eth_dev *priv = bus->priv;
 205        struct emac_regs *regs = priv->regs;
 206
 207        /* issue the phy address and reg */
 208        writel(addr << 8 | reg, &regs->mac_madr);
 209
 210        /* pull up the phy io line */
 211        writel(0x1, &regs->mac_mcmd);
 212
 213        /* Wait read complete */
 214        mdelay(1);
 215
 216        /* push down the phy io line */
 217        writel(0x0, &regs->mac_mcmd);
 218
 219        /* And read data */
 220        return readl(&regs->mac_mrdd);
 221}
 222
 223/* Write a word to phyxcer */
 224static int emac_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
 225                          u16 value)
 226{
 227        struct emac_eth_dev *priv = bus->priv;
 228        struct emac_regs *regs = priv->regs;
 229
 230        /* issue the phy address and reg */
 231        writel(addr << 8 | reg, &regs->mac_madr);
 232
 233        /* pull up the phy io line */
 234        writel(0x1, &regs->mac_mcmd);
 235
 236        /* Wait write complete */
 237        mdelay(1);
 238
 239        /* push down the phy io line */
 240        writel(0x0, &regs->mac_mcmd);
 241
 242        /* and write data */
 243        writel(value, &regs->mac_mwtd);
 244
 245        return 0;
 246}
 247
 248static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
 249{
 250        int ret, mask = 0xffffffff;
 251
 252#ifdef CONFIG_PHY_ADDR
 253        mask = 1 << CONFIG_PHY_ADDR;
 254#endif
 255
 256        priv->bus = mdio_alloc();
 257        if (!priv->bus) {
 258                printf("Failed to allocate MDIO bus\n");
 259                return -ENOMEM;
 260        }
 261
 262        priv->bus->read = emac_mdio_read;
 263        priv->bus->write = emac_mdio_write;
 264        priv->bus->priv = priv;
 265        strcpy(priv->bus->name, "emac");
 266
 267        ret = mdio_register(priv->bus);
 268        if (ret)
 269                return ret;
 270
 271        priv->phydev = phy_find_by_mask(priv->bus, mask,
 272                                        PHY_INTERFACE_MODE_MII);
 273        if (!priv->phydev)
 274                return -ENODEV;
 275
 276        phy_connect_dev(priv->phydev, dev);
 277        phy_config(priv->phydev);
 278
 279        return 0;
 280}
 281
 282static void emac_setup(struct emac_eth_dev *priv)
 283{
 284        struct emac_regs *regs = priv->regs;
 285        u32 reg_val;
 286
 287        /* Set up TX */
 288        writel(EMAC_TX_SETUP, &regs->tx_mode);
 289
 290        /* Set up RX */
 291        writel(EMAC_RX_SETUP, &regs->rx_ctl);
 292
 293        /* Set MAC */
 294        /* Set MAC CTL0 */
 295        writel(EMAC_MAC_CTL0_SETUP, &regs->mac_ctl0);
 296
 297        /* Set MAC CTL1 */
 298        reg_val = 0;
 299        if (priv->phydev->duplex == DUPLEX_FULL)
 300                reg_val = (0x1 << 0);
 301        writel(EMAC_MAC_CTL1_SETUP | reg_val, &regs->mac_ctl1);
 302
 303        /* Set up IPGT */
 304        writel(EMAC_MAC_IPGT, &regs->mac_ipgt);
 305
 306        /* Set up IPGR */
 307        writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), &regs->mac_ipgr);
 308
 309        /* Set up Collison window */
 310        writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), &regs->mac_clrt);
 311
 312        /* Set up Max Frame Length */
 313        writel(EMAC_MAC_MFL, &regs->mac_maxf);
 314}
 315
 316static void emac_reset(struct emac_eth_dev *priv)
 317{
 318        struct emac_regs *regs = priv->regs;
 319
 320        debug("resetting device\n");
 321
 322        /* RESET device */
 323        writel(0, &regs->ctl);
 324        udelay(200);
 325
 326        writel(1, &regs->ctl);
 327        udelay(200);
 328}
 329
 330static int _sunxi_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr)
 331{
 332        struct emac_regs *regs = priv->regs;
 333        int ret;
 334
 335        /* Init EMAC */
 336
 337        /* Flush RX FIFO */
 338        setbits_le32(&regs->rx_ctl, 0x8);
 339        udelay(1);
 340
 341        /* Init MAC */
 342
 343        /* Soft reset MAC */
 344        clrbits_le32(&regs->mac_ctl0, 0x1 << 15);
 345
 346        /* Clear RX counter */
 347        writel(0x0, &regs->rx_fbc);
 348        udelay(1);
 349
 350        /* Set up EMAC */
 351        emac_setup(priv);
 352
 353        writel(enetaddr[0] << 16 | enetaddr[1] << 8 | enetaddr[2],
 354               &regs->mac_a1);
 355        writel(enetaddr[3] << 16 | enetaddr[4] << 8 | enetaddr[5],
 356               &regs->mac_a0);
 357
 358        mdelay(1);
 359
 360        emac_reset(priv);
 361
 362        /* PHY POWER UP */
 363        ret = phy_startup(priv->phydev);
 364        if (ret) {
 365                printf("Could not initialize PHY %s\n",
 366                       priv->phydev->dev->name);
 367                return ret;
 368        }
 369
 370        /* Print link status only once */
 371        if (!priv->link_printed) {
 372                printf("ENET Speed is %d Mbps - %s duplex connection\n",
 373                       priv->phydev->speed,
 374                       priv->phydev->duplex ? "FULL" : "HALF");
 375                priv->link_printed = 1;
 376        }
 377
 378        /* Set EMAC SPEED depend on PHY */
 379        if (priv->phydev->speed == SPEED_100)
 380                setbits_le32(&regs->mac_supp, 1 << 8);
 381        else
 382                clrbits_le32(&regs->mac_supp, 1 << 8);
 383
 384        /* Set duplex depend on phy */
 385        if (priv->phydev->duplex == DUPLEX_FULL)
 386                setbits_le32(&regs->mac_ctl1, 1 << 0);
 387        else
 388                clrbits_le32(&regs->mac_ctl1, 1 << 0);
 389
 390        /* Enable RX/TX */
 391        setbits_le32(&regs->ctl, 0x7);
 392
 393        return 0;
 394}
 395
 396static int _sunxi_emac_eth_recv(struct emac_eth_dev *priv, void *packet)
 397{
 398        struct emac_regs *regs = priv->regs;
 399        struct emac_rxhdr rxhdr;
 400        u32 rxcount;
 401        u32 reg_val;
 402        int rx_len;
 403        int rx_status;
 404        int good_packet;
 405
 406        /* Check packet ready or not */
 407
 408        /* Race warning: The first packet might arrive with
 409         * the interrupts disabled, but the second will fix
 410         */
 411        rxcount = readl(&regs->rx_fbc);
 412        if (!rxcount) {
 413                /* Had one stuck? */
 414                rxcount = readl(&regs->rx_fbc);
 415                if (!rxcount)
 416                        return -EAGAIN;
 417        }
 418
 419        reg_val = readl(&regs->rx_io_data);
 420        if (reg_val != 0x0143414d) {
 421                /* Disable RX */
 422                clrbits_le32(&regs->ctl, 0x1 << 2);
 423
 424                /* Flush RX FIFO */
 425                setbits_le32(&regs->rx_ctl, 0x1 << 3);
 426                while (readl(&regs->rx_ctl) & (0x1 << 3))
 427                        ;
 428
 429                /* Enable RX */
 430                setbits_le32(&regs->ctl, 0x1 << 2);
 431
 432                return -EAGAIN;
 433        }
 434
 435        /* A packet ready now
 436         * Get status/length
 437         */
 438        good_packet = 1;
 439
 440        emac_inblk_32bit(&regs->rx_io_data, &rxhdr, sizeof(rxhdr));
 441
 442        rx_len = rxhdr.rx_len;
 443        rx_status = rxhdr.rx_status;
 444
 445        /* Packet Status check */
 446        if (rx_len < 0x40) {
 447                good_packet = 0;
 448                debug("RX: Bad Packet (runt)\n");
 449        }
 450
 451        /* rx_status is identical to RSR register. */
 452        if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) {
 453                good_packet = 0;
 454                if (rx_status & EMAC_CRCERR)
 455                        printf("crc error\n");
 456                if (rx_status & EMAC_LENERR)
 457                        printf("length error\n");
 458        }
 459
 460        /* Move data from EMAC */
 461        if (good_packet) {
 462                if (rx_len > EMAC_RX_BUFSIZE) {
 463                        printf("Received packet is too big (len=%d)\n", rx_len);
 464                        return -EMSGSIZE;
 465                }
 466                emac_inblk_32bit((void *)&regs->rx_io_data, packet, rx_len);
 467                return rx_len;
 468        }
 469
 470        return -EIO; /* Bad packet */
 471}
 472
 473static int _sunxi_emac_eth_send(struct emac_eth_dev *priv, void *packet,
 474                                int len)
 475{
 476        struct emac_regs *regs = priv->regs;
 477
 478        /* Select channel 0 */
 479        writel(0, &regs->tx_ins);
 480
 481        /* Write packet */
 482        emac_outblk_32bit((void *)&regs->tx_io_data, packet, len);
 483
 484        /* Set TX len */
 485        writel(len, &regs->tx_pl0);
 486
 487        /* Start translate from fifo to phy */
 488        setbits_le32(&regs->tx_ctl0, 1);
 489
 490        return 0;
 491}
 492
 493static void sunxi_emac_board_setup(struct emac_eth_dev *priv)
 494{
 495        struct sunxi_ccm_reg *const ccm =
 496                (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 497        struct sunxi_sramc_regs *sram =
 498                (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE;
 499        struct emac_regs *regs = priv->regs;
 500        int pin;
 501
 502        /* Map SRAM to EMAC */
 503        setbits_le32(&sram->ctrl1, 0x5 << 2);
 504
 505        /* Configure pin mux settings for MII Ethernet */
 506        for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++)
 507                sunxi_gpio_set_cfgpin(pin, SUNXI_GPA_EMAC);
 508
 509        /* Set up clock gating */
 510        setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC);
 511
 512        /* Set MII clock */
 513        clrsetbits_le32(&regs->mac_mcfg, 0xf << 2, 0xd << 2);
 514}
 515
 516static int sunxi_emac_eth_start(struct udevice *dev)
 517{
 518        struct eth_pdata *pdata = dev_get_platdata(dev);
 519
 520        return _sunxi_emac_eth_init(dev->priv, pdata->enetaddr);
 521}
 522
 523static int sunxi_emac_eth_send(struct udevice *dev, void *packet, int length)
 524{
 525        struct emac_eth_dev *priv = dev_get_priv(dev);
 526
 527        return _sunxi_emac_eth_send(priv, packet, length);
 528}
 529
 530static int sunxi_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 531{
 532        struct emac_eth_dev *priv = dev_get_priv(dev);
 533        int rx_len;
 534
 535        rx_len = _sunxi_emac_eth_recv(priv, priv->rx_buf);
 536        *packetp = priv->rx_buf;
 537
 538        return rx_len;
 539}
 540
 541static void sunxi_emac_eth_stop(struct udevice *dev)
 542{
 543        /* Nothing to do here */
 544}
 545
 546static int sunxi_emac_eth_probe(struct udevice *dev)
 547{
 548        struct eth_pdata *pdata = dev_get_platdata(dev);
 549        struct emac_eth_dev *priv = dev_get_priv(dev);
 550
 551        priv->regs = (struct emac_regs *)pdata->iobase;
 552        sunxi_emac_board_setup(priv);
 553
 554        return sunxi_emac_init_phy(priv, dev);
 555}
 556
 557static const struct eth_ops sunxi_emac_eth_ops = {
 558        .start                  = sunxi_emac_eth_start,
 559        .send                   = sunxi_emac_eth_send,
 560        .recv                   = sunxi_emac_eth_recv,
 561        .stop                   = sunxi_emac_eth_stop,
 562};
 563
 564static int sunxi_emac_eth_ofdata_to_platdata(struct udevice *dev)
 565{
 566        struct eth_pdata *pdata = dev_get_platdata(dev);
 567
 568        pdata->iobase = dev_get_addr(dev);
 569
 570        return 0;
 571}
 572
 573static const struct udevice_id sunxi_emac_eth_ids[] = {
 574        { .compatible = "allwinner,sun4i-a10-emac" },
 575        { }
 576};
 577
 578U_BOOT_DRIVER(eth_sunxi_emac) = {
 579        .name   = "eth_sunxi_emac",
 580        .id     = UCLASS_ETH,
 581        .of_match = sunxi_emac_eth_ids,
 582        .ofdata_to_platdata = sunxi_emac_eth_ofdata_to_platdata,
 583        .probe  = sunxi_emac_eth_probe,
 584        .ops    = &sunxi_emac_eth_ops,
 585        .priv_auto_alloc_size = sizeof(struct emac_eth_dev),
 586        .platdata_auto_alloc_size = sizeof(struct eth_pdata),
 587};
 588