[U-Boot] [PATCH 09/10] dm: net: fec: Add support for PHY reset

Jagan Teki jagan at amarulasolutions.com
Mon Jul 30 12:45:08 UTC 2018


Add PHY reset code for DM_ETH by retrieving phy-reset-gpios
and phy-reset-duration in fec node.

Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
---
 drivers/net/fec_mxc.c | 50 +++++++++++++++++++++++++++++++++++++------
 drivers/net/fec_mxc.h |  7 ++++++
 2 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index a87f5b6848..0fdad5c5bf 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -16,7 +16,6 @@
 #include <net.h>
 #include <netdev.h>
 #include <phy.h>
-#include "fec_mxc.h"
 
 #include <asm/io.h>
 #include <linux/errno.h>
@@ -25,6 +24,9 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/mach-imx/sys_proto.h>
+#include <asm-generic/gpio.h>
+
+#include "fec_mxc.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -1245,6 +1247,33 @@ static int fec_phy_init(struct udevice *dev)
 	return 0;
 }
 
+#if defined(CONFIG_DM_GPIO)
+static int fec_mdio_reset(struct mii_dev *bus)
+{
+	struct udevice *dev = bus->priv;
+	struct fec_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	if (!dm_gpio_is_valid(&priv->reset_gpio))
+		return 0;
+
+	ret = dm_gpio_set_value(&priv->reset_gpio, 1);
+	if (ret)
+		return ret;
+
+	if (priv->reset_delay > 20)
+		mdelay(priv->reset_delay);
+	else
+		udelay(priv->reset_delay * 1000);
+
+	ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+#endif
+
 static int fec_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 {
 	struct udevice *dev = bus->priv;
@@ -1275,6 +1304,9 @@ static int fec_mdio_init(struct udevice *dev)
 	bus->read = fec_mdio_read;
 	bus->write = fec_mdio_write;
 	snprintf(bus->name, sizeof(bus->name), "%s", dev->name);
+#if defined(CONFIG_DM_GPIO)
+	bus->reset = fec_mdio_reset;
+#endif
 	bus->priv = dev;
 
 	return mdio_register(bus);
@@ -1365,6 +1397,7 @@ static int fecmxc_ofdata_to_platdata(struct udevice *dev)
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct fec_priv *priv = dev_get_priv(dev);
 	const char *phy_mode;
+	int ret = 0;
 
 	pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
 	priv->eth = (struct ethernet_regs *)pdata->iobase;
@@ -1379,12 +1412,17 @@ static int fecmxc_ofdata_to_platdata(struct udevice *dev)
 		return -EINVAL;
 	}
 
-	/* TODO
-	 * Need to get the reset-gpio and related properties from DT
-	 * and implemet the enet reset code on .probe call
-	 */
+#ifdef CONFIG_DM_GPIO
+	ret = gpio_request_by_name(dev, "phy-reset-gpios", dev->seq,
+		&priv->reset_gpio, GPIOD_IS_OUT);
+	if (ret == 0) {
+		priv->reset_delay = dev_read_u32_default(dev, "phy-reset-duration", 1);
+	} else if (ret == -ENOENT) {
+		ret = 0;
+	}
+#endif
 
-	return 0;
+	return ret;
 }
 
 static const struct udevice_id fecmxc_ids[] = {
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
index 058341ca4a..ab5935bb83 100644
--- a/drivers/net/fec_mxc.h
+++ b/drivers/net/fec_mxc.h
@@ -241,6 +241,13 @@ struct fec_priv {
 	int phy_id;
 	int (*mii_postcall)(int);
 #endif
+
+#ifdef CONFIG_DM_ETH
+# if CONFIG_IS_ENABLED(DM_GPIO)
+	struct gpio_desc reset_gpio;
+	uint32_t reset_delay;
+# endif
+#endif
 };
 
 void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
-- 
2.18.0.321.gffc6fa0e3



More information about the U-Boot mailing list