[U-Boot] [PATCH v8 14/17] net: fec_mxc: Add fec_phy_reset support

From: Jagan Teki jagan@openedev.com
phy-reset-gpios and phy-reset-duration properties are needed for adding mii_dev reset bus operation, so the board code not take care of phy_reset anymore if it use DM_ETH.
Cc: Joe Hershberger joe.hershberger@ni.com Cc: Fabio Estevam fabio.estevam@nxp.com Signed-off-by: Jagan Teki jagan@openedev.com --- Changes for v8: - Add 'phy-reset-duration' property support
drivers/net/fec_mxc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++----- drivers/net/fec_mxc.h | 9 ++++++ include/netdev.h | 5 ++++ 3 files changed, 89 insertions(+), 8 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 08bea8b..17fe27f 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -180,13 +180,27 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyaddr, static int fec_phy_read(struct mii_dev *bus, int phyaddr, int dev_addr, int regaddr) { - return fec_mdio_read(bus->priv, phyaddr, regaddr); +#ifdef CONFIG_DM_ETH + struct fec_priv *priv = dev_get_priv((struct udevice *)bus->priv); + struct ethernet_regs *eth = priv->eth; +#else + struct ethernet_regs *eth = bus->priv; +#endif + + return fec_mdio_read(eth, phyaddr, regaddr); }
static int fec_phy_write(struct mii_dev *bus, int phyaddr, int dev_addr, int regaddr, u16 data) { - return fec_mdio_write(bus->priv, phyaddr, regaddr, data); +#ifdef CONFIG_DM_ETH + struct fec_priv *priv = dev_get_priv((struct udevice *)bus->priv); + struct ethernet_regs *eth = priv->eth; +#else + struct ethernet_regs *eth = bus->priv; +#endif + + return fec_mdio_write(eth, phyaddr, regaddr, data); }
#ifndef CONFIG_PHYLIB @@ -985,9 +999,44 @@ static void fec_free_descs(struct fec_priv *fec) free(fec->tbd_base); }
+#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO) +static int fec_phy_reset(struct mii_dev *bus) +{ + struct fec_priv *priv = dev_get_priv((struct udevice *)bus->priv); + int ret; + + if (!dm_gpio_is_valid(&priv->reset_gpio)) + return 0; + + /* phy reset */ + ret = dm_gpio_set_value(&priv->reset_gpio, 0); + if (ret) + return ret; + + mdelay(priv->reset_duration); + + ret = dm_gpio_set_value(&priv->reset_gpio, 1); + if (ret) + return ret; + + mdelay(priv->reset_duration); + + return 0; +} +#endif + +#ifdef CONFIG_DM_ETH +struct mii_dev *fec_get_miibus(struct udevice *dev, int dev_id) +#else struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) +#endif { +#ifdef CONFIG_DM_ETH + struct fec_priv *priv = dev_get_priv(dev); + struct ethernet_regs *eth = priv->eth; +#else struct ethernet_regs *eth = (struct ethernet_regs *)base_addr; +#endif struct mii_dev *bus; int ret;
@@ -998,7 +1047,14 @@ struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) } bus->read = fec_phy_read; bus->write = fec_phy_write; +#ifdef CONFIG_DM_ETH + bus->priv = dev; +# ifdef CONFIG_DM_GPIO + bus->reset = fec_phy_reset; +# endif +#else bus->priv = eth; +#endif fec_set_dev_name(bus->name, dev_id);
ret = mdio_register(bus); @@ -1223,7 +1279,7 @@ static int fecmxc_probe(struct udevice *dev) if (ret) return ret;
- bus = fec_get_miibus((uint32_t)priv->eth, dev_id); + bus = fec_get_miibus(dev, dev_id); if (!bus) goto err_mii;
@@ -1278,6 +1334,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)dev_get_addr(dev); priv->eth = (struct ethernet_regs *)pdata->iobase; @@ -1292,12 +1349,22 @@ 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 + /* phy reset gpio */ + ret = gpio_request_by_name(dev, "phy-reset-gpios", 0, + &priv->reset_gpio, GPIOD_IS_OUT); + if (ret == 0) { + priv->reset_duration = fdtdec_get_int(gd->fdt_blob, + dev_of_offset(dev), + "phy-reset-duration", 1); + /* A sane reset duration should not be longer than 1s */ + if (priv->reset_duration > 1000) + priv->reset_duration = 1; + 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 43a7d7b..fd51d6d 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -17,6 +17,10 @@ #ifndef __FEC_MXC_H #define __FEC_MXC_H
+#ifdef CONFIG_DM_GPIO +# include <asm-generic/gpio.h> +#endif + /* Layout description of the FEC */ struct ethernet_regs { /* [10:2]addr = 00 */ @@ -254,6 +258,11 @@ struct fec_priv {
#ifdef CONFIG_DM_ETH u32 interface; + +# ifdef CONFIG_DM_GPIO + struct gpio_desc reset_gpio; + u32 reset_duration; +# endif #endif };
diff --git a/include/netdev.h b/include/netdev.h index 8eb8b46..e5668f4 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -133,7 +133,12 @@ static inline int pci_eth_init(bd_t *bis) return num; }
+#ifdef CONFIG_DM_ETH +struct mii_dev *fec_get_miibus(struct udevice *dev, int dev_id); +#else struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id); +#endif + #ifdef CONFIG_PHYLIB struct phy_device; int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,

On Tue, May 23, 2017 at 8:33 AM, Jagan Teki jagannadh.teki@gmail.com wrote:
From: Jagan Teki jagan@openedev.com
phy-reset-gpios and phy-reset-duration properties are needed for adding mii_dev reset bus operation, so the board code not take care of phy_reset anymore if it use DM_ETH.
Cc: Joe Hershberger joe.hershberger@ni.com Cc: Fabio Estevam fabio.estevam@nxp.com Signed-off-by: Jagan Teki jagan@openedev.com
Changes for v8:
- Add 'phy-reset-duration' property support
drivers/net/fec_mxc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++----- drivers/net/fec_mxc.h | 9 ++++++ include/netdev.h | 5 ++++ 3 files changed, 89 insertions(+), 8 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 08bea8b..17fe27f 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -180,13 +180,27 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyaddr, static int fec_phy_read(struct mii_dev *bus, int phyaddr, int dev_addr, int regaddr) {
return fec_mdio_read(bus->priv, phyaddr, regaddr);
+#ifdef CONFIG_DM_ETH
struct fec_priv *priv = dev_get_priv((struct udevice *)bus->priv);
struct ethernet_regs *eth = priv->eth;
+#else
struct ethernet_regs *eth = bus->priv;
+#endif
return fec_mdio_read(eth, phyaddr, regaddr);
}
static int fec_phy_write(struct mii_dev *bus, int phyaddr, int dev_addr, int regaddr, u16 data) {
return fec_mdio_write(bus->priv, phyaddr, regaddr, data);
+#ifdef CONFIG_DM_ETH
struct fec_priv *priv = dev_get_priv((struct udevice *)bus->priv);
struct ethernet_regs *eth = priv->eth;
+#else
struct ethernet_regs *eth = bus->priv;
+#endif
return fec_mdio_write(eth, phyaddr, regaddr, data);
}
#ifndef CONFIG_PHYLIB @@ -985,9 +999,44 @@ static void fec_free_descs(struct fec_priv *fec) free(fec->tbd_base); }
+#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO) +static int fec_phy_reset(struct mii_dev *bus) +{
struct fec_priv *priv = dev_get_priv((struct udevice *)bus->priv);
int ret;
if (!dm_gpio_is_valid(&priv->reset_gpio))
return 0;
/* phy reset */
ret = dm_gpio_set_value(&priv->reset_gpio, 0);
if (ret)
return ret;
mdelay(priv->reset_duration);
ret = dm_gpio_set_value(&priv->reset_gpio, 1);
if (ret)
return ret;
mdelay(priv->reset_duration);
return 0;
+} +#endif
+#ifdef CONFIG_DM_ETH +struct mii_dev *fec_get_miibus(struct udevice *dev, int dev_id) +#else struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) +#endif { +#ifdef CONFIG_DM_ETH
struct fec_priv *priv = dev_get_priv(dev);
struct ethernet_regs *eth = priv->eth;
+#else struct ethernet_regs *eth = (struct ethernet_regs *)base_addr; +#endif struct mii_dev *bus; int ret;
@@ -998,7 +1047,14 @@ struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) } bus->read = fec_phy_read; bus->write = fec_phy_write; +#ifdef CONFIG_DM_ETH
bus->priv = dev;
+# ifdef CONFIG_DM_GPIO
bus->reset = fec_phy_reset;
+# endif +#else bus->priv = eth; +#endif fec_set_dev_name(bus->name, dev_id);
ret = mdio_register(bus);
@@ -1223,7 +1279,7 @@ static int fecmxc_probe(struct udevice *dev) if (ret) return ret;
bus = fec_get_miibus((uint32_t)priv->eth, dev_id);
bus = fec_get_miibus(dev, dev_id); if (!bus) goto err_mii;
@@ -1278,6 +1334,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)dev_get_addr(dev); priv->eth = (struct ethernet_regs *)pdata->iobase;
@@ -1292,12 +1349,22 @@ 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
/* phy reset gpio */
ret = gpio_request_by_name(dev, "phy-reset-gpios", 0,
&priv->reset_gpio, GPIOD_IS_OUT);
if (ret == 0) {
priv->reset_duration = fdtdec_get_int(gd->fdt_blob,
dev_of_offset(dev),
"phy-reset-duration", 1);
Seems like
/* A sane reset duration should not be longer than 1s */
if (priv->reset_duration > 1000)
priv->reset_duration = 1;
It seems odd to set it to 1 ms if the requested was too long. Maybe it should just be priv->reset_duration = MIN(priv->reset_duration, 1000); ?
Also, should the member variable have "_ms" at the end to make the units clear?
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 43a7d7b..fd51d6d 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -17,6 +17,10 @@ #ifndef __FEC_MXC_H #define __FEC_MXC_H
+#ifdef CONFIG_DM_GPIO +# include <asm-generic/gpio.h> +#endif
/* Layout description of the FEC */ struct ethernet_regs { /* [10:2]addr = 00 */ @@ -254,6 +258,11 @@ struct fec_priv {
#ifdef CONFIG_DM_ETH u32 interface;
+# ifdef CONFIG_DM_GPIO
struct gpio_desc reset_gpio;
u32 reset_duration;
+# endif #endif };
diff --git a/include/netdev.h b/include/netdev.h index 8eb8b46..e5668f4 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -133,7 +133,12 @@ static inline int pci_eth_init(bd_t *bis) return num; }
+#ifdef CONFIG_DM_ETH +struct mii_dev *fec_get_miibus(struct udevice *dev, int dev_id); +#else struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id); +#endif
#ifdef CONFIG_PHYLIB struct phy_device; int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr, -- 2.7.4
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
participants (2)
-
Jagan Teki
-
Joe Hershberger