uboot/drivers/net/ksz9477.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2020
   4 * Tim Harvey, Gateworks Corporation
   5 */
   6
   7#include <dm.h>
   8#include <dm/device_compat.h>
   9#include <dm/device-internal.h>
  10#include <dm/lists.h>
  11#include <eth_phy.h>
  12#include <linux/delay.h>
  13#include <miiphy.h>
  14#include <i2c.h>
  15#include <net/dsa.h>
  16
  17#include <asm-generic/gpio.h>
  18
  19/* Global registers */
  20
  21/* Chip ID */
  22#define REG_CHIP_ID0__1                 0x0000
  23
  24/* Operation control */
  25#define REG_SW_OPERATION                0x0300
  26#define SW_RESET                        BIT(1)
  27#define SW_START                        BIT(0)
  28
  29/* Port Specific Registers */
  30#define PORT_CTRL_ADDR(port, addr) ((addr) | (((port) + 1) << 12))
  31
  32/* Port Control */
  33#define REG_PORT_XMII_CTRL_1            0x0301
  34#define PORT_MII_NOT_1GBIT              BIT(6)
  35#define PORT_MII_SEL_EDGE               BIT(5)
  36#define PORT_RGMII_ID_IG_ENABLE         BIT(4)
  37#define PORT_RGMII_ID_EG_ENABLE         BIT(3)
  38#define PORT_MII_MAC_MODE               BIT(2)
  39#define PORT_MII_SEL_M                  0x3
  40#define PORT_RGMII_SEL                  0x0
  41#define PORT_RMII_SEL                   0x1
  42#define PORT_GMII_SEL                   0x2
  43#define PORT_MII_SEL                    0x3
  44
  45/* Port MSTP State Register */
  46#define REG_PORT_MSTP_STATE             0x0b04
  47#define PORT_TX_ENABLE                  BIT(2)
  48#define PORT_RX_ENABLE                  BIT(1)
  49#define PORT_LEARN_DISABLE              BIT(0)
  50
  51/* MMD */
  52#define REG_PORT_PHY_MMD_SETUP          0x011A
  53#define PORT_MMD_OP_MODE_M              0x3
  54#define PORT_MMD_OP_MODE_S              14
  55#define PORT_MMD_OP_INDEX               0
  56#define PORT_MMD_OP_DATA_NO_INCR        1
  57#define PORT_MMD_OP_DATA_INCR_RW        2
  58#define PORT_MMD_OP_DATA_INCR_W         3
  59#define PORT_MMD_DEVICE_ID_M            0x1F
  60#define MMD_SETUP(mode, dev)            (((u16)(mode) << PORT_MMD_OP_MODE_S) | (dev))
  61#define REG_PORT_PHY_MMD_INDEX_DATA     0x011C
  62
  63struct ksz_dsa_priv {
  64        struct udevice *dev;
  65        int active_port;
  66};
  67
  68static inline int ksz_read8(struct udevice *dev, u32 reg, u8 *val)
  69{
  70        int ret = dm_i2c_read(dev, reg, val, 1);
  71
  72        dev_dbg(dev, "%s 0x%04x<<0x%02x\n", __func__, reg, *val);
  73
  74        return ret;
  75}
  76
  77static inline int ksz_pread8(struct udevice *dev, int port, int reg, u8 *val)
  78{
  79        return ksz_read8(dev, PORT_CTRL_ADDR(port, reg), val);
  80}
  81
  82static inline int ksz_write8(struct udevice *dev, u32 reg, u8 val)
  83{
  84        dev_dbg(dev, "%s 0x%04x>>0x%02x\n", __func__, reg, val);
  85        return dm_i2c_write(dev, reg, &val, 1);
  86}
  87
  88static inline int ksz_pwrite8(struct udevice *dev, int port, int reg, u8 val)
  89{
  90        return ksz_write8(dev, PORT_CTRL_ADDR(port, reg), val);
  91}
  92
  93static inline int ksz_write16(struct udevice *dev, u32 reg, u16 val)
  94{
  95        u8 buf[2];
  96
  97        buf[1] = val & 0xff;
  98        buf[0] = val >> 8;
  99        dev_dbg(dev, "%s 0x%04x>>0x%04x\n", __func__, reg, val);
 100
 101        return dm_i2c_write(dev, reg, buf, 2);
 102}
 103
 104static inline int ksz_pwrite16(struct udevice *dev, int port, int reg, u16 val)
 105{
 106        return ksz_write16(dev, PORT_CTRL_ADDR(port, reg), val);
 107}
 108
 109static inline int ksz_read16(struct udevice *dev, u32 reg, u16 *val)
 110{
 111        u8 buf[2];
 112        int ret;
 113
 114        ret = dm_i2c_read(dev, reg, buf, 2);
 115        *val = (buf[0] << 8) | buf[1];
 116        dev_dbg(dev, "%s 0x%04x<<0x%04x\n", __func__, reg, *val);
 117
 118        return ret;
 119}
 120
 121static inline int ksz_pread16(struct udevice *dev, int port, int reg, u16 *val)
 122{
 123        return ksz_read16(dev, PORT_CTRL_ADDR(port, reg), val);
 124}
 125
 126static inline int ksz_read32(struct udevice *dev, u32 reg, u32 *val)
 127{
 128        return dm_i2c_read(dev, reg, (u8 *)val, 4);
 129}
 130
 131static inline int ksz_pread32(struct udevice *dev, int port, int reg, u32 *val)
 132{
 133        return ksz_read32(dev, PORT_CTRL_ADDR(port, reg), val);
 134}
 135
 136static inline int ksz_write32(struct udevice *dev, u32 reg, u32 val)
 137{
 138        u8 buf[4];
 139
 140        buf[3] = val & 0xff;
 141        buf[2] = (val >> 24) & 0xff;
 142        buf[1] = (val >> 16) & 0xff;
 143        buf[0] = (val >> 8) & 0xff;
 144        dev_dbg(dev, "%s 0x%04x>>0x%04x\n", __func__, reg, val);
 145
 146        return dm_i2c_write(dev, reg, buf, 4);
 147}
 148
 149static inline int ksz_pwrite32(struct udevice *dev, int port, int reg, u32 val)
 150{
 151        return ksz_write32(dev, PORT_CTRL_ADDR(port, reg), val);
 152}
 153
 154static __maybe_unused void ksz_port_mmd_read(struct udevice *dev, int port,
 155                                             u8 addr, u16 reg, u16 *val)
 156{
 157        ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_INDEX, addr));
 158        ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, reg);
 159        ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_DATA_NO_INCR, addr));
 160        ksz_pread16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, val);
 161        dev_dbg(dev, "%s  P%d 0x%02x:0x%04x<<0x%04x\n", __func__, port + 1, addr, reg, *val);
 162}
 163
 164static void ksz_port_mmd_write(struct udevice *dev, int port, u8 addr, u16 reg, u16 val)
 165{
 166        dev_dbg(dev, "%s P%d 0x%02x:0x%04x>>0x%04x\n", __func__, port + 1, addr, addr, val);
 167        ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_INDEX, addr));
 168        ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, addr);
 169        ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_DATA_NO_INCR, addr));
 170        ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, val);
 171}
 172
 173/* Apply PHY settings to address errata listed in KSZ9477, KSZ9897, KSZ9896, KSZ9567
 174 * Silicon Errata and Data Sheet Clarification documents
 175 */
 176static void ksz_phy_errata_setup(struct udevice *dev, int port)
 177{
 178        dev_dbg(dev, "%s P%d\n", __func__, port + 1);
 179
 180        /* Register settings are needed to improve PHY receive performance */
 181        ksz_port_mmd_write(dev, port, 0x01, 0x6f, 0xdd0b);
 182        ksz_port_mmd_write(dev, port, 0x01, 0x8f, 0x6032);
 183        ksz_port_mmd_write(dev, port, 0x01, 0x9d, 0x248c);
 184        ksz_port_mmd_write(dev, port, 0x01, 0x75, 0x0060);
 185        ksz_port_mmd_write(dev, port, 0x01, 0xd3, 0x7777);
 186        ksz_port_mmd_write(dev, port, 0x1c, 0x06, 0x3008);
 187        ksz_port_mmd_write(dev, port, 0x1c, 0x08, 0x2001);
 188
 189        /* Transmit waveform amplitude can be improved (1000BASE-T, 100BASE-TX, 10BASE-Te) */
 190        ksz_port_mmd_write(dev, port, 0x1c, 0x04, 0x00d0);
 191
 192        /* Energy Efficient Ethernet (EEE) feature select must be manually disabled */
 193        ksz_port_mmd_write(dev, port, 0x07, 0x3c, 0x0000);
 194
 195        /* Register settings are required to meet data sheet supply current specifications */
 196        ksz_port_mmd_write(dev, port, 0x1c, 0x13, 0x6eff);
 197        ksz_port_mmd_write(dev, port, 0x1c, 0x14, 0xe6ff);
 198        ksz_port_mmd_write(dev, port, 0x1c, 0x15, 0x6eff);
 199        ksz_port_mmd_write(dev, port, 0x1c, 0x16, 0xe6ff);
 200        ksz_port_mmd_write(dev, port, 0x1c, 0x17, 0x00ff);
 201        ksz_port_mmd_write(dev, port, 0x1c, 0x18, 0x43ff);
 202        ksz_port_mmd_write(dev, port, 0x1c, 0x19, 0xc3ff);
 203        ksz_port_mmd_write(dev, port, 0x1c, 0x1a, 0x6fff);
 204        ksz_port_mmd_write(dev, port, 0x1c, 0x1b, 0x07ff);
 205        ksz_port_mmd_write(dev, port, 0x1c, 0x1c, 0x0fff);
 206        ksz_port_mmd_write(dev, port, 0x1c, 0x1d, 0xe7ff);
 207        ksz_port_mmd_write(dev, port, 0x1c, 0x1e, 0xefff);
 208        ksz_port_mmd_write(dev, port, 0x1c, 0x20, 0xeeee);
 209}
 210
 211/*
 212 * mii bus driver
 213 */
 214#define KSZ_MDIO_CHILD_DRV_NAME "ksz_mdio"
 215
 216struct ksz_mdio_priv {
 217        struct ksz_dsa_priv *ksz;
 218};
 219
 220static int dm_ksz_mdio_read(struct udevice *dev, int addr, int devad, int reg)
 221{
 222        struct ksz_mdio_priv *priv = dev_get_priv(dev);
 223        struct ksz_dsa_priv *ksz = priv->ksz;
 224        u16 val = 0xffff;
 225
 226        ksz_pread16(ksz->dev, addr, 0x100 + (reg << 1), &val);
 227        dev_dbg(ksz->dev, "%s P%d reg=0x%04x:0x%04x<<0x%04x\n", __func__,
 228                addr + 1, reg, 0x100 + (reg << 1), val);
 229
 230        return val;
 231};
 232
 233static int dm_ksz_mdio_write(struct udevice *dev, int addr, int devad, int reg, u16 val)
 234{
 235        struct ksz_mdio_priv *priv = dev_get_priv(dev);
 236        struct ksz_dsa_priv *ksz = priv->ksz;
 237
 238        dev_dbg(ksz->dev, "%s P%d reg=0x%04x:%04x>>0x%04x\n",
 239                __func__, addr + 1, reg, 0x100 + (reg << 1), val);
 240        ksz_pwrite16(ksz->dev, addr, 0x100 + (reg << 1), val);
 241
 242        return 0;
 243}
 244
 245static const struct mdio_ops ksz_mdio_ops = {
 246        .read = dm_ksz_mdio_read,
 247        .write = dm_ksz_mdio_write,
 248};
 249
 250static int ksz_mdio_bind(struct udevice *dev)
 251{
 252        char name[16];
 253        static int num_devices;
 254
 255        dev_dbg(dev, "%s\n", __func__);
 256        sprintf(name, "ksz-mdio-%d", num_devices++);
 257        device_set_name(dev, name);
 258
 259        return 0;
 260}
 261
 262static int ksz_mdio_probe(struct udevice *dev)
 263{
 264        struct ksz_mdio_priv *priv = dev_get_priv(dev);
 265
 266        dev_dbg(dev, "%s\n", __func__);
 267        priv->ksz = dev_get_parent_priv(dev->parent);
 268
 269        return 0;
 270}
 271
 272static const struct udevice_id ksz_mdio_ids[] = {
 273        { .compatible = "microchip,ksz-mdio" },
 274        { }
 275};
 276
 277U_BOOT_DRIVER(ksz_mdio) = {
 278        .name           = KSZ_MDIO_CHILD_DRV_NAME,
 279        .id             = UCLASS_MDIO,
 280        .of_match       = ksz_mdio_ids,
 281        .bind           = ksz_mdio_bind,
 282        .probe          = ksz_mdio_probe,
 283        .ops            = &ksz_mdio_ops,
 284        .priv_auto      = sizeof(struct ksz_mdio_priv),
 285        .plat_auto      = sizeof(struct mdio_perdev_priv),
 286};
 287
 288static int ksz_port_setup(struct udevice *dev, int port,
 289                          phy_interface_t interface)
 290{
 291        struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
 292        u8 data8;
 293
 294        dev_dbg(dev, "%s P%d %s\n", __func__, port + 1,
 295                (port == pdata->cpu_port) ? "cpu" : "");
 296
 297        if (port != pdata->cpu_port) {
 298                /* phy port: config errata and leds */
 299                ksz_phy_errata_setup(dev, port);
 300        } else {
 301                /* cpu port: configure MAC interface mode */
 302                ksz_pread8(dev, port, REG_PORT_XMII_CTRL_1, &data8);
 303                dev_dbg(dev, "%s P%d cpu interface %s\n", __func__, port + 1,
 304                        phy_string_for_interface(interface));
 305                switch (interface) {
 306                case PHY_INTERFACE_MODE_MII:
 307                        data8 &= ~PORT_MII_SEL_M;
 308                        data8 |= PORT_MII_SEL;
 309                        data8 |= PORT_MII_NOT_1GBIT;
 310                        break;
 311                case PHY_INTERFACE_MODE_RMII:
 312                        data8 &= ~PORT_MII_SEL_M;
 313                        data8 |= PORT_RMII_SEL;
 314                        data8 |= PORT_MII_NOT_1GBIT;
 315                        break;
 316                case PHY_INTERFACE_MODE_GMII:
 317                        data8 &= ~PORT_MII_SEL_M;
 318                        data8 |= PORT_GMII_SEL;
 319                        data8 &= ~PORT_MII_NOT_1GBIT;
 320                        break;
 321                default:
 322                        data8 &= ~PORT_MII_SEL_M;
 323                        data8 |= PORT_RGMII_SEL;
 324                        data8 &= ~PORT_MII_NOT_1GBIT;
 325                        data8 &= ~PORT_RGMII_ID_IG_ENABLE;
 326                        data8 &= ~PORT_RGMII_ID_EG_ENABLE;
 327                        if (interface == PHY_INTERFACE_MODE_RGMII_ID ||
 328                            interface == PHY_INTERFACE_MODE_RGMII_RXID)
 329                                data8 |= PORT_RGMII_ID_IG_ENABLE;
 330                        if (interface == PHY_INTERFACE_MODE_RGMII_ID ||
 331                            interface == PHY_INTERFACE_MODE_RGMII_TXID)
 332                                data8 |= PORT_RGMII_ID_EG_ENABLE;
 333                        break;
 334                }
 335                ksz_write8(dev, PORT_CTRL_ADDR(port, REG_PORT_XMII_CTRL_1), data8);
 336        }
 337
 338        return 0;
 339}
 340
 341static int ksz_port_enable(struct udevice *dev, int port, struct phy_device *phy)
 342{
 343        struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
 344        struct ksz_dsa_priv *priv = dev_get_priv(dev);
 345        int supported = PHY_GBIT_FEATURES;
 346        u8 data8;
 347        int ret;
 348
 349        dev_dbg(dev, "%s P%d 0x%x %s\n", __func__, port + 1, phy->phy_id,
 350                phy_string_for_interface(phy->interface));
 351
 352        /* setup this port */
 353        ret = ksz_port_setup(dev, port, phy->interface);
 354        if (ret) {
 355                dev_err(dev, "port setup failed: %d\n", ret);
 356                return ret;
 357        }
 358
 359        /* enable port forwarding for this port */
 360        ksz_pread8(priv->dev, port, REG_PORT_MSTP_STATE, &data8);
 361        data8 &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
 362        data8 |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
 363        ksz_pwrite8(priv->dev, port, REG_PORT_MSTP_STATE, data8);
 364
 365        /* if cpu master we are done */
 366        if (port == pdata->cpu_port)
 367                return 0;
 368
 369        /* configure phy */
 370        phy->supported &= supported;
 371        phy->advertising &= supported;
 372        ret = phy_config(phy);
 373        if (ret)
 374                return ret;
 375
 376        ret = phy_startup(phy);
 377        if (ret)
 378                return ret;
 379
 380        /* start switch */
 381        ksz_read8(priv->dev, REG_SW_OPERATION, &data8);
 382        data8 |= SW_START;
 383        ksz_write8(priv->dev, REG_SW_OPERATION, data8);
 384
 385        /* keep track of current enabled non-cpu port */
 386        priv->active_port = port;
 387
 388        return 0;
 389}
 390
 391static void ksz_port_disable(struct udevice *dev, int port, struct phy_device *phy)
 392{
 393        struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
 394        struct ksz_dsa_priv *priv = dev_get_priv(dev);
 395        u8 data8;
 396
 397        dev_dbg(dev, "%s P%d 0x%x\n", __func__, port + 1, phy->phy_id);
 398
 399        /* can't disable CPU port without re-configuring/re-starting switch */
 400        if (port == pdata->cpu_port)
 401                return;
 402
 403        /* disable port */
 404        ksz_pread8(priv->dev, port, REG_PORT_MSTP_STATE, &data8);
 405        data8 &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
 406        data8 |= PORT_LEARN_DISABLE;
 407        ksz_pwrite8(priv->dev, port, REG_PORT_MSTP_STATE, data8);
 408
 409        /*
 410         * we don't call phy_shutdown here to avoid waiting next time we use
 411         * the port, but the downside is that remote side will think we're
 412         * actively processing traffic although we are not.
 413         */
 414}
 415
 416static int ksz_xmit(struct udevice *dev, int port, void *packet, int length)
 417{
 418        dev_dbg(dev, "%s P%d %d\n", __func__, port + 1, length);
 419
 420        return 0;
 421}
 422
 423static int ksz_recv(struct udevice *dev, int *port, void *packet, int length)
 424{
 425        struct ksz_dsa_priv *priv = dev_get_priv(dev);
 426
 427        dev_dbg(dev, "%s P%d %d\n", __func__, priv->active_port + 1, length);
 428        *port = priv->active_port;
 429
 430        return 0;
 431};
 432
 433static const struct dsa_ops ksz_dsa_ops = {
 434        .port_enable = ksz_port_enable,
 435        .port_disable = ksz_port_disable,
 436        .xmit = ksz_xmit,
 437        .rcv = ksz_recv,
 438};
 439
 440static int ksz_probe_mdio(struct udevice *dev)
 441{
 442        ofnode node, mdios;
 443        int ret;
 444
 445        mdios = dev_read_subnode(dev, "mdios");
 446        if (ofnode_valid(mdios)) {
 447                ofnode_for_each_subnode(node, mdios) {
 448                        const char *name = ofnode_get_name(node);
 449                        struct udevice *pdev;
 450
 451                        ret = device_bind_driver_to_node(dev,
 452                                                         KSZ_MDIO_CHILD_DRV_NAME,
 453                                                         name, node, &pdev);
 454                        if (ret)
 455                                dev_err(dev, "failed to probe %s: %d\n", name, ret);
 456                }
 457        }
 458
 459        return 0;
 460}
 461
 462/*
 463 * I2C driver
 464 */
 465static int ksz_i2c_probe(struct udevice *dev)
 466{
 467        struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
 468        struct ksz_dsa_priv *priv = dev_get_priv(dev);
 469        struct udevice *master = dsa_get_master(dev);
 470        int i, ret;
 471        u8 data8;
 472        u32 id;
 473
 474        if (!master)
 475                return -ENODEV;
 476
 477        dev_dbg(dev, "%s %s master:%s\n", __func__, dev->name, master->name);
 478        dev_set_parent_priv(dev, priv);
 479
 480        ret = i2c_set_chip_offset_len(dev, 2);
 481        if (ret) {
 482                printf("i2c_set_chip_offset_len failed: %d\n", ret);
 483                return ret;
 484        }
 485
 486        /* default config */
 487        priv->dev = dev;
 488
 489        /* chip level reset */
 490        ksz_read8(priv->dev, REG_SW_OPERATION, &data8);
 491        data8 |= SW_RESET;
 492        ksz_write8(priv->dev, REG_SW_OPERATION, data8);
 493
 494        /* read chip id */
 495        ret = ksz_read32(dev, REG_CHIP_ID0__1, &id);
 496        if (ret)
 497                return ret;
 498        id = __swab32(id);
 499        dev_dbg(dev, "%s id=0x%08x\n", __func__, id);
 500        switch (id & 0xffffff00) {
 501        case 0x00947700:
 502                puts("KSZ9477S: ");
 503                break;
 504        case 0x00956700:
 505                puts("KSZ9567R: ");
 506                break;
 507        case 0x00989700:
 508                puts("KSZ9897S: ");
 509                break;
 510        default:
 511                dev_err(dev, "invalid chip id: 0x%08x\n", id);
 512                return -EINVAL;
 513        }
 514
 515        /* probe mdio bus */
 516        ret = ksz_probe_mdio(dev);
 517        if (ret)
 518                return ret;
 519
 520        /* disable ports by default */
 521        for (i = 0; i < pdata->num_ports; i++) {
 522                ksz_pread8(priv->dev, i, REG_PORT_MSTP_STATE, &data8);
 523                data8 &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
 524                ksz_pwrite8(priv->dev, i, REG_PORT_MSTP_STATE, data8);
 525        }
 526
 527        dsa_set_tagging(dev, 0, 0);
 528
 529        return 0;
 530};
 531
 532static const struct udevice_id ksz_i2c_ids[] = {
 533        { .compatible = "microchip,ksz9897" },
 534        { .compatible = "microchip,ksz9477" },
 535        { .compatible = "microchip,ksz9567" },
 536        { }
 537};
 538
 539U_BOOT_DRIVER(ksz) = {
 540        .name           = "ksz-switch",
 541        .id             = UCLASS_DSA,
 542        .of_match       = ksz_i2c_ids,
 543        .probe          = ksz_i2c_probe,
 544        .ops            = &ksz_dsa_ops,
 545        .priv_auto      = sizeof(struct ksz_dsa_priv),
 546};
 547