uboot/drivers/net/ti/am65-cpsw-nuss.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Texas Instruments K3 AM65 Ethernet Switch SubSystem Driver
   4 *
   5 * Copyright (C) 2019, Texas Instruments, Incorporated
   6 *
   7 */
   8
   9#include <common.h>
  10#include <malloc.h>
  11#include <asm/cache.h>
  12#include <asm/io.h>
  13#include <asm/processor.h>
  14#include <clk.h>
  15#include <dm.h>
  16#include <dm/device_compat.h>
  17#include <dm/lists.h>
  18#include <dma-uclass.h>
  19#include <dm/of_access.h>
  20#include <miiphy.h>
  21#include <net.h>
  22#include <phy.h>
  23#include <power-domain.h>
  24#include <soc.h>
  25#include <linux/bitops.h>
  26#include <linux/soc/ti/ti-udma.h>
  27
  28#include "cpsw_mdio.h"
  29
  30#define AM65_CPSW_CPSWNU_MAX_PORTS 9
  31
  32#define AM65_CPSW_SS_BASE               0x0
  33#define AM65_CPSW_SGMII_BASE    0x100
  34#define AM65_CPSW_MDIO_BASE     0xf00
  35#define AM65_CPSW_XGMII_BASE    0x2100
  36#define AM65_CPSW_CPSW_NU_BASE  0x20000
  37#define AM65_CPSW_CPSW_NU_ALE_BASE 0x1e000
  38
  39#define AM65_CPSW_CPSW_NU_PORTS_OFFSET  0x1000
  40#define AM65_CPSW_CPSW_NU_PORT_MACSL_OFFSET     0x330
  41
  42#define AM65_CPSW_MDIO_BUS_FREQ_DEF 1000000
  43
  44#define AM65_CPSW_CTL_REG                       0x4
  45#define AM65_CPSW_STAT_PORT_EN_REG      0x14
  46#define AM65_CPSW_PTYPE_REG             0x18
  47
  48#define AM65_CPSW_CTL_REG_P0_ENABLE                     BIT(2)
  49#define AM65_CPSW_CTL_REG_P0_TX_CRC_REMOVE              BIT(13)
  50#define AM65_CPSW_CTL_REG_P0_RX_PAD                     BIT(14)
  51
  52#define AM65_CPSW_P0_FLOW_ID_REG                        0x8
  53#define AM65_CPSW_PN_RX_MAXLEN_REG              0x24
  54#define AM65_CPSW_PN_REG_SA_L                   0x308
  55#define AM65_CPSW_PN_REG_SA_H                   0x30c
  56
  57#define AM65_CPSW_ALE_CTL_REG                   0x8
  58#define AM65_CPSW_ALE_CTL_REG_ENABLE            BIT(31)
  59#define AM65_CPSW_ALE_CTL_REG_RESET_TBL         BIT(30)
  60#define AM65_CPSW_ALE_CTL_REG_BYPASS            BIT(4)
  61#define AM65_CPSW_ALE_PN_CTL_REG(x)             (0x40 + (x) * 4)
  62#define AM65_CPSW_ALE_PN_CTL_REG_MODE_FORWARD   0x3
  63#define AM65_CPSW_ALE_PN_CTL_REG_MAC_ONLY       BIT(11)
  64
  65#define AM65_CPSW_ALE_THREADMAPDEF_REG          0x134
  66#define AM65_CPSW_ALE_DEFTHREAD_EN              BIT(15)
  67
  68#define AM65_CPSW_MACSL_CTL_REG                 0x0
  69#define AM65_CPSW_MACSL_CTL_REG_IFCTL_A         BIT(15)
  70#define AM65_CPSW_MACSL_CTL_EXT_EN              BIT(18)
  71#define AM65_CPSW_MACSL_CTL_REG_GIG             BIT(7)
  72#define AM65_CPSW_MACSL_CTL_REG_GMII_EN         BIT(5)
  73#define AM65_CPSW_MACSL_CTL_REG_LOOPBACK        BIT(1)
  74#define AM65_CPSW_MACSL_CTL_REG_FULL_DUPLEX     BIT(0)
  75#define AM65_CPSW_MACSL_RESET_REG               0x8
  76#define AM65_CPSW_MACSL_RESET_REG_RESET         BIT(0)
  77#define AM65_CPSW_MACSL_STATUS_REG              0x4
  78#define AM65_CPSW_MACSL_RESET_REG_PN_IDLE       BIT(31)
  79#define AM65_CPSW_MACSL_RESET_REG_PN_E_IDLE     BIT(30)
  80#define AM65_CPSW_MACSL_RESET_REG_PN_P_IDLE     BIT(29)
  81#define AM65_CPSW_MACSL_RESET_REG_PN_TX_IDLE    BIT(28)
  82#define AM65_CPSW_MACSL_RESET_REG_IDLE_MASK \
  83        (AM65_CPSW_MACSL_RESET_REG_PN_IDLE | \
  84         AM65_CPSW_MACSL_RESET_REG_PN_E_IDLE | \
  85         AM65_CPSW_MACSL_RESET_REG_PN_P_IDLE | \
  86         AM65_CPSW_MACSL_RESET_REG_PN_TX_IDLE)
  87
  88#define AM65_CPSW_CPPI_PKT_TYPE                 0x7
  89
  90struct am65_cpsw_port {
  91        fdt_addr_t      port_base;
  92        fdt_addr_t      macsl_base;
  93        bool            disabled;
  94        u32             mac_control;
  95};
  96
  97struct am65_cpsw_common {
  98        struct udevice          *dev;
  99        fdt_addr_t              ss_base;
 100        fdt_addr_t              cpsw_base;
 101        fdt_addr_t              mdio_base;
 102        fdt_addr_t              ale_base;
 103        fdt_addr_t              gmii_sel;
 104        fdt_addr_t              mac_efuse;
 105
 106        struct clk              fclk;
 107        struct power_domain     pwrdmn;
 108
 109        u32                     port_num;
 110        struct am65_cpsw_port   ports[AM65_CPSW_CPSWNU_MAX_PORTS];
 111
 112        struct mii_dev          *bus;
 113        u32                     bus_freq;
 114
 115        struct dma              dma_tx;
 116        struct dma              dma_rx;
 117        u32                     rx_next;
 118        u32                     rx_pend;
 119        bool                    started;
 120};
 121
 122struct am65_cpsw_priv {
 123        struct udevice          *dev;
 124        struct am65_cpsw_common *cpsw_common;
 125        u32                     port_id;
 126
 127        struct phy_device       *phydev;
 128        bool                    has_phy;
 129        ofnode                  phy_node;
 130        u32                     phy_addr;
 131
 132        bool                    mdio_manual_mode;
 133};
 134
 135#ifdef PKTSIZE_ALIGN
 136#define UDMA_RX_BUF_SIZE PKTSIZE_ALIGN
 137#else
 138#define UDMA_RX_BUF_SIZE ALIGN(1522, ARCH_DMA_MINALIGN)
 139#endif
 140
 141#ifdef PKTBUFSRX
 142#define UDMA_RX_DESC_NUM PKTBUFSRX
 143#else
 144#define UDMA_RX_DESC_NUM 4
 145#endif
 146
 147#define mac_hi(mac)     (((mac)[0] << 0) | ((mac)[1] << 8) |    \
 148                         ((mac)[2] << 16) | ((mac)[3] << 24))
 149#define mac_lo(mac)     (((mac)[4] << 0) | ((mac)[5] << 8))
 150
 151static void am65_cpsw_set_sl_mac(struct am65_cpsw_port *slave,
 152                                 unsigned char *addr)
 153{
 154        writel(mac_hi(addr),
 155               slave->port_base + AM65_CPSW_PN_REG_SA_H);
 156        writel(mac_lo(addr),
 157               slave->port_base + AM65_CPSW_PN_REG_SA_L);
 158}
 159
 160int am65_cpsw_macsl_reset(struct am65_cpsw_port *slave)
 161{
 162        u32 i = 100;
 163
 164        /* Set the soft reset bit */
 165        writel(AM65_CPSW_MACSL_RESET_REG_RESET,
 166               slave->macsl_base + AM65_CPSW_MACSL_RESET_REG);
 167
 168        while ((readl(slave->macsl_base + AM65_CPSW_MACSL_RESET_REG) &
 169                AM65_CPSW_MACSL_RESET_REG_RESET) && i--)
 170                cpu_relax();
 171
 172        /* Timeout on the reset */
 173        return i;
 174}
 175
 176static int am65_cpsw_macsl_wait_for_idle(struct am65_cpsw_port *slave)
 177{
 178        u32 i = 100;
 179
 180        while ((readl(slave->macsl_base + AM65_CPSW_MACSL_STATUS_REG) &
 181                AM65_CPSW_MACSL_RESET_REG_IDLE_MASK) && i--)
 182                cpu_relax();
 183
 184        return i;
 185}
 186
 187static int am65_cpsw_update_link(struct am65_cpsw_priv *priv)
 188{
 189        struct am65_cpsw_common *common = priv->cpsw_common;
 190        struct am65_cpsw_port *port = &common->ports[priv->port_id];
 191        struct phy_device *phy = priv->phydev;
 192        u32 mac_control = 0;
 193
 194        if (phy->link) { /* link up */
 195                mac_control = /*AM65_CPSW_MACSL_CTL_REG_LOOPBACK |*/
 196                              AM65_CPSW_MACSL_CTL_REG_GMII_EN;
 197                if (phy->speed == 1000)
 198                        mac_control |= AM65_CPSW_MACSL_CTL_REG_GIG;
 199                if (phy->speed == 10 && phy_interface_is_rgmii(phy))
 200                        /* Can be used with in band mode only */
 201                        mac_control |= AM65_CPSW_MACSL_CTL_EXT_EN;
 202                if (phy->duplex == DUPLEX_FULL)
 203                        mac_control |= AM65_CPSW_MACSL_CTL_REG_FULL_DUPLEX;
 204                if (phy->speed == 100)
 205                        mac_control |= AM65_CPSW_MACSL_CTL_REG_IFCTL_A;
 206        }
 207
 208        if (mac_control == port->mac_control)
 209                goto out;
 210
 211        if (mac_control) {
 212                printf("link up on port %d, speed %d, %s duplex\n",
 213                       priv->port_id, phy->speed,
 214                       (phy->duplex == DUPLEX_FULL) ? "full" : "half");
 215        } else {
 216                printf("link down on port %d\n", priv->port_id);
 217        }
 218
 219        writel(mac_control, port->macsl_base + AM65_CPSW_MACSL_CTL_REG);
 220        port->mac_control = mac_control;
 221
 222out:
 223        return phy->link;
 224}
 225
 226#define AM65_GMII_SEL_MODE_MII          0
 227#define AM65_GMII_SEL_MODE_RMII         1
 228#define AM65_GMII_SEL_MODE_RGMII        2
 229
 230#define AM65_GMII_SEL_RGMII_IDMODE      BIT(4)
 231
 232static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
 233                                  phy_interface_t phy_mode, int slave)
 234{
 235        struct am65_cpsw_common *common = priv->cpsw_common;
 236        u32 reg;
 237        u32 mode = 0;
 238        bool rgmii_id = false;
 239
 240        reg = readl(common->gmii_sel);
 241
 242        dev_dbg(common->dev, "old gmii_sel: %08x\n", reg);
 243
 244        switch (phy_mode) {
 245        case PHY_INTERFACE_MODE_RMII:
 246                mode = AM65_GMII_SEL_MODE_RMII;
 247                break;
 248
 249        case PHY_INTERFACE_MODE_RGMII:
 250        case PHY_INTERFACE_MODE_RGMII_RXID:
 251                mode = AM65_GMII_SEL_MODE_RGMII;
 252                break;
 253
 254        case PHY_INTERFACE_MODE_RGMII_ID:
 255        case PHY_INTERFACE_MODE_RGMII_TXID:
 256                mode = AM65_GMII_SEL_MODE_RGMII;
 257                rgmii_id = true;
 258                break;
 259
 260        default:
 261                dev_warn(common->dev,
 262                         "Unsupported PHY mode: %u. Defaulting to MII.\n",
 263                         phy_mode);
 264                /* fallthrough */
 265        case PHY_INTERFACE_MODE_MII:
 266                mode = AM65_GMII_SEL_MODE_MII;
 267                break;
 268        };
 269
 270        if (rgmii_id)
 271                mode |= AM65_GMII_SEL_RGMII_IDMODE;
 272
 273        reg = mode;
 274        dev_dbg(common->dev, "gmii_sel PHY mode: %u, new gmii_sel: %08x\n",
 275                phy_mode, reg);
 276        writel(reg, common->gmii_sel);
 277
 278        reg = readl(common->gmii_sel);
 279        if (reg != mode)
 280                dev_err(common->dev,
 281                        "gmii_sel PHY mode NOT SET!: requested: %08x, gmii_sel: %08x\n",
 282                        mode, reg);
 283}
 284
 285static int am65_cpsw_start(struct udevice *dev)
 286{
 287        struct eth_pdata *pdata = dev_get_plat(dev);
 288        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 289        struct am65_cpsw_common *common = priv->cpsw_common;
 290        struct am65_cpsw_port *port = &common->ports[priv->port_id];
 291        struct am65_cpsw_port *port0 = &common->ports[0];
 292        struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
 293        int ret, i;
 294
 295        ret = power_domain_on(&common->pwrdmn);
 296        if (ret) {
 297                dev_err(dev, "power_domain_on() failed %d\n", ret);
 298                goto out;
 299        }
 300
 301        ret = clk_enable(&common->fclk);
 302        if (ret) {
 303                dev_err(dev, "clk enabled failed %d\n", ret);
 304                goto err_off_pwrdm;
 305        }
 306
 307        common->rx_next = 0;
 308        common->rx_pend = 0;
 309        ret = dma_get_by_name(common->dev, "tx0", &common->dma_tx);
 310        if (ret) {
 311                dev_err(dev, "TX dma get failed %d\n", ret);
 312                goto err_off_clk;
 313        }
 314        ret = dma_get_by_name(common->dev, "rx", &common->dma_rx);
 315        if (ret) {
 316                dev_err(dev, "RX dma get failed %d\n", ret);
 317                goto err_free_tx;
 318        }
 319
 320        for (i = 0; i < UDMA_RX_DESC_NUM; i++) {
 321                ret = dma_prepare_rcv_buf(&common->dma_rx,
 322                                          net_rx_packets[i],
 323                                          UDMA_RX_BUF_SIZE);
 324                if (ret) {
 325                        dev_err(dev, "RX dma add buf failed %d\n", ret);
 326                        goto err_free_tx;
 327                }
 328        }
 329
 330        ret = dma_enable(&common->dma_tx);
 331        if (ret) {
 332                dev_err(dev, "TX dma_enable failed %d\n", ret);
 333                goto err_free_rx;
 334        }
 335        ret = dma_enable(&common->dma_rx);
 336        if (ret) {
 337                dev_err(dev, "RX dma_enable failed %d\n", ret);
 338                goto err_dis_tx;
 339        }
 340
 341        /* Control register */
 342        writel(AM65_CPSW_CTL_REG_P0_ENABLE |
 343               AM65_CPSW_CTL_REG_P0_TX_CRC_REMOVE |
 344               AM65_CPSW_CTL_REG_P0_RX_PAD,
 345               common->cpsw_base + AM65_CPSW_CTL_REG);
 346
 347        /* disable priority elevation */
 348        writel(0, common->cpsw_base + AM65_CPSW_PTYPE_REG);
 349
 350        /* enable statistics */
 351        writel(BIT(0) | BIT(priv->port_id),
 352               common->cpsw_base + AM65_CPSW_STAT_PORT_EN_REG);
 353
 354        /* Port 0  length register */
 355        writel(PKTSIZE_ALIGN, port0->port_base + AM65_CPSW_PN_RX_MAXLEN_REG);
 356
 357        /* set base flow_id */
 358        dma_get_cfg(&common->dma_rx, 0, (void **)&dma_rx_cfg_data);
 359        writel(dma_rx_cfg_data->flow_id_base,
 360               port0->port_base + AM65_CPSW_P0_FLOW_ID_REG);
 361        dev_info(dev, "K3 CPSW: rflow_id_base: %u\n",
 362                 dma_rx_cfg_data->flow_id_base);
 363
 364        /* Reset and enable the ALE */
 365        writel(AM65_CPSW_ALE_CTL_REG_ENABLE | AM65_CPSW_ALE_CTL_REG_RESET_TBL |
 366               AM65_CPSW_ALE_CTL_REG_BYPASS,
 367               common->ale_base + AM65_CPSW_ALE_CTL_REG);
 368
 369        /* port 0 put into forward mode */
 370        writel(AM65_CPSW_ALE_PN_CTL_REG_MODE_FORWARD,
 371               common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(0));
 372
 373        writel(AM65_CPSW_ALE_DEFTHREAD_EN,
 374               common->ale_base + AM65_CPSW_ALE_THREADMAPDEF_REG);
 375
 376        /* PORT x configuration */
 377
 378        /* Port x Max length register */
 379        writel(PKTSIZE_ALIGN, port->port_base + AM65_CPSW_PN_RX_MAXLEN_REG);
 380
 381        /* Port x set mac */
 382        am65_cpsw_set_sl_mac(port, pdata->enetaddr);
 383
 384        /* Port x ALE: mac_only, Forwarding */
 385        writel(AM65_CPSW_ALE_PN_CTL_REG_MAC_ONLY |
 386               AM65_CPSW_ALE_PN_CTL_REG_MODE_FORWARD,
 387               common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(priv->port_id));
 388
 389        port->mac_control = 0;
 390        if (!am65_cpsw_macsl_reset(port)) {
 391                dev_err(dev, "mac_sl reset failed\n");
 392                ret = -EFAULT;
 393                goto err_dis_rx;
 394        }
 395
 396        ret = phy_startup(priv->phydev);
 397        if (ret) {
 398                dev_err(dev, "phy_startup failed\n");
 399                goto err_dis_rx;
 400        }
 401
 402        ret = am65_cpsw_update_link(priv);
 403        if (!ret) {
 404                ret = -ENODEV;
 405                goto err_phy_shutdown;
 406        }
 407
 408        common->started = true;
 409
 410        return 0;
 411
 412err_phy_shutdown:
 413        phy_shutdown(priv->phydev);
 414err_dis_rx:
 415        /* disable ports */
 416        writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(priv->port_id));
 417        writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(0));
 418        if (!am65_cpsw_macsl_wait_for_idle(port))
 419                dev_err(dev, "mac_sl idle timeout\n");
 420        writel(0, port->macsl_base + AM65_CPSW_MACSL_CTL_REG);
 421        writel(0, common->ale_base + AM65_CPSW_ALE_CTL_REG);
 422        writel(0, common->cpsw_base + AM65_CPSW_CTL_REG);
 423
 424        dma_disable(&common->dma_rx);
 425err_dis_tx:
 426        dma_disable(&common->dma_tx);
 427err_free_rx:
 428        dma_free(&common->dma_rx);
 429err_free_tx:
 430        dma_free(&common->dma_tx);
 431err_off_clk:
 432        clk_disable(&common->fclk);
 433err_off_pwrdm:
 434        power_domain_off(&common->pwrdmn);
 435out:
 436        dev_err(dev, "%s end error\n", __func__);
 437
 438        return ret;
 439}
 440
 441static int am65_cpsw_send(struct udevice *dev, void *packet, int length)
 442{
 443        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 444        struct am65_cpsw_common *common = priv->cpsw_common;
 445        struct ti_udma_drv_packet_data packet_data;
 446        int ret;
 447
 448        packet_data.pkt_type = AM65_CPSW_CPPI_PKT_TYPE;
 449        packet_data.dest_tag = priv->port_id;
 450        ret = dma_send(&common->dma_tx, packet, length, &packet_data);
 451        if (ret) {
 452                dev_err(dev, "TX dma_send failed %d\n", ret);
 453                return ret;
 454        }
 455
 456        return 0;
 457}
 458
 459static int am65_cpsw_recv(struct udevice *dev, int flags, uchar **packetp)
 460{
 461        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 462        struct am65_cpsw_common *common = priv->cpsw_common;
 463
 464        /* try to receive a new packet */
 465        return dma_receive(&common->dma_rx, (void **)packetp, NULL);
 466}
 467
 468static int am65_cpsw_free_pkt(struct udevice *dev, uchar *packet, int length)
 469{
 470        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 471        struct am65_cpsw_common *common = priv->cpsw_common;
 472        int ret;
 473
 474        if (length > 0) {
 475                u32 pkt = common->rx_next % UDMA_RX_DESC_NUM;
 476
 477                ret = dma_prepare_rcv_buf(&common->dma_rx,
 478                                          net_rx_packets[pkt],
 479                                          UDMA_RX_BUF_SIZE);
 480                if (ret)
 481                        dev_err(dev, "RX dma free_pkt failed %d\n", ret);
 482                common->rx_next++;
 483        }
 484
 485        return 0;
 486}
 487
 488static void am65_cpsw_stop(struct udevice *dev)
 489{
 490        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 491        struct am65_cpsw_common *common = priv->cpsw_common;
 492        struct am65_cpsw_port *port = &common->ports[priv->port_id];
 493
 494        if (!common->started)
 495                return;
 496
 497        phy_shutdown(priv->phydev);
 498
 499        writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(priv->port_id));
 500        writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(0));
 501        if (!am65_cpsw_macsl_wait_for_idle(port))
 502                dev_err(dev, "mac_sl idle timeout\n");
 503        writel(0, port->macsl_base + AM65_CPSW_MACSL_CTL_REG);
 504        writel(0, common->ale_base + AM65_CPSW_ALE_CTL_REG);
 505        writel(0, common->cpsw_base + AM65_CPSW_CTL_REG);
 506
 507        dma_disable(&common->dma_tx);
 508        dma_free(&common->dma_tx);
 509
 510        dma_disable(&common->dma_rx);
 511        dma_free(&common->dma_rx);
 512
 513        common->started = false;
 514}
 515
 516static int am65_cpsw_read_rom_hwaddr(struct udevice *dev)
 517{
 518        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 519        struct am65_cpsw_common *common = priv->cpsw_common;
 520        struct eth_pdata *pdata = dev_get_plat(dev);
 521        u32 mac_hi, mac_lo;
 522
 523        if (common->mac_efuse == FDT_ADDR_T_NONE)
 524                return -1;
 525
 526        mac_lo = readl(common->mac_efuse);
 527        mac_hi = readl(common->mac_efuse + 4);
 528        pdata->enetaddr[0] = (mac_hi >> 8) & 0xff;
 529        pdata->enetaddr[1] = mac_hi & 0xff;
 530        pdata->enetaddr[2] = (mac_lo >> 24) & 0xff;
 531        pdata->enetaddr[3] = (mac_lo >> 16) & 0xff;
 532        pdata->enetaddr[4] = (mac_lo >> 8) & 0xff;
 533        pdata->enetaddr[5] = mac_lo & 0xff;
 534
 535        return 0;
 536}
 537
 538static const struct eth_ops am65_cpsw_ops = {
 539        .start          = am65_cpsw_start,
 540        .send           = am65_cpsw_send,
 541        .recv           = am65_cpsw_recv,
 542        .free_pkt       = am65_cpsw_free_pkt,
 543        .stop           = am65_cpsw_stop,
 544        .read_rom_hwaddr = am65_cpsw_read_rom_hwaddr,
 545};
 546
 547static const struct soc_attr k3_mdio_soc_data[] = {
 548        { .family = "AM62X", .revision = "SR1.0" },
 549        { .family = "AM64X", .revision = "SR1.0" },
 550        { .family = "AM64X", .revision = "SR2.0" },
 551        { .family = "AM65X", .revision = "SR1.0" },
 552        { .family = "AM65X", .revision = "SR2.0" },
 553        { .family = "J7200", .revision = "SR1.0" },
 554        { .family = "J7200", .revision = "SR2.0" },
 555        { .family = "J721E", .revision = "SR1.0" },
 556        { .family = "J721E", .revision = "SR1.1" },
 557        { .family = "J721S2", .revision = "SR1.0" },
 558        { /* sentinel */ },
 559};
 560
 561static int am65_cpsw_mdio_init(struct udevice *dev)
 562{
 563        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 564        struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
 565
 566        if (!priv->has_phy || cpsw_common->bus)
 567                return 0;
 568
 569        cpsw_common->bus = cpsw_mdio_init(dev->name,
 570                                          cpsw_common->mdio_base,
 571                                          cpsw_common->bus_freq,
 572                                          clk_get_rate(&cpsw_common->fclk),
 573                                          priv->mdio_manual_mode);
 574        if (!cpsw_common->bus)
 575                return -EFAULT;
 576
 577        return 0;
 578}
 579
 580static int am65_cpsw_phy_init(struct udevice *dev)
 581{
 582        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 583        struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
 584        struct eth_pdata *pdata = dev_get_plat(dev);
 585        struct phy_device *phydev;
 586        u32 supported = PHY_GBIT_FEATURES;
 587        int ret;
 588
 589        phydev = phy_connect(cpsw_common->bus,
 590                             priv->phy_addr,
 591                             priv->dev,
 592                             pdata->phy_interface);
 593
 594        if (!phydev) {
 595                dev_err(dev, "phy_connect() failed\n");
 596                return -ENODEV;
 597        }
 598
 599        phydev->supported &= supported;
 600        if (pdata->max_speed) {
 601                ret = phy_set_supported(phydev, pdata->max_speed);
 602                if (ret)
 603                        return ret;
 604        }
 605        phydev->advertising = phydev->supported;
 606
 607        if (ofnode_valid(priv->phy_node))
 608                phydev->node = priv->phy_node;
 609
 610        priv->phydev = phydev;
 611        ret = phy_config(phydev);
 612        if (ret < 0)
 613                pr_err("phy_config() failed: %d", ret);
 614
 615        return ret;
 616}
 617
 618static int am65_cpsw_ofdata_parse_phy(struct udevice *dev)
 619{
 620        struct eth_pdata *pdata = dev_get_plat(dev);
 621        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 622        struct ofnode_phandle_args out_args;
 623        int ret = 0;
 624
 625        dev_read_u32(dev, "reg", &priv->port_id);
 626
 627        pdata->phy_interface = dev_read_phy_mode(dev);
 628        if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
 629                dev_err(dev, "Invalid PHY mode, port %u\n", priv->port_id);
 630                return -EINVAL;
 631        }
 632
 633        dev_read_u32(dev, "max-speed", (u32 *)&pdata->max_speed);
 634        if (pdata->max_speed)
 635                dev_err(dev, "Port %u speed froced to %uMbit\n",
 636                        priv->port_id, pdata->max_speed);
 637
 638        priv->has_phy  = true;
 639        ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "phy-handle",
 640                                             NULL, 0, 0, &out_args);
 641        if (ret) {
 642                dev_err(dev, "can't parse phy-handle port %u (%d)\n",
 643                        priv->port_id, ret);
 644                priv->has_phy  = false;
 645                ret = 0;
 646        }
 647
 648        priv->phy_node = out_args.node;
 649        if (priv->has_phy) {
 650                ret = ofnode_read_u32(priv->phy_node, "reg", &priv->phy_addr);
 651                if (ret) {
 652                        dev_err(dev, "failed to get phy_addr port %u (%d)\n",
 653                                priv->port_id, ret);
 654                        goto out;
 655                }
 656        }
 657
 658out:
 659        return ret;
 660}
 661
 662static int am65_cpsw_port_probe(struct udevice *dev)
 663{
 664        struct am65_cpsw_priv *priv = dev_get_priv(dev);
 665        struct eth_pdata *pdata = dev_get_plat(dev);
 666        struct am65_cpsw_common *cpsw_common;
 667        char portname[15];
 668        int ret;
 669
 670        priv->dev = dev;
 671
 672        cpsw_common = dev_get_priv(dev->parent);
 673        priv->cpsw_common = cpsw_common;
 674
 675        sprintf(portname, "%s%s", dev->parent->name, dev->name);
 676        device_set_name(dev, portname);
 677
 678        priv->mdio_manual_mode = false;
 679        if (soc_device_match(k3_mdio_soc_data))
 680                priv->mdio_manual_mode = true;
 681
 682        ret = am65_cpsw_ofdata_parse_phy(dev);
 683        if (ret)
 684                goto out;
 685
 686        am65_cpsw_gmii_sel_k3(priv, pdata->phy_interface, priv->port_id);
 687
 688        ret = am65_cpsw_mdio_init(dev);
 689        if (ret)
 690                goto out;
 691
 692        ret = am65_cpsw_phy_init(dev);
 693        if (ret)
 694                goto out;
 695out:
 696        return ret;
 697}
 698
 699static int am65_cpsw_probe_nuss(struct udevice *dev)
 700{
 701        struct am65_cpsw_common *cpsw_common = dev_get_priv(dev);
 702        ofnode ports_np, node;
 703        int ret, i;
 704        struct udevice *port_dev;
 705
 706        cpsw_common->dev = dev;
 707        cpsw_common->ss_base = dev_read_addr(dev);
 708        if (cpsw_common->ss_base == FDT_ADDR_T_NONE)
 709                return -EINVAL;
 710        cpsw_common->mac_efuse = devfdt_get_addr_name(dev, "mac_efuse");
 711        /* no err check - optional */
 712
 713        ret = power_domain_get_by_index(dev, &cpsw_common->pwrdmn, 0);
 714        if (ret) {
 715                dev_err(dev, "failed to get pwrdmn: %d\n", ret);
 716                return ret;
 717        }
 718
 719        ret = clk_get_by_name(dev, "fck", &cpsw_common->fclk);
 720        if (ret) {
 721                power_domain_free(&cpsw_common->pwrdmn);
 722                dev_err(dev, "failed to get clock %d\n", ret);
 723                return ret;
 724        }
 725
 726        cpsw_common->cpsw_base = cpsw_common->ss_base + AM65_CPSW_CPSW_NU_BASE;
 727        cpsw_common->ale_base = cpsw_common->cpsw_base +
 728                                AM65_CPSW_CPSW_NU_ALE_BASE;
 729        cpsw_common->mdio_base = cpsw_common->ss_base + AM65_CPSW_MDIO_BASE;
 730
 731        ports_np = dev_read_subnode(dev, "ethernet-ports");
 732        if (!ofnode_valid(ports_np)) {
 733                ret = -ENOENT;
 734                goto out;
 735        }
 736
 737        ofnode_for_each_subnode(node, ports_np) {
 738                const char *node_name;
 739                u32 port_id;
 740                bool disabled;
 741
 742                node_name = ofnode_get_name(node);
 743
 744                disabled = !ofnode_is_enabled(node);
 745
 746                ret = ofnode_read_u32(node, "reg", &port_id);
 747                if (ret) {
 748                        dev_err(dev, "%s: failed to get port_id (%d)\n",
 749                                node_name, ret);
 750                        goto out;
 751                }
 752
 753                if (port_id >= AM65_CPSW_CPSWNU_MAX_PORTS) {
 754                        dev_err(dev, "%s: invalid port_id (%d)\n",
 755                                node_name, port_id);
 756                        ret = -EINVAL;
 757                        goto out;
 758                }
 759                cpsw_common->port_num++;
 760
 761                if (!port_id)
 762                        continue;
 763
 764                cpsw_common->ports[port_id].disabled = disabled;
 765                if (disabled)
 766                        continue;
 767
 768                ret = device_bind_driver_to_node(dev, "am65_cpsw_nuss_port", ofnode_get_name(node), node, &port_dev);
 769                if (ret)
 770                        dev_err(dev, "Failed to bind to %s node\n", ofnode_get_name(node));
 771        }
 772
 773        for (i = 0; i < AM65_CPSW_CPSWNU_MAX_PORTS; i++) {
 774                struct am65_cpsw_port *port = &cpsw_common->ports[i];
 775
 776                port->port_base = cpsw_common->cpsw_base +
 777                                  AM65_CPSW_CPSW_NU_PORTS_OFFSET +
 778                                  (i * AM65_CPSW_CPSW_NU_PORTS_OFFSET);
 779                port->macsl_base = port->port_base +
 780                                   AM65_CPSW_CPSW_NU_PORT_MACSL_OFFSET;
 781        }
 782
 783        node = dev_read_subnode(dev, "cpsw-phy-sel");
 784        if (!ofnode_valid(node)) {
 785                dev_err(dev, "can't find cpsw-phy-sel\n");
 786                ret = -ENOENT;
 787                goto out;
 788        }
 789
 790        cpsw_common->gmii_sel = ofnode_get_addr(node);
 791        if (cpsw_common->gmii_sel == FDT_ADDR_T_NONE) {
 792                dev_err(dev, "failed to get gmii_sel base\n");
 793                goto out;
 794        }
 795
 796        cpsw_common->bus_freq =
 797                        dev_read_u32_default(dev, "bus_freq",
 798                                             AM65_CPSW_MDIO_BUS_FREQ_DEF);
 799
 800        dev_info(dev, "K3 CPSW: nuss_ver: 0x%08X cpsw_ver: 0x%08X ale_ver: 0x%08X Ports:%u mdio_freq:%u\n",
 801                 readl(cpsw_common->ss_base),
 802                 readl(cpsw_common->cpsw_base),
 803                 readl(cpsw_common->ale_base),
 804                 cpsw_common->port_num,
 805                 cpsw_common->bus_freq);
 806
 807out:
 808        clk_free(&cpsw_common->fclk);
 809        power_domain_free(&cpsw_common->pwrdmn);
 810        return ret;
 811}
 812
 813static const struct udevice_id am65_cpsw_nuss_ids[] = {
 814        { .compatible = "ti,am654-cpsw-nuss" },
 815        { .compatible = "ti,j721e-cpsw-nuss" },
 816        { .compatible = "ti,am642-cpsw-nuss" },
 817        { }
 818};
 819
 820U_BOOT_DRIVER(am65_cpsw_nuss) = {
 821        .name   = "am65_cpsw_nuss",
 822        .id     = UCLASS_MISC,
 823        .of_match = am65_cpsw_nuss_ids,
 824        .probe  = am65_cpsw_probe_nuss,
 825        .priv_auto = sizeof(struct am65_cpsw_common),
 826};
 827
 828U_BOOT_DRIVER(am65_cpsw_nuss_port) = {
 829        .name   = "am65_cpsw_nuss_port",
 830        .id     = UCLASS_ETH,
 831        .probe  = am65_cpsw_port_probe,
 832        .ops    = &am65_cpsw_ops,
 833        .priv_auto      = sizeof(struct am65_cpsw_priv),
 834        .plat_auto      = sizeof(struct eth_pdata),
 835        .flags = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_OS_PREPARE,
 836};
 837