net: designware: Add bitbang feature for designware driver.
authorMichael Chang <zhang971090220@gmail.com>
Fri, 17 Jan 2025 10:45:40 +0000 (18:45 +0800)
committerTom Rini <trini@konsulko.com>
Fri, 24 Jan 2025 00:51:26 +0000 (18:51 -0600)
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>
drivers/net/designware.c
drivers/net/designware.h

index 07b0f49..94d8f1b 100644 (file)
@@ -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
index e47101c..cccf9d5 100644 (file)
@@ -229,7 +229,11 @@ struct dw_eth_dev {
        u32 max_speed;
        u32 tx_currdescnum;
        u32 rx_currdescnum;
-
+#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
+       u32 bb_delay;
+       struct gpio_desc mdc_gpio;
+       struct gpio_desc mdio_gpio;
+#endif
        struct eth_mac_regs *mac_regs_p;
        struct eth_dma_regs *dma_regs_p;
 #if CONFIG_IS_ENABLED(DM_GPIO)