The gpio reset assert/deassert delay are today harcoded in U-Boot driver
but the value should be read from DT.

STM32 use the generic binding defined 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 moves these 2 delay configuration in the driver platdata
and manages this ethernet phy binding for STM32 variant;
when the properties are absent, the driver use the existing value = 2
and the minimal supported udelay = 1 to avoid issue with udelay(0)
when the the property is absent.

This patch also updates the tegra186 part to use the modified platdata,
even if the GPIO reset delay value is hardcoded in probe function.

Signed-off-by: Patrick Delaunay <patrick.delau...@foss.st.com>
---

 drivers/net/dwc_eth_qos.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index e8242ca4e1..6ef750a348 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -293,6 +293,13 @@ struct eqos_ops {
        ulong (*eqos_get_tick_clk_rate)(struct udevice *dev);
 };
 
+/* extend the u-class platdata (eth_pdata) with EQOS driver platdata */
+struct eqos_pdata {
+       struct eth_pdata eth_pdata;
+       u32 reset_assert_us;
+       u32 reset_deassert_us;
+};
+
 struct eqos_priv {
        struct udevice *dev;
        const struct eqos_config *config;
@@ -662,6 +669,7 @@ static void eqos_stop_clks_imx(struct udevice *dev)
 
 static int eqos_start_resets_tegra186(struct udevice *dev)
 {
+       struct eqos_pdata *eqos_plat = dev_get_plat(dev);
        struct eqos_priv *eqos = dev_get_priv(dev);
        int ret;
 
@@ -672,14 +680,14 @@ static int eqos_start_resets_tegra186(struct udevice *dev)
                pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", ret);
                return ret;
        }
-
-       udelay(2);
+       udelay(eqos_plat->reset_assert_us);
 
        ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
        if (ret < 0) {
                pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", 
ret);
                return ret;
        }
+       udelay(eqos_plat->reset_deassert_us);
 
        ret = reset_assert(&eqos->reset_ctl);
        if (ret < 0) {
@@ -701,6 +709,7 @@ static int eqos_start_resets_tegra186(struct udevice *dev)
 
 static int eqos_start_resets_stm32(struct udevice *dev)
 {
+       struct eqos_pdata *eqos_plat = dev_get_plat(dev);
        struct eqos_priv *eqos = dev_get_priv(dev);
        int ret;
 
@@ -712,8 +721,7 @@ static int eqos_start_resets_stm32(struct udevice *dev)
                               ret);
                        return ret;
                }
-
-               udelay(2);
+               udelay(eqos_plat->reset_assert_us);
 
                ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
                if (ret < 0) {
@@ -721,6 +729,7 @@ static int eqos_start_resets_stm32(struct udevice *dev)
                               ret);
                        return ret;
                }
+               udelay(eqos_plat->reset_deassert_us);
        }
        debug("%s: OK\n", __func__);
 
@@ -1070,7 +1079,8 @@ static int eqos_adjust_link(struct udevice *dev)
 
 static int eqos_write_hwaddr(struct udevice *dev)
 {
-       struct eth_pdata *plat = dev_get_plat(dev);
+       struct eqos_pdata *eqos_plat = dev_get_plat(dev);
+       struct eth_pdata *plat = &eqos_plat->eth_pdata;
        struct eqos_priv *eqos = dev_get_priv(dev);
        uint32_t val;
 
@@ -1114,7 +1124,8 @@ static int eqos_write_hwaddr(struct udevice *dev)
 
 static int eqos_read_rom_hwaddr(struct udevice *dev)
 {
-       struct eth_pdata *pdata = dev_get_plat(dev);
+       struct eqos_pdata *eqos_plat = dev_get_plat(dev);
+       struct eth_pdata *pdata = &eqos_plat->eth_pdata;
 
 #ifdef CONFIG_ARCH_IMX8M
        imx_get_mac_from_fuse(dev_seq(dev), pdata->enetaddr);
@@ -1704,6 +1715,7 @@ static int eqos_remove_resources_core(struct udevice *dev)
 
 static int eqos_probe_resources_tegra186(struct udevice *dev)
 {
+       struct eqos_pdata *eqos_plat = dev_get_plat(dev);
        struct eqos_priv *eqos = dev_get_priv(dev);
        int ret;
 
@@ -1722,6 +1734,8 @@ static int eqos_probe_resources_tegra186(struct udevice 
*dev)
                pr_err("gpio_request_by_name(phy reset) failed: %d", ret);
                goto err_free_reset_eqos;
        }
+       eqos_plat->reset_assert_us = 2;
+       eqos_plat->reset_deassert_us = 1;
 
        ret = clk_get_by_name(dev, "slave_bus", &eqos->clk_slave_bus);
        if (ret) {
@@ -1783,6 +1797,7 @@ __weak int board_interface_eth_init(struct udevice *dev,
 
 static int eqos_probe_resources_stm32(struct udevice *dev)
 {
+       struct eqos_pdata *eqos_plat = dev_get_plat(dev);
        struct eqos_priv *eqos = dev_get_priv(dev);
        int ret;
        phy_interface_t interface;
@@ -1839,6 +1854,10 @@ static int eqos_probe_resources_stm32(struct udevice 
*dev)
                if (ret)
                        pr_warn("gpio_request_by_name(phy reset) not provided 
%d",
                                ret);
+               eqos_plat->reset_assert_us = 
ofnode_read_u32_default(phandle_args.node,
+                                                                    
"reset-assert-us", 2);
+               eqos_plat->reset_deassert_us = 
ofnode_read_u32_default(phandle_args.node,
+                                                                      
"reset-deassert-us", 1);
 
                eqos->phyaddr = ofnode_read_u32_default(phandle_args.node,
                                                        "reg", -1);
@@ -2167,5 +2186,5 @@ U_BOOT_DRIVER(eth_eqos) = {
        .remove = eqos_remove,
        .ops = &eqos_ops,
        .priv_auto      = sizeof(struct eqos_priv),
-       .plat_auto      = sizeof(struct eth_pdata),
+       .plat_auto      = sizeof(struct eqos_pdata),
 };
-- 
2.17.1

Reply via email to