Message ID | 20210224140239.2617642-1-narmstrong@baylibre.com |
---|---|
State | Accepted |
Commit | 5160b4567c7181364add9ff6a282e600d47b31d8 |
Delegated to: | Joe Hershberger |
Headers | show |
Series | net: designware: add DM_MDIO support | expand |
On Wed, Feb 24, 2021 at 4:02 PM Neil Armstrong <narmstrong@baylibre.com> wrote: > > Add support for DM_MDIO to connect to PHY and expose a MDIO device for the > internal MDIO bus in order to dynamically connect to MDIO PHYs with DT > with eventual MDIO muxes in between. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> > --- > drivers/net/designware.c | 93 +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 92 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/designware.c b/drivers/net/designware.c > index 9dba55adaa..acf3a82828 100644 > --- a/drivers/net/designware.c > +++ b/drivers/net/designware.c > @@ -21,7 +21,9 @@ > #include <reset.h> > #include <asm/cache.h> > #include <dm/device_compat.h> > +#include <dm/device-internal.h> > #include <dm/devres.h> > +#include <dm/lists.h> > #include <linux/compiler.h> > #include <linux/delay.h> > #include <linux/err.h> > @@ -122,6 +124,55 @@ static int dw_mdio_reset(struct mii_dev *bus) > } > #endif > > +#if IS_ENABLED(CONFIG_DM_MDIO) > +int designware_eth_mdio_read(struct udevice *mdio_dev, int addr, int devad, int reg) > +{ > + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); > + > + return dw_mdio_read(pdata->mii_bus, addr, devad, reg); > +} > + > +int designware_eth_mdio_write(struct udevice *mdio_dev, int addr, int devad, int reg, u16 val) > +{ > + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); > + > + return dw_mdio_write(pdata->mii_bus, addr, devad, reg, val); > +} > + > +#if CONFIG_IS_ENABLED(DM_GPIO) > +int designware_eth_mdio_reset(struct udevice *mdio_dev) > +{ > + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); > + > + return dw_mdio_reset(pdata->mii_bus); > +} > +#endif > + > +static const struct mdio_ops designware_eth_mdio_ops = { > + .read = designware_eth_mdio_read, > + .write = designware_eth_mdio_write, > +#if CONFIG_IS_ENABLED(DM_GPIO) > + .reset = designware_eth_mdio_reset, > +#endif > +}; > + > +static int designware_eth_mdio_probe(struct udevice *dev) > +{ > + /* Use the priv data of parent */ > + dev_set_priv(dev, dev_get_priv(dev->parent)); > + > + return 0; > +} > + > +U_BOOT_DRIVER(designware_eth_mdio) = { > + .name = "eth_designware_mdio", > + .id = UCLASS_MDIO, > + .probe = designware_eth_mdio_probe, > + .ops = &designware_eth_mdio_ops, > + .plat_auto = sizeof(struct mdio_perdev_priv), > +}; > +#endif > + > static int dw_mdio_init(const char *name, void *priv) > { > struct mii_dev *bus = mdio_alloc(); > @@ -143,6 +194,34 @@ static int dw_mdio_init(const char *name, void *priv) > return mdio_register(bus); > } > > +#if IS_ENABLED(CONFIG_DM_MDIO) > +static int dw_dm_mdio_init(const char *name, void *priv) > +{ > + struct udevice *dev = priv; > + ofnode node; > + int ret; > + > + ofnode_for_each_subnode(node, dev_ofnode(dev)) { > + const char *subnode_name = ofnode_get_name(node); > + struct udevice *mdiodev; > + > + if (strcmp(subnode_name, "mdio")) > + continue; > + > + ret = device_bind_driver_to_node(dev, "eth_designware_mdio", > + subnode_name, node, &mdiodev); > + if (ret) > + debug("%s: not able to bind mdio device node\n", __func__); > + > + return 0; > + } > + > + printf("%s: mdio node is missing, registering legacy mdio bus", __func__); > + > + return dw_mdio_init(name, priv); > +} > +#endif > + > static void tx_descs_init(struct dw_eth_dev *priv) > { > struct eth_dma_regs *dma_p = priv->dma_regs_p; > @@ -487,7 +566,14 @@ static int _dw_free_pkt(struct dw_eth_dev *priv) > static int dw_phy_init(struct dw_eth_dev *priv, void *dev) > { > struct phy_device *phydev; > - int phy_addr = -1, ret; > + int ret; > + > +#if IS_ENABLED(CONFIG_DM_MDIO) && IS_ENABLED(CONFIG_DM_ETH) > + phydev = dm_eth_phy_connect(dev); > + if (!phydev) > + return -ENODEV; > +#else > + int phy_addr = -1; > > #ifdef CONFIG_PHY_ADDR > phy_addr = CONFIG_PHY_ADDR; > @@ -496,6 +582,7 @@ static int dw_phy_init(struct dw_eth_dev *priv, void *dev) > phydev = phy_connect(priv->bus, phy_addr, dev, priv->interface); > if (!phydev) > return -ENODEV; > +#endif > > phydev->supported &= PHY_GBIT_FEATURES; > if (priv->max_speed) { > @@ -759,7 +846,11 @@ int designware_eth_probe(struct udevice *dev) > priv->interface = pdata->phy_interface; > priv->max_speed = pdata->max_speed; > > +#if IS_ENABLED(CONFIG_DM_MDIO) > + ret = dw_dm_mdio_init(dev->name, dev); > +#else > ret = dw_mdio_init(dev->name, dev); > +#endif > if (ret) { > err = ret; > goto mdio_err; > -- > 2.25.1 > Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
On 25/02/2021 20:34, Ramon Fried wrote: > On Wed, Feb 24, 2021 at 4:02 PM Neil Armstrong <narmstrong@baylibre.com> wrote: >> >> Add support for DM_MDIO to connect to PHY and expose a MDIO device for the >> internal MDIO bus in order to dynamically connect to MDIO PHYs with DT >> with eventual MDIO muxes in between. >> >> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> >> --- >> drivers/net/designware.c | 93 +++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 92 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/net/designware.c b/drivers/net/designware.c >> index 9dba55adaa..acf3a82828 100644 >> --- a/drivers/net/designware.c >> +++ b/drivers/net/designware.c >> @@ -21,7 +21,9 @@ >> #include <reset.h> >> #include <asm/cache.h> >> #include <dm/device_compat.h> >> +#include <dm/device-internal.h> >> #include <dm/devres.h> >> +#include <dm/lists.h> >> #include <linux/compiler.h> >> #include <linux/delay.h> >> #include <linux/err.h> >> @@ -122,6 +124,55 @@ static int dw_mdio_reset(struct mii_dev *bus) >> } >> #endif >> >> +#if IS_ENABLED(CONFIG_DM_MDIO) >> +int designware_eth_mdio_read(struct udevice *mdio_dev, int addr, int devad, int reg) >> +{ >> + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); >> + >> + return dw_mdio_read(pdata->mii_bus, addr, devad, reg); >> +} >> + >> +int designware_eth_mdio_write(struct udevice *mdio_dev, int addr, int devad, int reg, u16 val) >> +{ >> + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); >> + >> + return dw_mdio_write(pdata->mii_bus, addr, devad, reg, val); >> +} >> + >> +#if CONFIG_IS_ENABLED(DM_GPIO) >> +int designware_eth_mdio_reset(struct udevice *mdio_dev) >> +{ >> + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); >> + >> + return dw_mdio_reset(pdata->mii_bus); >> +} >> +#endif >> + >> +static const struct mdio_ops designware_eth_mdio_ops = { >> + .read = designware_eth_mdio_read, >> + .write = designware_eth_mdio_write, >> +#if CONFIG_IS_ENABLED(DM_GPIO) >> + .reset = designware_eth_mdio_reset, >> +#endif >> +}; >> + >> +static int designware_eth_mdio_probe(struct udevice *dev) >> +{ >> + /* Use the priv data of parent */ >> + dev_set_priv(dev, dev_get_priv(dev->parent)); >> + >> + return 0; >> +} >> + >> +U_BOOT_DRIVER(designware_eth_mdio) = { >> + .name = "eth_designware_mdio", >> + .id = UCLASS_MDIO, >> + .probe = designware_eth_mdio_probe, >> + .ops = &designware_eth_mdio_ops, >> + .plat_auto = sizeof(struct mdio_perdev_priv), >> +}; >> +#endif >> + >> static int dw_mdio_init(const char *name, void *priv) >> { >> struct mii_dev *bus = mdio_alloc(); >> @@ -143,6 +194,34 @@ static int dw_mdio_init(const char *name, void *priv) >> return mdio_register(bus); >> } >> >> +#if IS_ENABLED(CONFIG_DM_MDIO) >> +static int dw_dm_mdio_init(const char *name, void *priv) >> +{ >> + struct udevice *dev = priv; >> + ofnode node; >> + int ret; >> + >> + ofnode_for_each_subnode(node, dev_ofnode(dev)) { >> + const char *subnode_name = ofnode_get_name(node); >> + struct udevice *mdiodev; >> + >> + if (strcmp(subnode_name, "mdio")) >> + continue; >> + >> + ret = device_bind_driver_to_node(dev, "eth_designware_mdio", >> + subnode_name, node, &mdiodev); >> + if (ret) >> + debug("%s: not able to bind mdio device node\n", __func__); >> + >> + return 0; >> + } >> + >> + printf("%s: mdio node is missing, registering legacy mdio bus", __func__); >> + >> + return dw_mdio_init(name, priv); >> +} >> +#endif >> + >> static void tx_descs_init(struct dw_eth_dev *priv) >> { >> struct eth_dma_regs *dma_p = priv->dma_regs_p; >> @@ -487,7 +566,14 @@ static int _dw_free_pkt(struct dw_eth_dev *priv) >> static int dw_phy_init(struct dw_eth_dev *priv, void *dev) >> { >> struct phy_device *phydev; >> - int phy_addr = -1, ret; >> + int ret; >> + >> +#if IS_ENABLED(CONFIG_DM_MDIO) && IS_ENABLED(CONFIG_DM_ETH) >> + phydev = dm_eth_phy_connect(dev); >> + if (!phydev) >> + return -ENODEV; >> +#else >> + int phy_addr = -1; >> >> #ifdef CONFIG_PHY_ADDR >> phy_addr = CONFIG_PHY_ADDR; >> @@ -496,6 +582,7 @@ static int dw_phy_init(struct dw_eth_dev *priv, void *dev) >> phydev = phy_connect(priv->bus, phy_addr, dev, priv->interface); >> if (!phydev) >> return -ENODEV; >> +#endif >> >> phydev->supported &= PHY_GBIT_FEATURES; >> if (priv->max_speed) { >> @@ -759,7 +846,11 @@ int designware_eth_probe(struct udevice *dev) >> priv->interface = pdata->phy_interface; >> priv->max_speed = pdata->max_speed; >> >> +#if IS_ENABLED(CONFIG_DM_MDIO) >> + ret = dw_dm_mdio_init(dev->name, dev); >> +#else >> ret = dw_mdio_init(dev->name, dev); >> +#endif >> if (ret) { >> err = ret; >> goto mdio_err; >> -- >> 2.25.1 >> > Reviewed-by: Ramon Fried <rfried.dev@gmail.com> > Thanks ! Applied to u-boot-amlogic-next
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 9dba55adaa..acf3a82828 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -21,7 +21,9 @@ #include <reset.h> #include <asm/cache.h> #include <dm/device_compat.h> +#include <dm/device-internal.h> #include <dm/devres.h> +#include <dm/lists.h> #include <linux/compiler.h> #include <linux/delay.h> #include <linux/err.h> @@ -122,6 +124,55 @@ static int dw_mdio_reset(struct mii_dev *bus) } #endif +#if IS_ENABLED(CONFIG_DM_MDIO) +int designware_eth_mdio_read(struct udevice *mdio_dev, int addr, int devad, int reg) +{ + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); + + return dw_mdio_read(pdata->mii_bus, addr, devad, reg); +} + +int designware_eth_mdio_write(struct udevice *mdio_dev, int addr, int devad, int reg, u16 val) +{ + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); + + return dw_mdio_write(pdata->mii_bus, addr, devad, reg, val); +} + +#if CONFIG_IS_ENABLED(DM_GPIO) +int designware_eth_mdio_reset(struct udevice *mdio_dev) +{ + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev); + + return dw_mdio_reset(pdata->mii_bus); +} +#endif + +static const struct mdio_ops designware_eth_mdio_ops = { + .read = designware_eth_mdio_read, + .write = designware_eth_mdio_write, +#if CONFIG_IS_ENABLED(DM_GPIO) + .reset = designware_eth_mdio_reset, +#endif +}; + +static int designware_eth_mdio_probe(struct udevice *dev) +{ + /* Use the priv data of parent */ + dev_set_priv(dev, dev_get_priv(dev->parent)); + + return 0; +} + +U_BOOT_DRIVER(designware_eth_mdio) = { + .name = "eth_designware_mdio", + .id = UCLASS_MDIO, + .probe = designware_eth_mdio_probe, + .ops = &designware_eth_mdio_ops, + .plat_auto = sizeof(struct mdio_perdev_priv), +}; +#endif + static int dw_mdio_init(const char *name, void *priv) { struct mii_dev *bus = mdio_alloc(); @@ -143,6 +194,34 @@ static int dw_mdio_init(const char *name, void *priv) return mdio_register(bus); } +#if IS_ENABLED(CONFIG_DM_MDIO) +static int dw_dm_mdio_init(const char *name, void *priv) +{ + struct udevice *dev = priv; + ofnode node; + int ret; + + ofnode_for_each_subnode(node, dev_ofnode(dev)) { + const char *subnode_name = ofnode_get_name(node); + struct udevice *mdiodev; + + if (strcmp(subnode_name, "mdio")) + continue; + + ret = device_bind_driver_to_node(dev, "eth_designware_mdio", + subnode_name, node, &mdiodev); + if (ret) + debug("%s: not able to bind mdio device node\n", __func__); + + return 0; + } + + printf("%s: mdio node is missing, registering legacy mdio bus", __func__); + + return dw_mdio_init(name, priv); +} +#endif + static void tx_descs_init(struct dw_eth_dev *priv) { struct eth_dma_regs *dma_p = priv->dma_regs_p; @@ -487,7 +566,14 @@ static int _dw_free_pkt(struct dw_eth_dev *priv) static int dw_phy_init(struct dw_eth_dev *priv, void *dev) { struct phy_device *phydev; - int phy_addr = -1, ret; + int ret; + +#if IS_ENABLED(CONFIG_DM_MDIO) && IS_ENABLED(CONFIG_DM_ETH) + phydev = dm_eth_phy_connect(dev); + if (!phydev) + return -ENODEV; +#else + int phy_addr = -1; #ifdef CONFIG_PHY_ADDR phy_addr = CONFIG_PHY_ADDR; @@ -496,6 +582,7 @@ static int dw_phy_init(struct dw_eth_dev *priv, void *dev) phydev = phy_connect(priv->bus, phy_addr, dev, priv->interface); if (!phydev) return -ENODEV; +#endif phydev->supported &= PHY_GBIT_FEATURES; if (priv->max_speed) { @@ -759,7 +846,11 @@ int designware_eth_probe(struct udevice *dev) priv->interface = pdata->phy_interface; priv->max_speed = pdata->max_speed; +#if IS_ENABLED(CONFIG_DM_MDIO) + ret = dw_dm_mdio_init(dev->name, dev); +#else ret = dw_mdio_init(dev->name, dev); +#endif if (ret) { err = ret; goto mdio_err;
Add support for DM_MDIO to connect to PHY and expose a MDIO device for the internal MDIO bus in order to dynamically connect to MDIO PHYs with DT with eventual MDIO muxes in between. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- drivers/net/designware.c | 93 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-)