* [U-Boot] [PATCH v8 14/17] net: fec_mxc: Add fec_phy_reset support
@ 2017-05-23 13:33 Jagan Teki
2017-05-30 19:35 ` Joe Hershberger
0 siblings, 1 reply; 2+ messages in thread
From: Jagan Teki @ 2017-05-23 13:33 UTC (permalink / raw)
To: u-boot
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,
--
2.7.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [U-Boot] [PATCH v8 14/17] net: fec_mxc: Add fec_phy_reset support
2017-05-23 13:33 [U-Boot] [PATCH v8 14/17] net: fec_mxc: Add fec_phy_reset support Jagan Teki
@ 2017-05-30 19:35 ` Joe Hershberger
0 siblings, 0 replies; 2+ messages in thread
From: Joe Hershberger @ 2017-05-30 19:35 UTC (permalink / raw)
To: u-boot
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 at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-05-30 19:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-23 13:33 [U-Boot] [PATCH v8 14/17] net: fec_mxc: Add fec_phy_reset support Jagan Teki
2017-05-30 19:35 ` Joe Hershberger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox