uboot/drivers/net/ag7xxx.c
<<
>>
Prefs
   1/*
   2 * Atheros AR71xx / AR9xxx GMAC driver
   3 *
   4 * Copyright (C) 2016 Marek Vasut <marex@denx.de>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <miiphy.h>
  13#include <malloc.h>
  14#include <linux/compiler.h>
  15#include <linux/err.h>
  16#include <linux/mii.h>
  17#include <wait_bit.h>
  18#include <asm/io.h>
  19
  20#include <mach/ath79.h>
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24enum ag7xxx_model {
  25        AG7XXX_MODEL_AG933X,
  26        AG7XXX_MODEL_AG934X,
  27};
  28
  29#define AG7XXX_ETH_CFG1                         0x00
  30#define AG7XXX_ETH_CFG1_SOFT_RST                BIT(31)
  31#define AG7XXX_ETH_CFG1_RX_RST                  BIT(19)
  32#define AG7XXX_ETH_CFG1_TX_RST                  BIT(18)
  33#define AG7XXX_ETH_CFG1_LOOPBACK                BIT(8)
  34#define AG7XXX_ETH_CFG1_RX_EN                   BIT(2)
  35#define AG7XXX_ETH_CFG1_TX_EN                   BIT(0)
  36
  37#define AG7XXX_ETH_CFG2                         0x04
  38#define AG7XXX_ETH_CFG2_IF_1000                 BIT(9)
  39#define AG7XXX_ETH_CFG2_IF_10_100               BIT(8)
  40#define AG7XXX_ETH_CFG2_IF_SPEED_MASK           (3 << 8)
  41#define AG7XXX_ETH_CFG2_HUGE_FRAME_EN           BIT(5)
  42#define AG7XXX_ETH_CFG2_LEN_CHECK               BIT(4)
  43#define AG7XXX_ETH_CFG2_PAD_CRC_EN              BIT(2)
  44#define AG7XXX_ETH_CFG2_FDX                     BIT(0)
  45
  46#define AG7XXX_ETH_MII_MGMT_CFG                 0x20
  47#define AG7XXX_ETH_MII_MGMT_CFG_RESET           BIT(31)
  48
  49#define AG7XXX_ETH_MII_MGMT_CMD                 0x24
  50#define AG7XXX_ETH_MII_MGMT_CMD_READ            0x1
  51
  52#define AG7XXX_ETH_MII_MGMT_ADDRESS             0x28
  53#define AG7XXX_ETH_MII_MGMT_ADDRESS_SHIFT       8
  54
  55#define AG7XXX_ETH_MII_MGMT_CTRL                0x2c
  56
  57#define AG7XXX_ETH_MII_MGMT_STATUS              0x30
  58
  59#define AG7XXX_ETH_MII_MGMT_IND                 0x34
  60#define AG7XXX_ETH_MII_MGMT_IND_INVALID         BIT(2)
  61#define AG7XXX_ETH_MII_MGMT_IND_BUSY            BIT(0)
  62
  63#define AG7XXX_ETH_ADDR1                        0x40
  64#define AG7XXX_ETH_ADDR2                        0x44
  65
  66#define AG7XXX_ETH_FIFO_CFG_0                   0x48
  67#define AG7XXX_ETH_FIFO_CFG_1                   0x4c
  68#define AG7XXX_ETH_FIFO_CFG_2                   0x50
  69#define AG7XXX_ETH_FIFO_CFG_3                   0x54
  70#define AG7XXX_ETH_FIFO_CFG_4                   0x58
  71#define AG7XXX_ETH_FIFO_CFG_5                   0x5c
  72
  73#define AG7XXX_ETH_DMA_TX_CTRL                  0x180
  74#define AG7XXX_ETH_DMA_TX_CTRL_TXE              BIT(0)
  75
  76#define AG7XXX_ETH_DMA_TX_DESC                  0x184
  77
  78#define AG7XXX_ETH_DMA_TX_STATUS                0x188
  79
  80#define AG7XXX_ETH_DMA_RX_CTRL                  0x18c
  81#define AG7XXX_ETH_DMA_RX_CTRL_RXE              BIT(0)
  82
  83#define AG7XXX_ETH_DMA_RX_DESC                  0x190
  84
  85#define AG7XXX_ETH_DMA_RX_STATUS                0x194
  86
  87/* Custom register at 0x18070000 */
  88#define AG7XXX_GMAC_ETH_CFG                     0x00
  89#define AG7XXX_ETH_CFG_SW_PHY_ADDR_SWAP         BIT(8)
  90#define AG7XXX_ETH_CFG_SW_PHY_SWAP              BIT(7)
  91#define AG7XXX_ETH_CFG_SW_ONLY_MODE             BIT(6)
  92#define AG7XXX_ETH_CFG_GE0_ERR_EN               BIT(5)
  93#define AG7XXX_ETH_CFG_MII_GE0_SLAVE            BIT(4)
  94#define AG7XXX_ETH_CFG_MII_GE0_MASTER           BIT(3)
  95#define AG7XXX_ETH_CFG_GMII_GE0                 BIT(2)
  96#define AG7XXX_ETH_CFG_MII_GE0                  BIT(1)
  97#define AG7XXX_ETH_CFG_RGMII_GE0                BIT(0)
  98
  99#define CONFIG_TX_DESCR_NUM     8
 100#define CONFIG_RX_DESCR_NUM     8
 101#define CONFIG_ETH_BUFSIZE      2048
 102#define TX_TOTAL_BUFSIZE        (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
 103#define RX_TOTAL_BUFSIZE        (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
 104
 105/* DMA descriptor. */
 106struct ag7xxx_dma_desc {
 107        u32     data_addr;
 108#define AG7XXX_DMADESC_IS_EMPTY                 BIT(31)
 109#define AG7XXX_DMADESC_FTPP_OVERRIDE_OFFSET     16
 110#define AG7XXX_DMADESC_PKT_SIZE_OFFSET          0
 111#define AG7XXX_DMADESC_PKT_SIZE_MASK            0xfff
 112        u32     config;
 113        u32     next_desc;
 114        u32     _pad[5];
 115};
 116
 117struct ar7xxx_eth_priv {
 118        struct ag7xxx_dma_desc  tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
 119        struct ag7xxx_dma_desc  rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
 120        char            txbuffs[TX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN);
 121        char            rxbuffs[RX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN);
 122
 123        void __iomem            *regs;
 124        void __iomem            *phyregs;
 125
 126        struct eth_device       *dev;
 127        struct phy_device       *phydev;
 128        struct mii_dev          *bus;
 129
 130        u32                     interface;
 131        u32                     tx_currdescnum;
 132        u32                     rx_currdescnum;
 133        enum ag7xxx_model       model;
 134};
 135
 136/*
 137 * Switch and MDIO access
 138 */
 139static int ag7xxx_switch_read(struct mii_dev *bus, int addr, int reg, u16 *val)
 140{
 141        struct ar7xxx_eth_priv *priv = bus->priv;
 142        void __iomem *regs = priv->phyregs;
 143        int ret;
 144
 145        writel(0x0, regs + AG7XXX_ETH_MII_MGMT_CMD);
 146        writel((addr << AG7XXX_ETH_MII_MGMT_ADDRESS_SHIFT) | reg,
 147               regs + AG7XXX_ETH_MII_MGMT_ADDRESS);
 148        writel(AG7XXX_ETH_MII_MGMT_CMD_READ,
 149               regs + AG7XXX_ETH_MII_MGMT_CMD);
 150
 151        ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND,
 152                           AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
 153        if (ret)
 154                return ret;
 155
 156        *val = readl(regs + AG7XXX_ETH_MII_MGMT_STATUS) & 0xffff;
 157        writel(0x0, regs + AG7XXX_ETH_MII_MGMT_CMD);
 158
 159        return 0;
 160}
 161
 162static int ag7xxx_switch_write(struct mii_dev *bus, int addr, int reg, u16 val)
 163{
 164        struct ar7xxx_eth_priv *priv = bus->priv;
 165        void __iomem *regs = priv->phyregs;
 166        int ret;
 167
 168        writel((addr << AG7XXX_ETH_MII_MGMT_ADDRESS_SHIFT) | reg,
 169               regs + AG7XXX_ETH_MII_MGMT_ADDRESS);
 170        writel(val, regs + AG7XXX_ETH_MII_MGMT_CTRL);
 171
 172        ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND,
 173                           AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
 174
 175        return ret;
 176}
 177
 178static int ag7xxx_switch_reg_read(struct mii_dev *bus, int reg, u32 *val)
 179{
 180        struct ar7xxx_eth_priv *priv = bus->priv;
 181        u32 phy_addr;
 182        u32 reg_addr;
 183        u32 phy_temp;
 184        u32 reg_temp;
 185        u16 rv = 0;
 186        int ret;
 187
 188        if (priv->model == AG7XXX_MODEL_AG933X) {
 189                phy_addr = 0x1f;
 190                reg_addr = 0x10;
 191        } else if (priv->model == AG7XXX_MODEL_AG934X) {
 192                phy_addr = 0x18;
 193                reg_addr = 0x00;
 194        } else
 195                return -EINVAL;
 196
 197        ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9);
 198        if (ret)
 199                return ret;
 200
 201        phy_temp = ((reg >> 6) & 0x7) | 0x10;
 202        reg_temp = (reg >> 1) & 0x1e;
 203        *val = 0;
 204
 205        ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 0, &rv);
 206        if (ret < 0)
 207                return ret;
 208        *val |= rv;
 209
 210        ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 1, &rv);
 211        if (ret < 0)
 212                return ret;
 213        *val |= (rv << 16);
 214
 215        return 0;
 216}
 217
 218static int ag7xxx_switch_reg_write(struct mii_dev *bus, int reg, u32 val)
 219{
 220        struct ar7xxx_eth_priv *priv = bus->priv;
 221        u32 phy_addr;
 222        u32 reg_addr;
 223        u32 phy_temp;
 224        u32 reg_temp;
 225        int ret;
 226
 227        if (priv->model == AG7XXX_MODEL_AG933X) {
 228                phy_addr = 0x1f;
 229                reg_addr = 0x10;
 230        } else if (priv->model == AG7XXX_MODEL_AG934X) {
 231                phy_addr = 0x18;
 232                reg_addr = 0x00;
 233        } else
 234                return -EINVAL;
 235
 236        ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9);
 237        if (ret)
 238                return ret;
 239
 240        phy_temp = ((reg >> 6) & 0x7) | 0x10;
 241        reg_temp = (reg >> 1) & 0x1e;
 242
 243        /*
 244         * The switch on AR933x has some special register behavior, which
 245         * expects particular write order of their nibbles:
 246         *   0x40 ..... MSB first, LSB second
 247         *   0x50 ..... MSB first, LSB second
 248         *   0x98 ..... LSB first, MSB second
 249         *   others ... don't care
 250         */
 251        if ((priv->model == AG7XXX_MODEL_AG933X) && (reg == 0x98)) {
 252                ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 0, val & 0xffff);
 253                if (ret < 0)
 254                        return ret;
 255
 256                ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16);
 257                if (ret < 0)
 258                        return ret;
 259        } else {
 260                ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16);
 261                if (ret < 0)
 262                        return ret;
 263
 264                ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 0, val & 0xffff);
 265                if (ret < 0)
 266                        return ret;
 267        }
 268
 269        return 0;
 270}
 271
 272static u16 ag7xxx_mdio_rw(struct mii_dev *bus, int addr, int reg, u32 val)
 273{
 274        u32 data;
 275
 276        /* Dummy read followed by PHY read/write command. */
 277        ag7xxx_switch_reg_read(bus, 0x98, &data);
 278        data = val | (reg << 16) | (addr << 21) | BIT(30) | BIT(31);
 279        ag7xxx_switch_reg_write(bus, 0x98, data);
 280
 281        /* Wait for operation to finish */
 282        do {
 283                ag7xxx_switch_reg_read(bus, 0x98, &data);
 284        } while (data & BIT(31));
 285
 286        return data & 0xffff;
 287}
 288
 289static int ag7xxx_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 290{
 291        return ag7xxx_mdio_rw(bus, addr, reg, BIT(27));
 292}
 293
 294static int ag7xxx_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
 295                             u16 val)
 296{
 297        ag7xxx_mdio_rw(bus, addr, reg, val);
 298        return 0;
 299}
 300
 301/*
 302 * DMA ring handlers
 303 */
 304static void ag7xxx_dma_clean_tx(struct udevice *dev)
 305{
 306        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 307        struct ag7xxx_dma_desc *curr, *next;
 308        u32 start, end;
 309        int i;
 310
 311        for (i = 0; i < CONFIG_TX_DESCR_NUM; i++) {
 312                curr = &priv->tx_mac_descrtable[i];
 313                next = &priv->tx_mac_descrtable[(i + 1) % CONFIG_TX_DESCR_NUM];
 314
 315                curr->data_addr = virt_to_phys(&priv->txbuffs[i * CONFIG_ETH_BUFSIZE]);
 316                curr->config = AG7XXX_DMADESC_IS_EMPTY;
 317                curr->next_desc = virt_to_phys(next);
 318        }
 319
 320        priv->tx_currdescnum = 0;
 321
 322        /* Cache: Flush descriptors, don't care about buffers. */
 323        start = (u32)(&priv->tx_mac_descrtable[0]);
 324        end = start + sizeof(priv->tx_mac_descrtable);
 325        flush_dcache_range(start, end);
 326}
 327
 328static void ag7xxx_dma_clean_rx(struct udevice *dev)
 329{
 330        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 331        struct ag7xxx_dma_desc *curr, *next;
 332        u32 start, end;
 333        int i;
 334
 335        for (i = 0; i < CONFIG_RX_DESCR_NUM; i++) {
 336                curr = &priv->rx_mac_descrtable[i];
 337                next = &priv->rx_mac_descrtable[(i + 1) % CONFIG_RX_DESCR_NUM];
 338
 339                curr->data_addr = virt_to_phys(&priv->rxbuffs[i * CONFIG_ETH_BUFSIZE]);
 340                curr->config = AG7XXX_DMADESC_IS_EMPTY;
 341                curr->next_desc = virt_to_phys(next);
 342        }
 343
 344        priv->rx_currdescnum = 0;
 345
 346        /* Cache: Flush+Invalidate descriptors, Invalidate buffers. */
 347        start = (u32)(&priv->rx_mac_descrtable[0]);
 348        end = start + sizeof(priv->rx_mac_descrtable);
 349        flush_dcache_range(start, end);
 350        invalidate_dcache_range(start, end);
 351
 352        start = (u32)&priv->rxbuffs;
 353        end = start + sizeof(priv->rxbuffs);
 354        invalidate_dcache_range(start, end);
 355}
 356
 357/*
 358 * Ethernet I/O
 359 */
 360static int ag7xxx_eth_send(struct udevice *dev, void *packet, int length)
 361{
 362        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 363        struct ag7xxx_dma_desc *curr;
 364        u32 start, end;
 365
 366        curr = &priv->tx_mac_descrtable[priv->tx_currdescnum];
 367
 368        /* Cache: Invalidate descriptor. */
 369        start = (u32)curr;
 370        end = start + sizeof(*curr);
 371        invalidate_dcache_range(start, end);
 372
 373        if (!(curr->config & AG7XXX_DMADESC_IS_EMPTY)) {
 374                printf("ag7xxx: Out of TX DMA descriptors!\n");
 375                return -EPERM;
 376        }
 377
 378        /* Copy the packet into the data buffer. */
 379        memcpy(phys_to_virt(curr->data_addr), packet, length);
 380        curr->config = length & AG7XXX_DMADESC_PKT_SIZE_MASK;
 381
 382        /* Cache: Flush descriptor, Flush buffer. */
 383        start = (u32)curr;
 384        end = start + sizeof(*curr);
 385        flush_dcache_range(start, end);
 386        start = (u32)phys_to_virt(curr->data_addr);
 387        end = start + length;
 388        flush_dcache_range(start, end);
 389
 390        /* Load the DMA descriptor and start TX DMA. */
 391        writel(AG7XXX_ETH_DMA_TX_CTRL_TXE,
 392               priv->regs + AG7XXX_ETH_DMA_TX_CTRL);
 393
 394        /* Switch to next TX descriptor. */
 395        priv->tx_currdescnum = (priv->tx_currdescnum + 1) % CONFIG_TX_DESCR_NUM;
 396
 397        return 0;
 398}
 399
 400static int ag7xxx_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 401{
 402        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 403        struct ag7xxx_dma_desc *curr;
 404        u32 start, end, length;
 405
 406        curr = &priv->rx_mac_descrtable[priv->rx_currdescnum];
 407
 408        /* Cache: Invalidate descriptor. */
 409        start = (u32)curr;
 410        end = start + sizeof(*curr);
 411        invalidate_dcache_range(start, end);
 412
 413        /* No packets received. */
 414        if (curr->config & AG7XXX_DMADESC_IS_EMPTY)
 415                return -EAGAIN;
 416
 417        length = curr->config & AG7XXX_DMADESC_PKT_SIZE_MASK;
 418
 419        /* Cache: Invalidate buffer. */
 420        start = (u32)phys_to_virt(curr->data_addr);
 421        end = start + length;
 422        invalidate_dcache_range(start, end);
 423
 424        /* Receive one packet and return length. */
 425        *packetp = phys_to_virt(curr->data_addr);
 426        return length;
 427}
 428
 429static int ag7xxx_eth_free_pkt(struct udevice *dev, uchar *packet,
 430                                   int length)
 431{
 432        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 433        struct ag7xxx_dma_desc *curr;
 434        u32 start, end;
 435
 436        curr = &priv->rx_mac_descrtable[priv->rx_currdescnum];
 437
 438        curr->config = AG7XXX_DMADESC_IS_EMPTY;
 439
 440        /* Cache: Flush descriptor. */
 441        start = (u32)curr;
 442        end = start + sizeof(*curr);
 443        flush_dcache_range(start, end);
 444
 445        /* Switch to next RX descriptor. */
 446        priv->rx_currdescnum = (priv->rx_currdescnum + 1) % CONFIG_RX_DESCR_NUM;
 447
 448        return 0;
 449}
 450
 451static int ag7xxx_eth_start(struct udevice *dev)
 452{
 453        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 454
 455        /* FIXME: Check if link up */
 456
 457        /* Clear the DMA rings. */
 458        ag7xxx_dma_clean_tx(dev);
 459        ag7xxx_dma_clean_rx(dev);
 460
 461        /* Load DMA descriptors and start the RX DMA. */
 462        writel(virt_to_phys(&priv->tx_mac_descrtable[priv->tx_currdescnum]),
 463               priv->regs + AG7XXX_ETH_DMA_TX_DESC);
 464        writel(virt_to_phys(&priv->rx_mac_descrtable[priv->rx_currdescnum]),
 465               priv->regs + AG7XXX_ETH_DMA_RX_DESC);
 466        writel(AG7XXX_ETH_DMA_RX_CTRL_RXE,
 467               priv->regs + AG7XXX_ETH_DMA_RX_CTRL);
 468
 469        return 0;
 470}
 471
 472static void ag7xxx_eth_stop(struct udevice *dev)
 473{
 474        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 475
 476        /* Stop the TX DMA. */
 477        writel(0, priv->regs + AG7XXX_ETH_DMA_TX_CTRL);
 478        wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_TX_CTRL, ~0, 0,
 479                     1000, 0);
 480
 481        /* Stop the RX DMA. */
 482        writel(0, priv->regs + AG7XXX_ETH_DMA_RX_CTRL);
 483        wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_RX_CTRL, ~0, 0,
 484                     1000, 0);
 485}
 486
 487/*
 488 * Hardware setup
 489 */
 490static int ag7xxx_eth_write_hwaddr(struct udevice *dev)
 491{
 492        struct eth_pdata *pdata = dev_get_platdata(dev);
 493        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 494        unsigned char *mac = pdata->enetaddr;
 495        u32 macid_lo, macid_hi;
 496
 497        macid_hi = mac[3] | (mac[2] << 8) | (mac[1] << 16) | (mac[0] << 24);
 498        macid_lo = (mac[5] << 16) | (mac[4] << 24);
 499
 500        writel(macid_lo, priv->regs + AG7XXX_ETH_ADDR1);
 501        writel(macid_hi, priv->regs + AG7XXX_ETH_ADDR2);
 502
 503        return 0;
 504}
 505
 506static void ag7xxx_hw_setup(struct udevice *dev)
 507{
 508        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 509        u32 speed;
 510
 511        setbits_be32(priv->regs + AG7XXX_ETH_CFG1,
 512                     AG7XXX_ETH_CFG1_RX_RST | AG7XXX_ETH_CFG1_TX_RST |
 513                     AG7XXX_ETH_CFG1_SOFT_RST);
 514
 515        mdelay(10);
 516
 517        writel(AG7XXX_ETH_CFG1_RX_EN | AG7XXX_ETH_CFG1_TX_EN,
 518               priv->regs + AG7XXX_ETH_CFG1);
 519
 520        if (priv->interface == PHY_INTERFACE_MODE_RMII)
 521                speed = AG7XXX_ETH_CFG2_IF_10_100;
 522        else
 523                speed = AG7XXX_ETH_CFG2_IF_1000;
 524
 525        clrsetbits_be32(priv->regs + AG7XXX_ETH_CFG2,
 526                        AG7XXX_ETH_CFG2_IF_SPEED_MASK,
 527                        speed | AG7XXX_ETH_CFG2_PAD_CRC_EN |
 528                        AG7XXX_ETH_CFG2_LEN_CHECK);
 529
 530        writel(0xfff0000, priv->regs + AG7XXX_ETH_FIFO_CFG_1);
 531        writel(0x1fff, priv->regs + AG7XXX_ETH_FIFO_CFG_2);
 532
 533        writel(0x1f00, priv->regs + AG7XXX_ETH_FIFO_CFG_0);
 534        setbits_be32(priv->regs + AG7XXX_ETH_FIFO_CFG_4, 0x3ffff);
 535        writel(0x10ffff, priv->regs + AG7XXX_ETH_FIFO_CFG_1);
 536        writel(0xaaa0555, priv->regs + AG7XXX_ETH_FIFO_CFG_2);
 537        writel(0x7eccf, priv->regs + AG7XXX_ETH_FIFO_CFG_5);
 538        writel(0x1f00140, priv->regs + AG7XXX_ETH_FIFO_CFG_3);
 539}
 540
 541static int ag7xxx_mii_get_div(void)
 542{
 543        ulong freq = get_bus_freq(0);
 544
 545        switch (freq / 1000000) {
 546        case 150:       return 0x7;
 547        case 175:       return 0x5;
 548        case 200:       return 0x4;
 549        case 210:       return 0x9;
 550        case 220:       return 0x9;
 551        default:        return 0x7;
 552        }
 553}
 554
 555static int ag7xxx_mii_setup(struct udevice *dev)
 556{
 557        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 558        int i, ret, div = ag7xxx_mii_get_div();
 559        u32 reg;
 560
 561        if (priv->model == AG7XXX_MODEL_AG933X) {
 562                /* Unit 0 is PHY-less on AR9331, see datasheet Figure 2-3 */
 563                if (priv->interface == PHY_INTERFACE_MODE_RMII)
 564                        return 0;
 565        }
 566
 567        if (priv->model == AG7XXX_MODEL_AG934X) {
 568                writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | 0x4,
 569                       priv->regs + AG7XXX_ETH_MII_MGMT_CFG);
 570                writel(0x4, priv->regs + AG7XXX_ETH_MII_MGMT_CFG);
 571                return 0;
 572        }
 573
 574        for (i = 0; i < 10; i++) {
 575                writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | div,
 576                       priv->regs + AG7XXX_ETH_MII_MGMT_CFG);
 577                writel(div, priv->regs + AG7XXX_ETH_MII_MGMT_CFG);
 578
 579                /* Check the switch */
 580                ret = ag7xxx_switch_reg_read(priv->bus, 0x10c, &reg);
 581                if (ret)
 582                        continue;
 583
 584                if (reg != 0x18007fff)
 585                        continue;
 586
 587                return 0;
 588        }
 589
 590        return -EINVAL;
 591}
 592
 593static int ag933x_phy_setup_wan(struct udevice *dev)
 594{
 595        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 596
 597        /* Configure switch port 4 (GMAC0) */
 598        return ag7xxx_mdio_write(priv->bus, 4, 0, MII_BMCR, 0x9000);
 599}
 600
 601static int ag933x_phy_setup_lan(struct udevice *dev)
 602{
 603        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 604        int i, ret;
 605        u32 reg;
 606
 607        /* Reset the switch */
 608        ret = ag7xxx_switch_reg_read(priv->bus, 0, &reg);
 609        if (ret)
 610                return ret;
 611        reg |= BIT(31);
 612        ret = ag7xxx_switch_reg_write(priv->bus, 0, reg);
 613        if (ret)
 614                return ret;
 615
 616        do {
 617                ret = ag7xxx_switch_reg_read(priv->bus, 0, &reg);
 618                if (ret)
 619                        return ret;
 620        } while (reg & BIT(31));
 621
 622        /* Configure switch ports 0...3 (GMAC1) */
 623        for (i = 0; i < 4; i++) {
 624                ret = ag7xxx_mdio_write(priv->bus, 0x4, 0, MII_BMCR, 0x9000);
 625                if (ret)
 626                        return ret;
 627        }
 628
 629        /* Enable CPU port */
 630        ret = ag7xxx_switch_reg_write(priv->bus, 0x78, BIT(8));
 631        if (ret)
 632                return ret;
 633
 634        for (i = 0; i < 4; i++) {
 635                ret = ag7xxx_switch_reg_write(priv->bus, i * 0x100, BIT(9));
 636                if (ret)
 637                        return ret;
 638        }
 639
 640        /* QM Control */
 641        ret = ag7xxx_switch_reg_write(priv->bus, 0x38, 0xc000050e);
 642        if (ret)
 643                return ret;
 644
 645        /* Disable Atheros header */
 646        ret = ag7xxx_switch_reg_write(priv->bus, 0x104, 0x4004);
 647        if (ret)
 648                return ret;
 649
 650        /* Tag priority mapping */
 651        ret = ag7xxx_switch_reg_write(priv->bus, 0x70, 0xfa50);
 652        if (ret)
 653                return ret;
 654
 655        /* Enable ARP packets to the CPU */
 656        ret = ag7xxx_switch_reg_read(priv->bus, 0x5c, &reg);
 657        if (ret)
 658                return ret;
 659        reg |= 0x100000;
 660        ret = ag7xxx_switch_reg_write(priv->bus, 0x5c, reg);
 661        if (ret)
 662                return ret;
 663
 664        return 0;
 665}
 666
 667static int ag933x_phy_setup_reset_set(struct udevice *dev, int port)
 668{
 669        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 670        int ret;
 671
 672        ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_ADVERTISE,
 673                                ADVERTISE_ALL | ADVERTISE_PAUSE_CAP |
 674                                ADVERTISE_PAUSE_ASYM);
 675        if (ret)
 676                return ret;
 677
 678        if (priv->model == AG7XXX_MODEL_AG934X) {
 679                ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_CTRL1000,
 680                                        ADVERTISE_1000FULL);
 681                if (ret)
 682                        return ret;
 683        }
 684
 685        return ag7xxx_mdio_write(priv->bus, port, 0, MII_BMCR,
 686                                 BMCR_ANENABLE | BMCR_RESET);
 687}
 688
 689static int ag933x_phy_setup_reset_fin(struct udevice *dev, int port)
 690{
 691        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 692        int ret;
 693
 694        do {
 695                ret = ag7xxx_mdio_read(priv->bus, port, 0, MII_BMCR);
 696                if (ret < 0)
 697                        return ret;
 698                mdelay(10);
 699        } while (ret & BMCR_RESET);
 700
 701        return 0;
 702}
 703
 704static int ag933x_phy_setup_common(struct udevice *dev)
 705{
 706        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 707        int i, ret, phymax;
 708
 709        if (priv->model == AG7XXX_MODEL_AG933X)
 710                phymax = 4;
 711        else if (priv->model == AG7XXX_MODEL_AG934X)
 712                phymax = 5;
 713        else
 714                return -EINVAL;
 715
 716        if (priv->interface == PHY_INTERFACE_MODE_RMII) {
 717                ret = ag933x_phy_setup_reset_set(dev, phymax);
 718                if (ret)
 719                        return ret;
 720
 721                ret = ag933x_phy_setup_reset_fin(dev, phymax);
 722                if (ret)
 723                        return ret;
 724
 725                /* Read out link status */
 726                ret = ag7xxx_mdio_read(priv->bus, phymax, 0, MII_MIPSCR);
 727                if (ret < 0)
 728                        return ret;
 729
 730                return 0;
 731        }
 732
 733        /* Switch ports */
 734        for (i = 0; i < phymax; i++) {
 735                ret = ag933x_phy_setup_reset_set(dev, i);
 736                if (ret)
 737                        return ret;
 738        }
 739
 740        for (i = 0; i < phymax; i++) {
 741                ret = ag933x_phy_setup_reset_fin(dev, i);
 742                if (ret)
 743                        return ret;
 744        }
 745
 746        for (i = 0; i < phymax; i++) {
 747                /* Read out link status */
 748                ret = ag7xxx_mdio_read(priv->bus, i, 0, MII_MIPSCR);
 749                if (ret < 0)
 750                        return ret;
 751        }
 752
 753        return 0;
 754}
 755
 756static int ag934x_phy_setup(struct udevice *dev)
 757{
 758        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 759        int i, ret;
 760        u32 reg;
 761
 762        ret = ag7xxx_switch_reg_write(priv->bus, 0x624, 0x7f7f7f7f);
 763        if (ret)
 764                return ret;
 765        ret = ag7xxx_switch_reg_write(priv->bus, 0x10, 0x40000000);
 766        if (ret)
 767                return ret;
 768        ret = ag7xxx_switch_reg_write(priv->bus, 0x4, 0x07600000);
 769        if (ret)
 770                return ret;
 771        ret = ag7xxx_switch_reg_write(priv->bus, 0xc, 0x01000000);
 772        if (ret)
 773                return ret;
 774        ret = ag7xxx_switch_reg_write(priv->bus, 0x7c, 0x0000007e);
 775        if (ret)
 776                return ret;
 777
 778        /* AR8327/AR8328 v1.0 fixup */
 779        ret = ag7xxx_switch_reg_read(priv->bus, 0, &reg);
 780        if (ret)
 781                return ret;
 782        if ((reg & 0xffff) == 0x1201) {
 783                for (i = 0; i < 5; i++) {
 784                        ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1d, 0x0);
 785                        if (ret)
 786                                return ret;
 787                        ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1e, 0x02ea);
 788                        if (ret)
 789                                return ret;
 790                        ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1d, 0x3d);
 791                        if (ret)
 792                                return ret;
 793                        ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1e, 0x68a0);
 794                        if (ret)
 795                                return ret;
 796                }
 797        }
 798
 799        ret = ag7xxx_switch_reg_read(priv->bus, 0x66c, &reg);
 800        if (ret)
 801                return ret;
 802        reg &= ~0x70000;
 803        ret = ag7xxx_switch_reg_write(priv->bus, 0x66c, reg);
 804        if (ret)
 805                return ret;
 806
 807        return 0;
 808}
 809
 810static int ag7xxx_mac_probe(struct udevice *dev)
 811{
 812        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 813        int ret;
 814
 815        ag7xxx_hw_setup(dev);
 816        ret = ag7xxx_mii_setup(dev);
 817        if (ret)
 818                return ret;
 819
 820        ag7xxx_eth_write_hwaddr(dev);
 821
 822        if (priv->model == AG7XXX_MODEL_AG933X) {
 823                if (priv->interface == PHY_INTERFACE_MODE_RMII)
 824                        ret = ag933x_phy_setup_wan(dev);
 825                else
 826                        ret = ag933x_phy_setup_lan(dev);
 827        } else if (priv->model == AG7XXX_MODEL_AG934X) {
 828                ret = ag934x_phy_setup(dev);
 829        } else {
 830                return -EINVAL;
 831        }
 832
 833        if (ret)
 834                return ret;
 835
 836        return ag933x_phy_setup_common(dev);
 837}
 838
 839static int ag7xxx_mdio_probe(struct udevice *dev)
 840{
 841        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 842        struct mii_dev *bus = mdio_alloc();
 843
 844        if (!bus)
 845                return -ENOMEM;
 846
 847        bus->read = ag7xxx_mdio_read;
 848        bus->write = ag7xxx_mdio_write;
 849        snprintf(bus->name, sizeof(bus->name), dev->name);
 850
 851        bus->priv = (void *)priv;
 852
 853        return mdio_register(bus);
 854}
 855
 856static int ag7xxx_get_phy_iface_offset(struct udevice *dev)
 857{
 858        int offset;
 859
 860        offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phy");
 861        if (offset <= 0) {
 862                debug("%s: PHY OF node not found (ret=%i)\n", __func__, offset);
 863                return -EINVAL;
 864        }
 865
 866        offset = fdt_parent_offset(gd->fdt_blob, offset);
 867        if (offset <= 0) {
 868                debug("%s: PHY OF node parent MDIO bus not found (ret=%i)\n",
 869                      __func__, offset);
 870                return -EINVAL;
 871        }
 872
 873        offset = fdt_parent_offset(gd->fdt_blob, offset);
 874        if (offset <= 0) {
 875                debug("%s: PHY MDIO OF node parent MAC not found (ret=%i)\n",
 876                      __func__, offset);
 877                return -EINVAL;
 878        }
 879
 880        return offset;
 881}
 882
 883static int ag7xxx_eth_probe(struct udevice *dev)
 884{
 885        struct eth_pdata *pdata = dev_get_platdata(dev);
 886        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 887        void __iomem *iobase, *phyiobase;
 888        int ret, phyreg;
 889
 890        /* Decoding of convoluted PHY wiring on Atheros MIPS. */
 891        ret = ag7xxx_get_phy_iface_offset(dev);
 892        if (ret <= 0)
 893                return ret;
 894        phyreg = fdtdec_get_int(gd->fdt_blob, ret, "reg", -1);
 895
 896        iobase = map_physmem(pdata->iobase, 0x200, MAP_NOCACHE);
 897        phyiobase = map_physmem(phyreg, 0x200, MAP_NOCACHE);
 898
 899        debug("%s, iobase=%p, phyiobase=%p, priv=%p\n",
 900              __func__, iobase, phyiobase, priv);
 901        priv->regs = iobase;
 902        priv->phyregs = phyiobase;
 903        priv->interface = pdata->phy_interface;
 904        priv->model = dev_get_driver_data(dev);
 905
 906        ret = ag7xxx_mdio_probe(dev);
 907        if (ret)
 908                return ret;
 909
 910        priv->bus = miiphy_get_dev_by_name(dev->name);
 911
 912        ret = ag7xxx_mac_probe(dev);
 913        debug("%s, ret=%d\n", __func__, ret);
 914
 915        return ret;
 916}
 917
 918static int ag7xxx_eth_remove(struct udevice *dev)
 919{
 920        struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
 921
 922        free(priv->phydev);
 923        mdio_unregister(priv->bus);
 924        mdio_free(priv->bus);
 925
 926        return 0;
 927}
 928
 929static const struct eth_ops ag7xxx_eth_ops = {
 930        .start                  = ag7xxx_eth_start,
 931        .send                   = ag7xxx_eth_send,
 932        .recv                   = ag7xxx_eth_recv,
 933        .free_pkt               = ag7xxx_eth_free_pkt,
 934        .stop                   = ag7xxx_eth_stop,
 935        .write_hwaddr           = ag7xxx_eth_write_hwaddr,
 936};
 937
 938static int ag7xxx_eth_ofdata_to_platdata(struct udevice *dev)
 939{
 940        struct eth_pdata *pdata = dev_get_platdata(dev);
 941        const char *phy_mode;
 942        int ret;
 943
 944        pdata->iobase = dev_get_addr(dev);
 945        pdata->phy_interface = -1;
 946
 947        /* Decoding of convoluted PHY wiring on Atheros MIPS. */
 948        ret = ag7xxx_get_phy_iface_offset(dev);
 949        if (ret <= 0)
 950                return ret;
 951
 952        phy_mode = fdt_getprop(gd->fdt_blob, ret, "phy-mode", NULL);
 953        if (phy_mode)
 954                pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 955        if (pdata->phy_interface == -1) {
 956                debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
 957                return -EINVAL;
 958        }
 959
 960        return 0;
 961}
 962
 963static const struct udevice_id ag7xxx_eth_ids[] = {
 964        { .compatible = "qca,ag933x-mac", .data = AG7XXX_MODEL_AG933X },
 965        { .compatible = "qca,ag934x-mac", .data = AG7XXX_MODEL_AG934X },
 966        { }
 967};
 968
 969U_BOOT_DRIVER(eth_ag7xxx) = {
 970        .name           = "eth_ag7xxx",
 971        .id             = UCLASS_ETH,
 972        .of_match       = ag7xxx_eth_ids,
 973        .ofdata_to_platdata = ag7xxx_eth_ofdata_to_platdata,
 974        .probe          = ag7xxx_eth_probe,
 975        .remove         = ag7xxx_eth_remove,
 976        .ops            = &ag7xxx_eth_ops,
 977        .priv_auto_alloc_size = sizeof(struct ar7xxx_eth_priv),
 978        .platdata_auto_alloc_size = sizeof(struct eth_pdata),
 979        .flags          = DM_FLAG_ALLOC_PRIV_DMA,
 980};
 981