Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
0004  *
0005  * MDIO implementation for ARC EMAC
0006  */
0007 
0008 #include <linux/delay.h>
0009 #include <linux/of_mdio.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/gpio/consumer.h>
0012 
0013 #include "emac.h"
0014 
0015 /* Number of seconds we wait for "MDIO complete" flag to appear */
0016 #define ARC_MDIO_COMPLETE_POLL_COUNT    1
0017 
0018 /**
0019  * arc_mdio_complete_wait - Waits until MDIO transaction is completed.
0020  * @priv:   Pointer to ARC EMAC private data structure.
0021  *
0022  * returns: 0 on success, -ETIMEDOUT on a timeout.
0023  */
0024 static int arc_mdio_complete_wait(struct arc_emac_priv *priv)
0025 {
0026     unsigned int i;
0027 
0028     for (i = 0; i < ARC_MDIO_COMPLETE_POLL_COUNT * 40; i++) {
0029         unsigned int status = arc_reg_get(priv, R_STATUS);
0030 
0031         status &= MDIO_MASK;
0032 
0033         if (status) {
0034             /* Reset "MDIO complete" flag */
0035             arc_reg_set(priv, R_STATUS, status);
0036             return 0;
0037         }
0038 
0039         msleep(25);
0040     }
0041 
0042     return -ETIMEDOUT;
0043 }
0044 
0045 /**
0046  * arc_mdio_read - MDIO interface read function.
0047  * @bus:    Pointer to MII bus structure.
0048  * @phy_addr:   Address of the PHY device.
0049  * @reg_num:    PHY register to read.
0050  *
0051  * returns: The register contents on success, -ETIMEDOUT on a timeout.
0052  *
0053  * Reads the contents of the requested register from the requested PHY
0054  * address.
0055  */
0056 static int arc_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
0057 {
0058     struct arc_emac_priv *priv = bus->priv;
0059     unsigned int value;
0060     int error;
0061 
0062     arc_reg_set(priv, R_MDIO,
0063             0x60020000 | (phy_addr << 23) | (reg_num << 18));
0064 
0065     error = arc_mdio_complete_wait(priv);
0066     if (error < 0)
0067         return error;
0068 
0069     value = arc_reg_get(priv, R_MDIO) & 0xffff;
0070 
0071     dev_dbg(priv->dev, "arc_mdio_read(phy_addr=%i, reg_num=%x) = %x\n",
0072         phy_addr, reg_num, value);
0073 
0074     return value;
0075 }
0076 
0077 /**
0078  * arc_mdio_write - MDIO interface write function.
0079  * @bus:    Pointer to MII bus structure.
0080  * @phy_addr:   Address of the PHY device.
0081  * @reg_num:    PHY register to write to.
0082  * @value:  Value to be written into the register.
0083  *
0084  * returns: 0 on success, -ETIMEDOUT on a timeout.
0085  *
0086  * Writes the value to the requested register.
0087  */
0088 static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
0089               int reg_num, u16 value)
0090 {
0091     struct arc_emac_priv *priv = bus->priv;
0092 
0093     dev_dbg(priv->dev,
0094         "arc_mdio_write(phy_addr=%i, reg_num=%x, value=%x)\n",
0095         phy_addr, reg_num, value);
0096 
0097     arc_reg_set(priv, R_MDIO,
0098             0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
0099 
0100     return arc_mdio_complete_wait(priv);
0101 }
0102 
0103 /**
0104  * arc_mdio_reset
0105  * @bus: points to the mii_bus structure
0106  * Description: reset the MII bus
0107  */
0108 static int arc_mdio_reset(struct mii_bus *bus)
0109 {
0110     struct arc_emac_priv *priv = bus->priv;
0111     struct arc_emac_mdio_bus_data *data = &priv->bus_data;
0112 
0113     if (data->reset_gpio) {
0114         gpiod_set_value_cansleep(data->reset_gpio, 1);
0115         msleep(data->msec);
0116         gpiod_set_value_cansleep(data->reset_gpio, 0);
0117     }
0118 
0119     return 0;
0120 }
0121 
0122 /**
0123  * arc_mdio_probe - MDIO probe function.
0124  * @priv:   Pointer to ARC EMAC private data structure.
0125  *
0126  * returns: 0 on success, -ENOMEM when mdiobus_alloc
0127  * (to allocate memory for MII bus structure) fails.
0128  *
0129  * Sets up and registers the MDIO interface.
0130  */
0131 int arc_mdio_probe(struct arc_emac_priv *priv)
0132 {
0133     struct arc_emac_mdio_bus_data *data = &priv->bus_data;
0134     struct device_node *np = priv->dev->of_node;
0135     const char *name = "Synopsys MII Bus";
0136     struct mii_bus *bus;
0137     int error;
0138 
0139     bus = mdiobus_alloc();
0140     if (!bus)
0141         return -ENOMEM;
0142 
0143     priv->bus = bus;
0144     bus->priv = priv;
0145     bus->parent = priv->dev;
0146     bus->name = name;
0147     bus->read = &arc_mdio_read;
0148     bus->write = &arc_mdio_write;
0149     bus->reset = &arc_mdio_reset;
0150 
0151     /* optional reset-related properties */
0152     data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset",
0153                            GPIOD_OUT_LOW);
0154     if (IS_ERR(data->reset_gpio)) {
0155         mdiobus_free(bus);
0156         return dev_err_probe(priv->dev, PTR_ERR(data->reset_gpio),
0157                      "Failed to request gpio\n");
0158     }
0159 
0160     of_property_read_u32(np, "phy-reset-duration", &data->msec);
0161     /* A sane reset duration should not be longer than 1s */
0162     if (data->msec > 1000)
0163         data->msec = 1;
0164 
0165     snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
0166 
0167     error = of_mdiobus_register(bus, priv->dev->of_node);
0168     if (error) {
0169         mdiobus_free(bus);
0170         return dev_err_probe(priv->dev, error,
0171                      "cannot register MDIO bus %s\n", name);
0172     }
0173 
0174     return 0;
0175 }
0176 
0177 /**
0178  * arc_mdio_remove - MDIO remove function.
0179  * @priv:   Pointer to ARC EMAC private data structure.
0180  *
0181  * Unregisters the MDIO and frees any associate memory for MII bus.
0182  */
0183 int arc_mdio_remove(struct arc_emac_priv *priv)
0184 {
0185     mdiobus_unregister(priv->bus);
0186     mdiobus_free(priv->bus);
0187     priv->bus = NULL;
0188 
0189     return 0;
0190 }