]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
net: phy: Factor out PHY GPIO reset code
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Mon, 18 Mar 2024 14:57:01 +0000 (15:57 +0100)
committerTom Rini <trini@konsulko.com>
Tue, 26 Mar 2024 23:58:26 +0000 (19:58 -0400)
Pull the PHY GPIO reset code into separate function, since
this is and will be reused multiple times. Set up default
reset assert and deassert timing to generous 20ms and 1ms
for maximum compatibility in case those DT properties are
missing.

Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
drivers/net/phy/ethernet_id.c
drivers/net/phy/phy.c
include/phy.h

index 6cb1fd4453e9c1e525aaa51455ecd3965f100abc..4dfdee60dccb23f454353453122c6b34dd1e4cd8 100644 (file)
@@ -18,12 +18,11 @@ struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
 {
        struct phy_device *phydev;
        struct ofnode_phandle_args phandle_args;
-       struct gpio_desc gpio;
        const char *node_name;
        struct udevice *pdev;
-       ofnode node;
-       u32 id, assert, deassert;
        u16 vendor, device;
+       ofnode node;
+       u32 id;
        int ret;
 
        if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
@@ -41,35 +40,9 @@ struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
                return NULL;
        }
 
-       if (!IS_ENABLED(CONFIG_DM_ETH_PHY)) {
-               ret = gpio_request_by_name_nodev(node, "reset-gpios", 0, &gpio,
-                                                GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
-               if (!ret) {
-                       assert = ofnode_read_u32_default(node,
-                                                        "reset-assert-us", 0);
-                       deassert = ofnode_read_u32_default(node,
-                                                          "reset-deassert-us",
-                                                          0);
-                       ret = dm_gpio_set_value(&gpio, 1);
-                       if (ret) {
-                               dev_err(dev,
-                                       "Failed assert gpio, err: %d\n", ret);
-                               return NULL;
-                       }
-
-                       udelay(assert);
-
-                       ret = dm_gpio_set_value(&gpio, 0);
-                       if (ret) {
-                               dev_err(dev,
-                                       "Failed deassert gpio, err: %d\n",
-                                       ret);
-                               return NULL;
-                       }
-
-                       udelay(deassert);
-               }
-       }
+       ret = phy_gpio_reset(dev);
+       if (ret)
+               return NULL;
 
        if (phyaddr == -1)
                phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1);
index 9cec04a0c94191668c298da668abe73cdca1603c..270176cfe6296f36e9c19e39ff1cd18ee9fdc54b 100644 (file)
@@ -18,6 +18,8 @@
 #include <phy.h>
 #include <errno.h>
 #include <asm/global_data.h>
+#include <asm-generic/gpio.h>
+#include <dm/device_compat.h>
 #include <dm/of_extra.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
@@ -769,6 +771,59 @@ int miiphy_reset(const char *devname, unsigned char addr)
        return phy_reset(phydev);
 }
 
+#if CONFIG_IS_ENABLED(DM_GPIO) && CONFIG_IS_ENABLED(OF_REAL) && \
+    !IS_ENABLED(CONFIG_DM_ETH_PHY)
+int phy_gpio_reset(struct udevice *dev)
+{
+       struct ofnode_phandle_args phandle_args;
+       struct gpio_desc gpio;
+       u32 assert, deassert;
+       ofnode node;
+       int ret;
+
+       ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
+                                        &phandle_args);
+       /* No PHY handle is OK */
+       if (ret)
+               return 0;
+
+       node = phandle_args.node;
+       if (!ofnode_valid(node))
+               return -EINVAL;
+
+       ret = gpio_request_by_name_nodev(node, "reset-gpios", 0, &gpio,
+                                        GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
+       /* No PHY reset GPIO is OK */
+       if (ret)
+               return 0;
+
+       assert = ofnode_read_u32_default(node, "reset-assert-us", 20000);
+       deassert = ofnode_read_u32_default(node, "reset-deassert-us", 1000);
+       ret = dm_gpio_set_value(&gpio, 1);
+       if (ret) {
+               dev_err(dev, "Failed assert gpio, err: %d\n", ret);
+               return ret;
+       }
+
+       udelay(assert);
+
+       ret = dm_gpio_set_value(&gpio, 0);
+       if (ret) {
+               dev_err(dev, "Failed deassert gpio, err: %d\n", ret);
+               return ret;
+       }
+
+       udelay(deassert);
+
+       return 0;
+}
+#else
+int phy_gpio_reset(struct udevice *dev)
+{
+       return 0;
+}
+#endif
+
 struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask)
 {
        /* Reset the bus */
index ae23814bbf3b650e7a28d0753ba67f8b8d6a0cfb..90b7e364101b2d8358aca81026f70415faf4934d 100644 (file)
@@ -183,6 +183,15 @@ struct fixed_link {
  */
 int phy_reset(struct phy_device *phydev);
 
+/**
+ * phy_gpio_reset() - Resets the specified PHY using GPIO reset
+ * Toggles the optional PHY reset GPIO
+ *
+ * @dev:       PHY udevice to reset
+ * @return: 0 if OK, -ve on error
+ */
+int phy_gpio_reset(struct udevice *dev);
+
 /**
  * phy_find_by_mask() - Searches for a PHY on the specified MDIO bus
  * The function checks the PHY addresses flagged in phy_mask and returns a