aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorPatrick Delaunay2021-07-20 20:09:51 +0200
committerRamon Fried2021-07-22 22:05:28 +0300
commitd33982d5bc442a0dc720962160019cad518d266e (patch)
treee379d8ae52ff69282b5fe505bde6e4828c3e1786 /drivers/net
parentb8da46fda664d06f0afa2fbd0fab6e2acd603a93 (diff)
net: eth-phy: add support of device tree configuration for gpio reset
The gpio reset and the assert or deassert delay are defined in generic binding of the ethernet phy in Linux: Documentation/devicetree/bindings/net/ethernet-phy.yaml reset-gpios: maxItems: 1 description: The GPIO phandle and specifier for the PHY reset signal. reset-assert-us: description: Delay after the reset was asserted in microseconds. If this property is missing the delay will be skipped. reset-deassert-us: description: Delay after the reset was deasserted in microseconds. If this property is missing the delay will be skipped. See also U-Boot: doc/device-tree-bindings/net/phy.txt This patch adds the parsing of this common DT properties in the u-class "eth_phy_generic", used by default in the associated driver "eth_phy_generic_drv" This parsing function eth_phy_of_to_plat can be reused by other ethernet phy drivers for this uclass UCLASS_ETH_PHY. Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/eth-phy-uclass.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/eth-phy-uclass.c b/drivers/net/eth-phy-uclass.c
index 07aebd935e6..7abed14392f 100644
--- a/drivers/net/eth-phy-uclass.c
+++ b/drivers/net/eth-phy-uclass.c
@@ -6,12 +6,17 @@
#include <common.h>
#include <dm.h>
#include <net.h>
+#include <asm-generic/gpio.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <dm/lists.h>
+#include <linux/delay.h>
struct eth_phy_device_priv {
struct mii_dev *mdio_bus;
+ struct gpio_desc reset_gpio;
+ u32 reset_assert_delay;
+ u32 reset_deassert_delay;
};
int eth_phy_binds_nodes(struct udevice *eth_dev)
@@ -110,13 +115,64 @@ int eth_phy_get_addr(struct udevice *dev)
return reg;
}
+/* parsing generic properties of devicetree/bindings/net/ethernet-phy.yaml */
+static int eth_phy_of_to_plat(struct udevice *dev)
+{
+ struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(DM_GPIO))
+ return 0;
+
+ /* search "reset-gpios" in phy node */
+ ret = gpio_request_by_name(dev, "reset-gpios", 0,
+ &uc_priv->reset_gpio,
+ GPIOD_IS_OUT);
+ if (ret != -ENOENT)
+ return ret;
+
+ uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0);
+ uc_priv->reset_deassert_delay = dev_read_u32_default(dev, "reset-deassert-us", 0);
+
+ return 0;
+}
+
+void eth_phy_reset(struct udevice *dev, int value)
+{
+ struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
+ u32 delay;
+
+ if (!CONFIG_IS_ENABLED(DM_GPIO))
+ return;
+
+ if (!dm_gpio_is_valid(&uc_priv->reset_gpio))
+ return;
+
+ dm_gpio_set_value(&uc_priv->reset_gpio, value);
+
+ delay = value ? uc_priv->reset_assert_delay : uc_priv->reset_deassert_delay;
+ if (delay)
+ udelay(delay);
+}
+
+static int eth_phy_pre_probe(struct udevice *dev)
+{
+ /* Assert and deassert the reset signal */
+ eth_phy_reset(dev, 1);
+ eth_phy_reset(dev, 0);
+
+ return 0;
+}
+
UCLASS_DRIVER(eth_phy_generic) = {
.id = UCLASS_ETH_PHY,
.name = "eth_phy_generic",
.per_device_auto = sizeof(struct eth_phy_device_priv),
+ .pre_probe = eth_phy_pre_probe,
};
U_BOOT_DRIVER(eth_phy_generic_drv) = {
.name = "eth_phy_generic_drv",
.id = UCLASS_ETH_PHY,
+ .of_to_plat = eth_phy_of_to_plat,
};