Hi Sjoerd, On 1 October 2015 at 10:48, Sjoerd Simons <sjoerd.sim...@collabora.co.uk> wrote: > Add support for the snps,reset-gpio, snps,reset-active-low (optional) and > snps,reset-delays-us device-tree bindings. The combination of these > three define how the PHY should be reset to ensure it's in a sane state. > > Signed-off-by: Sjoerd Simons <sjoerd.sim...@collabora.co.uk> > --- > > drivers/net/designware.c | 74 > ++++++++++++++++++++++++++++++++++++++++++++---- > drivers/net/designware.h | 11 +++++++ > 2 files changed, 79 insertions(+), 6 deletions(-) > > diff --git a/drivers/net/designware.c b/drivers/net/designware.c > index 6433896..f9ceec2 100644 > --- a/drivers/net/designware.c > +++ b/drivers/net/designware.c > @@ -28,7 +28,12 @@ DECLARE_GLOBAL_DATA_PTR; > > static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) > { > +#ifdef CONFIG_DM_ETH > + struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv); > + struct eth_mac_regs *mac_p = priv->mac_regs_p; > +#else > struct eth_mac_regs *mac_p = bus->priv; > +#endif > ulong start; > u16 miiaddr; > int timeout = CONFIG_MDIO_TIMEOUT; > @@ -51,7 +56,12 @@ static int dw_mdio_read(struct mii_dev *bus, int addr, int > devad, int reg) > static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, > u16 val) > { > +#ifdef CONFIG_DM_ETH > + struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv); > + struct eth_mac_regs *mac_p = priv->mac_regs_p; > +#else > struct eth_mac_regs *mac_p = bus->priv; > +#endif > ulong start; > u16 miiaddr; > int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT; > @@ -74,7 +84,40 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, > int devad, int reg, > return ret; > } > > -static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p) > +#if CONFIG_DM_ETH > +static int dw_mdio_reset(struct mii_dev *bus) > +{ > + struct udevice *dev = bus->priv; > + struct dw_eth_pdata *pdata = dev_get_platdata(dev); > + int ret; > + > + if (pdata->reset_gpio.dev == NULL)
!dm_gpio_is_valid(&pdata->reset_gpio) > + return 0; > + > + /* reset the phy */ > + ret = dm_gpio_set_value(&pdata->reset_gpio, 0); > + if (ret) > + return ret; > + > + udelay(pdata->reset_delays[0]); > + > + ret = dm_gpio_set_value(&pdata->reset_gpio, 1); > + if (ret) > + return ret; > + > + udelay(pdata->reset_delays[1]); > + > + ret = dm_gpio_set_value(&pdata->reset_gpio, 0); > + if (ret) > + return ret; > + > + udelay(pdata->reset_delays[2]); > + > + return 0; > +} > +#endif > + > +static int dw_mdio_init(const char *name, void *priv) > { > struct mii_dev *bus = mdio_alloc(); > > @@ -85,9 +128,12 @@ static int dw_mdio_init(const char *name, struct > eth_mac_regs *mac_regs_p) > > bus->read = dw_mdio_read; > bus->write = dw_mdio_write; > +#ifdef CONFIG_DM_ETH > + bus->reset = dw_mdio_reset; > +#endif > snprintf(bus->name, sizeof(bus->name), name); > > - bus->priv = (void *)mac_regs_p; > + bus->priv = priv; > > return mdio_register(bus); > } > @@ -604,7 +650,7 @@ static int designware_eth_probe(struct udevice *dev) > priv->dma_regs_p = (struct eth_dma_regs *)(iobase + > DW_DMA_BASE_OFFSET); > priv->interface = pdata->phy_interface; > > - dw_mdio_init(dev->name, priv->mac_regs_p); > + dw_mdio_init(dev->name, dev); > priv->bus = miiphy_get_dev_by_name(dev->name); > > ret = dw_phy_init(priv, dev); > @@ -624,8 +670,11 @@ static const struct eth_ops designware_eth_ops = { > > static int designware_eth_ofdata_to_platdata(struct udevice *dev) > { > - struct eth_pdata *pdata = dev_get_platdata(dev); > + struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); > + struct eth_pdata *pdata = &dw_pdata->eth_pdata; > const char *phy_mode; > + int reset_flags = GPIOD_IS_OUT; > + int ret = 0; > > pdata->iobase = dev_get_addr(dev); > pdata->phy_interface = -1; > @@ -637,7 +686,20 @@ static int designware_eth_ofdata_to_platdata(struct > udevice *dev) > return -EINVAL; > } > > - return 0; > + if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, > + "snps,reset-active-low")) > + reset_flags |= GPIOD_ACTIVE_LOW; > + > + ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, > + &dw_pdata->reset_gpio, reset_flags); It's odd to put a probed gpio into platdata. Should you use private data instead? (dev_get_priv()) > + if (ret == 0) { > + ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, > + "snps,reset-delays-us", dw_pdata->reset_delays, 3); > + } else if (ret == -ENOENT) { > + ret = 0; > + } > + > + return ret; > } > > static const struct udevice_id designware_eth_ids[] = { > @@ -655,7 +717,7 @@ U_BOOT_DRIVER(eth_designware) = { > .probe = designware_eth_probe, > .ops = &designware_eth_ops, > .priv_auto_alloc_size = sizeof(struct dw_eth_dev), > - .platdata_auto_alloc_size = sizeof(struct eth_pdata), > + .platdata_auto_alloc_size = sizeof(struct dw_eth_pdata), > .flags = DM_FLAG_ALLOC_PRIV_DMA, > }; > > diff --git a/drivers/net/designware.h b/drivers/net/designware.h > index 4b9ec39..f34263b 100644 > --- a/drivers/net/designware.h > +++ b/drivers/net/designware.h > @@ -8,6 +8,9 @@ > #ifndef _DW_ETH_H > #define _DW_ETH_H > > +#include <common.h> Drop that one... > +#include <asm/gpio.h> > + > #define CONFIG_TX_DESCR_NUM 16 > #define CONFIG_RX_DESCR_NUM 16 > #define CONFIG_ETH_BUFSIZE 2048 > @@ -235,4 +238,12 @@ struct dw_eth_dev { > struct mii_dev *bus; > }; > > +#ifdef CONFIG_DM_ETH Do you need this #ifdef > +struct dw_eth_pdata { > + struct eth_pdata eth_pdata; > + struct gpio_desc reset_gpio; > + u32 reset_delays[3]; > +}; > +#endif > + > #endif > -- > 2.5.3 > Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot