198 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)4 *5 * MDIO implementation for ARC EMAC6 */7 8#include <linux/delay.h>9#include <linux/of_mdio.h>10#include <linux/platform_device.h>11#include <linux/gpio/consumer.h>12 13#include "emac.h"14 15/* Number of seconds we wait for "MDIO complete" flag to appear */16#define ARC_MDIO_COMPLETE_POLL_COUNT 117 18/**19 * arc_mdio_complete_wait - Waits until MDIO transaction is completed.20 * @priv: Pointer to ARC EMAC private data structure.21 *22 * returns: 0 on success, -ETIMEDOUT on a timeout.23 */24static int arc_mdio_complete_wait(struct arc_emac_priv *priv)25{26 unsigned int i;27 28 for (i = 0; i < ARC_MDIO_COMPLETE_POLL_COUNT * 40; i++) {29 unsigned int status = arc_reg_get(priv, R_STATUS);30 31 status &= MDIO_MASK;32 33 if (status) {34 /* Reset "MDIO complete" flag */35 arc_reg_set(priv, R_STATUS, status);36 return 0;37 }38 39 msleep(25);40 }41 42 return -ETIMEDOUT;43}44 45/**46 * arc_mdio_read - MDIO interface read function.47 * @bus: Pointer to MII bus structure.48 * @phy_addr: Address of the PHY device.49 * @reg_num: PHY register to read.50 *51 * returns: The register contents on success, -ETIMEDOUT on a timeout.52 *53 * Reads the contents of the requested register from the requested PHY54 * address.55 */56static int arc_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)57{58 struct arc_emac_priv *priv = bus->priv;59 unsigned int value;60 int error;61 62 arc_reg_set(priv, R_MDIO,63 0x60020000 | (phy_addr << 23) | (reg_num << 18));64 65 error = arc_mdio_complete_wait(priv);66 if (error < 0)67 return error;68 69 value = arc_reg_get(priv, R_MDIO) & 0xffff;70 71 dev_dbg(priv->dev, "arc_mdio_read(phy_addr=%i, reg_num=%x) = %x\n",72 phy_addr, reg_num, value);73 74 return value;75}76 77/**78 * arc_mdio_write - MDIO interface write function.79 * @bus: Pointer to MII bus structure.80 * @phy_addr: Address of the PHY device.81 * @reg_num: PHY register to write to.82 * @value: Value to be written into the register.83 *84 * returns: 0 on success, -ETIMEDOUT on a timeout.85 *86 * Writes the value to the requested register.87 */88static int arc_mdio_write(struct mii_bus *bus, int phy_addr,89 int reg_num, u16 value)90{91 struct arc_emac_priv *priv = bus->priv;92 93 dev_dbg(priv->dev,94 "arc_mdio_write(phy_addr=%i, reg_num=%x, value=%x)\n",95 phy_addr, reg_num, value);96 97 arc_reg_set(priv, R_MDIO,98 0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);99 100 return arc_mdio_complete_wait(priv);101}102 103/**104 * arc_mdio_reset105 * @bus: points to the mii_bus structure106 * Description: reset the MII bus107 */108static int arc_mdio_reset(struct mii_bus *bus)109{110 struct arc_emac_priv *priv = bus->priv;111 struct arc_emac_mdio_bus_data *data = &priv->bus_data;112 113 if (data->reset_gpio) {114 gpiod_set_value_cansleep(data->reset_gpio, 1);115 msleep(data->msec);116 gpiod_set_value_cansleep(data->reset_gpio, 0);117 }118 119 return 0;120}121 122/**123 * arc_mdio_probe - MDIO probe function.124 * @priv: Pointer to ARC EMAC private data structure.125 *126 * returns: 0 on success, -ENOMEM when mdiobus_alloc127 * (to allocate memory for MII bus structure) fails.128 *129 * Sets up and registers the MDIO interface.130 */131int arc_mdio_probe(struct arc_emac_priv *priv)132{133 struct arc_emac_mdio_bus_data *data = &priv->bus_data;134 struct device_node *np = priv->dev->of_node;135 const char *name = "Synopsys MII Bus";136 struct device_node *mdio_node;137 struct mii_bus *bus;138 int error;139 140 bus = mdiobus_alloc();141 if (!bus)142 return -ENOMEM;143 144 priv->bus = bus;145 bus->priv = priv;146 bus->parent = priv->dev;147 bus->name = name;148 bus->read = &arc_mdio_read;149 bus->write = &arc_mdio_write;150 bus->reset = &arc_mdio_reset;151 152 /* optional reset-related properties */153 data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset",154 GPIOD_OUT_LOW);155 if (IS_ERR(data->reset_gpio)) {156 mdiobus_free(bus);157 return dev_err_probe(priv->dev, PTR_ERR(data->reset_gpio),158 "Failed to request gpio\n");159 }160 161 of_property_read_u32(np, "phy-reset-duration", &data->msec);162 /* A sane reset duration should not be longer than 1s */163 if (data->msec > 1000)164 data->msec = 1;165 166 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);167 168 /* Backwards compatibility for EMAC nodes without MDIO subnode. */169 mdio_node = of_get_child_by_name(np, "mdio");170 if (!mdio_node)171 mdio_node = of_node_get(np);172 173 error = of_mdiobus_register(bus, mdio_node);174 of_node_put(mdio_node);175 if (error) {176 mdiobus_free(bus);177 return dev_err_probe(priv->dev, error,178 "cannot register MDIO bus %s\n", name);179 }180 181 return 0;182}183 184/**185 * arc_mdio_remove - MDIO remove function.186 * @priv: Pointer to ARC EMAC private data structure.187 *188 * Unregisters the MDIO and frees any associate memory for MII bus.189 */190int arc_mdio_remove(struct arc_emac_priv *priv)191{192 mdiobus_unregister(priv->bus);193 mdiobus_free(priv->bus);194 priv->bus = NULL;195 196 return 0;197}198