On Tue, May 23, 2017 at 8:33 AM, Jagan Teki <jagannadh.t...@gmail.com> wrote: > From: Jagan Teki <ja...@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.hershber...@ni.com> > Cc: Fabio Estevam <fabio.este...@nxp.com> > Signed-off-by: Jagan Teki <ja...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot