summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/phy/ethernet_id.c37
-rw-r--r--drivers/net/phy/phy.c55
-rw-r--r--include/phy.h9
3 files changed, 69 insertions, 32 deletions
diff --git a/drivers/net/phy/ethernet_id.c b/drivers/net/phy/ethernet_id.c
index 6cb1fd4453e..4dfdee60dcc 100644
--- a/drivers/net/phy/ethernet_id.c
+++ b/drivers/net/phy/ethernet_id.c
@@ -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);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 9cec04a0c94..270176cfe62 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -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 */
diff --git a/include/phy.h b/include/phy.h
index ae23814bbf3..90b7e364101 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -184,6 +184,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
* phy_device pointer if it detects a PHY.