diff options
author | Michael Chang <zhang971090220@gmail.com> | 2025-01-17 18:45:40 +0800 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-01-23 18:51:26 -0600 |
commit | 6272fc8a2ee2c75428f9358372ea8b53e0e63efd (patch) | |
tree | b1a9b33d2580ffd91f0d39aa2a1030c0b3f916ad /drivers/net/designware.c | |
parent | a78ab770633ece27e86e537aec9f5c3878efa7a4 (diff) |
net: designware: Add bitbang feature for designware driver.
Add bb_miiphy_bus function for designware bitbang feature.
Signed-off-by: Jim Liu <JJLIU0@nuvoton.com>
Signed-off-by: Michael Chang <zhang971090220@gmail.com>
Diffstat (limited to 'drivers/net/designware.c')
-rw-r--r-- | drivers/net/designware.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 07b0f49ef58..94d8f1b4c04 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -784,6 +784,39 @@ int designware_eth_probe(struct udevice *dev) priv->bus = miiphy_get_dev_by_name(dev->name); priv->dev = dev; +#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO) + if (dev_read_bool(dev, "snps,bitbang-mii")) { + int bus_idx; + + debug("\n%s: use bitbang mii..\n", dev->name); + ret = gpio_request_by_name(dev, "snps,mdc-gpio", 0, + &priv->mdc_gpio, GPIOD_IS_OUT + | GPIOD_IS_OUT_ACTIVE); + if (ret) { + debug("no mdc-gpio\n"); + return ret; + } + ret = gpio_request_by_name(dev, "snps,mdio-gpio", 0, + &priv->mdio_gpio, GPIOD_IS_OUT + | GPIOD_IS_OUT_ACTIVE); + if (ret) { + debug("no mdio-gpio\n"); + return ret; + } + priv->bb_delay = dev_read_u32_default(dev, "snps,bitbang-delay", 1); + + for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; bus_idx++) { + if (!bb_miiphy_buses[bus_idx].priv) { + bb_miiphy_buses[bus_idx].priv = priv; + strlcpy(bb_miiphy_buses[bus_idx].name, priv->bus->name, + MDIO_NAME_LEN); + priv->bus->read = bb_miiphy_read; + priv->bus->write = bb_miiphy_write; + break; + } + } + } +#endif ret = dw_phy_init(priv, dev); debug("%s, ret=%d\n", __func__, ret); if (!ret) @@ -894,3 +927,83 @@ static struct pci_device_id supported[] = { }; U_BOOT_PCI_DEVICE(eth_designware, supported); + +#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO) +static int dw_eth_bb_mdio_active(struct bb_miiphy_bus *bus) +{ + struct dw_eth_dev *priv = bus->priv; + struct gpio_desc *desc = &priv->mdio_gpio; + + desc->flags = 0; + dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + + return 0; +} + +static int dw_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus) +{ + struct dw_eth_dev *priv = bus->priv; + struct gpio_desc *desc = &priv->mdio_gpio; + + desc->flags = 0; + dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_IN); + + return 0; +} + +static int dw_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v) +{ + struct dw_eth_dev *priv = bus->priv; + + if (v) + dm_gpio_set_value(&priv->mdio_gpio, 1); + else + dm_gpio_set_value(&priv->mdio_gpio, 0); + + return 0; +} + +static int dw_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v) +{ + struct dw_eth_dev *priv = bus->priv; + + *v = dm_gpio_get_value(&priv->mdio_gpio); + + return 0; +} + +static int dw_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v) +{ + struct dw_eth_dev *priv = bus->priv; + + if (v) + dm_gpio_set_value(&priv->mdc_gpio, 1); + else + dm_gpio_set_value(&priv->mdc_gpio, 0); + + return 0; +} + +static int dw_eth_bb_delay(struct bb_miiphy_bus *bus) +{ + struct dw_eth_dev *priv = bus->priv; + + udelay(priv->bb_delay); + return 0; +} + +struct bb_miiphy_bus bb_miiphy_buses[] = { + { + .name = BB_MII_DEVNAME, + .mdio_active = dw_eth_bb_mdio_active, + .mdio_tristate = dw_eth_bb_mdio_tristate, + .set_mdio = dw_eth_bb_set_mdio, + .get_mdio = dw_eth_bb_get_mdio, + .set_mdc = dw_eth_bb_set_mdc, + .delay = dw_eth_bb_delay, + .priv = NULL, + } +}; + +int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses); +#endif |