net: fec_mxc: Add fec_phy_reset support
PATCH v8 14/17 net: fec_mxc: Add fec_phy_reset support
From: Jagan Teki <[email protected]>
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.
---
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(-)
drivers/net/fec_mxc.c +75 -8
@@ -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[] = {
drivers/net/fec_mxc.h +9 -0
@@ -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 };
include/netdev.h +5 -0
@@ -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,
Signature · 1 line
2.7.4
PATCH v8 14/17 net: fec_mxc: Add fec_phy_reset support
Quoted 136 lines · Jagan Teki
From: Jagan Teki <[email protected]>
phy-reset-gpios and phy-reset-duration properties are needed for adding
mii_devreset bus operation, so the board code not take care ofphy_resetanymore if it useDM_ETH.Cc Joe Hershberger <[email protected]>Cc Fabio Estevam <[email protected]>Signed-off-by Jagan Teki <[email protected]>---
Changes for v8:
- Add 'phy-reset-duration' property supportdrivers/net/fec_mxc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++----- drivers/net/fec_mxc.h | 9 ++++++ include/netdev.h | 5 ++++ 3 files changed, 89 insertions(+), 8 deletions(-)drivers/net/fec_mxc.c +60
-5@@ -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
drivers/net/fec_mxc.c static int fecmxc_ofdata_to_platdata(struct udevice *dev) · line 1359
Quoted 10 lines
drivers/net/fec_mxc.c +8
-2-* 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
drivers/net/fec_mxc.c static int fecmxc_ofdata_to_platdata(struct udevice *dev) · line 1362
Quoted 3 lines
drivers/net/fec_mxc.c +3
-0+/* 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?
Quoted 60 lines
drivers/net/fec_mxc.c +4
-1+ ret =0 ; + } +#endif -return 0 ; +return ret; } static const struct udevice_id fecmxc_ids[] = {drivers/net/fec_mxc.h +9
-0@@ -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 };include/netdev.h +5
-1@@ -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