
On Tue, Jul 20, 2021 at 9:10 PM Patrick Delaunay patrick.delaunay@foss.st.com wrote:
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
Changes in v3:
- allow compilation without DM_GPIO
Changes in v2:
- Update eth-phy driver (NEW)
drivers/net/eth-phy-uclass.c | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
diff --git a/drivers/net/eth-phy-uclass.c b/drivers/net/eth-phy-uclass.c index 07aebd935e..7abed14392 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,
};
2.25.1
Applied to u-boot-net/network-master Thanks, Ramon.