
From: Paul Burton paul.burton@imgtec.com
Add support to the pch_gbe driver for resetting the PHY using a GPIO specified in the device tree. This matches the support already in Linux.
Signed-off-by: Paul Burton paul.burton@imgtec.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
Changes in v2: None
drivers/net/pch_gbe.c | 29 +++++++++++++++++++++++++++-- drivers/net/pch_gbe.h | 1 + 2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c index 8866f6632f..cc3ca8b3da 100644 --- a/drivers/net/pch_gbe.c +++ b/drivers/net/pch_gbe.c @@ -12,6 +12,7 @@ #include <asm/io.h> #include <pci.h> #include <miiphy.h> +#include <asm/gpio.h> #include "pch_gbe.h"
#if !defined(CONFIG_PHYLIB) @@ -72,6 +73,14 @@ static int pch_gbe_reset(struct udevice *dev) priv->rx_idx = 0; priv->tx_idx = 0;
+ if (dm_gpio_is_valid(&priv->gpio_phy_reset)) { + /* Reset the PHY */ + dm_gpio_set_value(&priv->gpio_phy_reset, 1); + udelay(15000); + dm_gpio_set_value(&priv->gpio_phy_reset, 0); + udelay(5000); + } + writel(PCH_GBE_ALL_RST, &mac_regs->reset);
/* @@ -451,6 +460,11 @@ int pch_gbe_probe(struct udevice *dev) plat->iobase = (ulong)iobase; priv->mac_regs = (struct pch_gbe_regs *)iobase;
+ err = gpio_request_by_name(dev, "phy-reset-gpios", 0, + &priv->gpio_phy_reset, GPIOD_IS_OUT); + if (err && (err != -ENOENT)) + return err; + /* Read MAC address from SROM and initialize dev->enetaddr with it */ pch_gbe_mac_read(priv->mac_regs, plat->enetaddr);
@@ -460,9 +474,17 @@ int pch_gbe_probe(struct udevice *dev)
err = pch_gbe_reset(dev); if (err) - return err; + goto out_err;
- return pch_gbe_phy_init(dev); + err = pch_gbe_phy_init(dev); + if (err) + goto out_err; + + return 0; +out_err: + if (dm_gpio_is_valid(&priv->gpio_phy_reset)) + dm_gpio_free(dev, &priv->gpio_phy_reset); + return err; }
int pch_gbe_remove(struct udevice *dev) @@ -473,6 +495,9 @@ int pch_gbe_remove(struct udevice *dev) mdio_unregister(priv->bus); mdio_free(priv->bus);
+ if (dm_gpio_is_valid(&priv->gpio_phy_reset)) + dm_gpio_free(dev, &priv->gpio_phy_reset); + return 0; }
diff --git a/drivers/net/pch_gbe.h b/drivers/net/pch_gbe.h index 0ea0c73a4f..1d13380837 100644 --- a/drivers/net/pch_gbe.h +++ b/drivers/net/pch_gbe.h @@ -293,6 +293,7 @@ struct pch_gbe_priv { struct udevice *dev; int rx_idx; int tx_idx; + struct gpio_desc gpio_phy_reset; };
#endif /* _PCH_GBE_H_ */