uboot/drivers/net/phy/atheros.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Atheros PHY drivers
   4 *
   5 * Copyright 2011, 2013 Freescale Semiconductor, Inc.
   6 * author Andy Fleming
   7 * Copyright (c) 2019 Michael Walle <michael@walle.cc>
   8 */
   9#include <common.h>
  10#include <phy.h>
  11#include <dm/device_compat.h>
  12#include <linux/bitfield.h>
  13#include <linux/bitops.h>
  14#include <dt-bindings/net/qca-ar803x.h>
  15
  16#define AR803x_PHY_DEBUG_ADDR_REG       0x1d
  17#define AR803x_PHY_DEBUG_DATA_REG       0x1e
  18
  19/* Debug registers */
  20#define AR803x_DEBUG_REG_0              0x0
  21#define AR803x_RGMII_RX_CLK_DLY         BIT(15)
  22
  23#define AR803x_DEBUG_REG_5              0x5
  24#define AR803x_RGMII_TX_CLK_DLY         BIT(8)
  25
  26#define AR803x_DEBUG_REG_1F             0x1f
  27#define AR803x_PLL_ON                   BIT(2)
  28#define AR803x_RGMII_1V8                BIT(3)
  29
  30/* CLK_25M register is at MMD 7, address 0x8016 */
  31#define AR803x_CLK_25M_SEL_REG          0x8016
  32
  33#define AR803x_CLK_25M_MASK             GENMASK(4, 2)
  34#define AR803x_CLK_25M_25MHZ_XTAL       0
  35#define AR803x_CLK_25M_25MHZ_DSP        1
  36#define AR803x_CLK_25M_50MHZ_PLL        2
  37#define AR803x_CLK_25M_50MHZ_DSP        3
  38#define AR803x_CLK_25M_62_5MHZ_PLL      4
  39#define AR803x_CLK_25M_62_5MHZ_DSP      5
  40#define AR803x_CLK_25M_125MHZ_PLL       6
  41#define AR803x_CLK_25M_125MHZ_DSP       7
  42#define AR8035_CLK_25M_MASK             GENMASK(4, 3)
  43
  44#define AR803x_CLK_25M_DR_MASK          GENMASK(8, 7)
  45#define AR803x_CLK_25M_DR_FULL          0
  46#define AR803x_CLK_25M_DR_HALF          1
  47#define AR803x_CLK_25M_DR_QUARTER       2
  48
  49#define AR8021_PHY_ID 0x004dd040
  50#define AR8031_PHY_ID 0x004dd074
  51#define AR8035_PHY_ID 0x004dd072
  52
  53struct ar803x_priv {
  54        int flags;
  55#define AR803x_FLAG_KEEP_PLL_ENABLED    BIT(0) /* don't turn off internal PLL */
  56#define AR803x_FLAG_RGMII_1V8           BIT(1) /* use 1.8V RGMII I/O voltage */
  57        u16 clk_25m_reg;
  58        u16 clk_25m_mask;
  59};
  60
  61static int ar803x_debug_reg_read(struct phy_device *phydev, u16 reg)
  62{
  63        int ret;
  64
  65        ret = phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
  66                        reg);
  67        if (ret < 0)
  68                return ret;
  69
  70        return phy_read(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG);
  71}
  72
  73static int ar803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
  74                                 u16 clear, u16 set)
  75{
  76        int val;
  77
  78        val = ar803x_debug_reg_read(phydev, reg);
  79        if (val < 0)
  80                return val;
  81
  82        val &= 0xffff;
  83        val &= ~clear;
  84        val |= set;
  85
  86        return phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
  87                         val);
  88}
  89
  90static int ar803x_enable_rx_delay(struct phy_device *phydev, bool on)
  91{
  92        u16 clear = 0, set = 0;
  93
  94        if (on)
  95                set = AR803x_RGMII_RX_CLK_DLY;
  96        else
  97                clear = AR803x_RGMII_RX_CLK_DLY;
  98
  99        return ar803x_debug_reg_mask(phydev, AR803x_DEBUG_REG_0, clear, set);
 100}
 101
 102static int ar803x_enable_tx_delay(struct phy_device *phydev, bool on)
 103{
 104        u16 clear = 0, set = 0;
 105
 106        if (on)
 107                set = AR803x_RGMII_TX_CLK_DLY;
 108        else
 109                clear = AR803x_RGMII_TX_CLK_DLY;
 110
 111        return ar803x_debug_reg_mask(phydev, AR803x_DEBUG_REG_5, clear, set);
 112}
 113
 114static int ar8021_config(struct phy_device *phydev)
 115{
 116        phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
 117                  BMCR_ANENABLE | BMCR_ANRESTART);
 118
 119        ar803x_enable_tx_delay(phydev, true);
 120
 121        phydev->supported = phydev->drv->features;
 122        return 0;
 123}
 124
 125static int ar803x_delay_config(struct phy_device *phydev)
 126{
 127        int ret;
 128
 129        if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
 130            phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 131                ret = ar803x_enable_tx_delay(phydev, true);
 132        else
 133                ret = ar803x_enable_tx_delay(phydev, false);
 134
 135        if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
 136            phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 137                ret = ar803x_enable_rx_delay(phydev, true);
 138        else
 139                ret = ar803x_enable_rx_delay(phydev, false);
 140
 141        return ret;
 142}
 143
 144static int ar803x_regs_config(struct phy_device *phydev)
 145{
 146        struct ar803x_priv *priv = phydev->priv;
 147        u16 set = 0, clear = 0;
 148        int val;
 149        int ret;
 150
 151        /* no configuration available */
 152        if (!priv)
 153                return 0;
 154
 155        /*
 156         * Only supported on the AR8031, AR8035 has strappings for the PLL mode
 157         * as well as the RGMII voltage.
 158         */
 159        if (phydev->drv->uid == AR8031_PHY_ID) {
 160                if (priv->flags & AR803x_FLAG_KEEP_PLL_ENABLED)
 161                        set |= AR803x_PLL_ON;
 162                else
 163                        clear |= AR803x_PLL_ON;
 164
 165                if (priv->flags & AR803x_FLAG_RGMII_1V8)
 166                        set |= AR803x_RGMII_1V8;
 167                else
 168                        clear |= AR803x_RGMII_1V8;
 169
 170                ret = ar803x_debug_reg_mask(phydev, AR803x_DEBUG_REG_1F, clear,
 171                                            set);
 172                if (ret < 0)
 173                        return ret;
 174        }
 175
 176        /* save the write access if the mask is empty */
 177        if (priv->clk_25m_mask) {
 178                val = phy_read_mmd(phydev, MDIO_MMD_AN, AR803x_CLK_25M_SEL_REG);
 179                if (val < 0)
 180                        return val;
 181                val &= ~priv->clk_25m_mask;
 182                val |= priv->clk_25m_reg;
 183                ret = phy_write_mmd(phydev, MDIO_MMD_AN,
 184                                    AR803x_CLK_25M_SEL_REG, val);
 185                if (ret < 0)
 186                        return ret;
 187        }
 188
 189        return 0;
 190}
 191
 192static int ar803x_of_init(struct phy_device *phydev)
 193{
 194#if defined(CONFIG_DM_ETH)
 195        struct ar803x_priv *priv;
 196        ofnode node, vddio_reg_node;
 197        u32 strength, freq, min_uV, max_uV;
 198        int sel;
 199
 200        node = phy_get_ofnode(phydev);
 201        if (!ofnode_valid(node))
 202                return -EINVAL;
 203
 204        priv = malloc(sizeof(*priv));
 205        if (!priv)
 206                return -ENOMEM;
 207        memset(priv, 0, sizeof(*priv));
 208
 209        phydev->priv = priv;
 210
 211        debug("%s: found PHY node: %s\n", __func__, ofnode_get_name(node));
 212
 213        if (ofnode_read_bool(node, "qca,keep-pll-enabled"))
 214                priv->flags |= AR803x_FLAG_KEEP_PLL_ENABLED;
 215
 216        /*
 217         * We can't use the regulator framework because the regulator is
 218         * a subnode of the PHY. So just read the two properties we are
 219         * interested in.
 220         */
 221        vddio_reg_node = ofnode_find_subnode(node, "vddio-regulator");
 222        if (ofnode_valid(vddio_reg_node)) {
 223                min_uV = ofnode_read_u32_default(vddio_reg_node,
 224                                                 "regulator-min-microvolt", 0);
 225                max_uV = ofnode_read_u32_default(vddio_reg_node,
 226                                                 "regulator-max-microvolt", 0);
 227
 228                if (min_uV != max_uV) {
 229                        free(priv);
 230                        return -EINVAL;
 231                }
 232
 233                switch (min_uV) {
 234                case 1500000:
 235                        break;
 236                case 1800000:
 237                        priv->flags |= AR803x_FLAG_RGMII_1V8;
 238                        break;
 239                default:
 240                        free(priv);
 241                        return -EINVAL;
 242                }
 243        }
 244
 245        /*
 246         * Get the CLK_25M frequency from the device tree. Only XTAL and PLL
 247         * sources are supported right now. There is also the possibilty to use
 248         * the DSP as frequency reference, this is used for synchronous
 249         * ethernet.
 250         */
 251        if (!ofnode_read_u32(node, "qca,clk-out-frequency", &freq)) {
 252                switch (freq) {
 253                case 25000000:
 254                        sel = AR803x_CLK_25M_25MHZ_XTAL;
 255                        break;
 256                case 50000000:
 257                        sel = AR803x_CLK_25M_50MHZ_PLL;
 258                        break;
 259                case 62500000:
 260                        sel = AR803x_CLK_25M_62_5MHZ_PLL;
 261                        break;
 262                case 125000000:
 263                        sel = AR803x_CLK_25M_125MHZ_PLL;
 264                        break;
 265                default:
 266                        dev_err(phydev->dev,
 267                                "invalid qca,clk-out-frequency\n");
 268                        free(priv);
 269                        return -EINVAL;
 270                }
 271
 272                priv->clk_25m_mask |= AR803x_CLK_25M_MASK;
 273                priv->clk_25m_reg |= FIELD_PREP(AR803x_CLK_25M_MASK, sel);
 274                /*
 275                 * Fixup for the AR8035 which only has two bits. The two
 276                 * remaining bits map to the same frequencies.
 277                 */
 278
 279                if (phydev->drv->uid == AR8035_PHY_ID) {
 280                        priv->clk_25m_reg &= AR8035_CLK_25M_MASK;
 281                        priv->clk_25m_mask &= AR8035_CLK_25M_MASK;
 282                }
 283        }
 284
 285        if (phydev->drv->uid == AR8031_PHY_ID &&
 286            !ofnode_read_u32(node, "qca,clk-out-strength", &strength)) {
 287                switch (strength) {
 288                case AR803X_STRENGTH_FULL:
 289                        sel = AR803x_CLK_25M_DR_FULL;
 290                        break;
 291                case AR803X_STRENGTH_HALF:
 292                        sel = AR803x_CLK_25M_DR_HALF;
 293                        break;
 294                case AR803X_STRENGTH_QUARTER:
 295                        sel = AR803x_CLK_25M_DR_QUARTER;
 296                        break;
 297                default:
 298                        dev_err(phydev->dev,
 299                                "invalid qca,clk-out-strength\n");
 300                        free(priv);
 301                        return -EINVAL;
 302                }
 303                priv->clk_25m_mask |= AR803x_CLK_25M_DR_MASK;
 304                priv->clk_25m_reg |= FIELD_PREP(AR803x_CLK_25M_DR_MASK, sel);
 305        }
 306
 307        debug("%s: flags=%x clk_25m_reg=%04x clk_25m_mask=%04x\n", __func__,
 308              priv->flags, priv->clk_25m_reg, priv->clk_25m_mask);
 309#endif
 310
 311        return 0;
 312}
 313
 314static int ar803x_config(struct phy_device *phydev)
 315{
 316        int ret;
 317
 318        ret = ar803x_of_init(phydev);
 319        if (ret < 0)
 320                return ret;
 321
 322        ret = ar803x_delay_config(phydev);
 323        if (ret < 0)
 324                return ret;
 325
 326        ret = ar803x_regs_config(phydev);
 327        if (ret < 0)
 328                return ret;
 329
 330        phydev->supported = phydev->drv->features;
 331
 332        genphy_config_aneg(phydev);
 333        genphy_restart_aneg(phydev);
 334
 335        return 0;
 336}
 337
 338static struct phy_driver AR8021_driver =  {
 339        .name = "AR8021",
 340        .uid = AR8021_PHY_ID,
 341        .mask = 0xfffffff0,
 342        .features = PHY_GBIT_FEATURES,
 343        .config = ar8021_config,
 344        .startup = genphy_startup,
 345        .shutdown = genphy_shutdown,
 346};
 347
 348static struct phy_driver AR8031_driver =  {
 349        .name = "AR8031/AR8033",
 350        .uid = AR8031_PHY_ID,
 351        .mask = 0xffffffef,
 352        .features = PHY_GBIT_FEATURES,
 353        .config = ar803x_config,
 354        .startup = genphy_startup,
 355        .shutdown = genphy_shutdown,
 356};
 357
 358static struct phy_driver AR8035_driver =  {
 359        .name = "AR8035",
 360        .uid = AR8035_PHY_ID,
 361        .mask = 0xffffffef,
 362        .features = PHY_GBIT_FEATURES,
 363        .config = ar803x_config,
 364        .startup = genphy_startup,
 365        .shutdown = genphy_shutdown,
 366};
 367
 368int phy_atheros_init(void)
 369{
 370        phy_register(&AR8021_driver);
 371        phy_register(&AR8031_driver);
 372        phy_register(&AR8035_driver);
 373
 374        return 0;
 375}
 376