On Wed, Nov 10, 2021 at 7:42 AM Joakim Zhang <qiangqing.zh...@nxp.com> wrote: > > For EQOS ethernet, it will do phy_connect() and phy_config() when start > the ethernet (eqos_srart()), users need wait seconds for PHY auto negotiation > to complete when do tftp boot. > phy_config() > -> board_phy_config() > -> phydev->drv->config() // i.MX8MP/DXL use realtek PHY > -> rtl8211f_config() > -> genphy_config_aneg() > -> genphy_restart_aneg() // > restart auto-nego, then need seconds to complete > > To avoid wasting time, we can move PHY connection and configuration from > eqos_start() to eqos_probe(). This patch also moves clock setting from > eqos_start() to eqos_probe() as MDIO access need CSR clock, there is no > function change. > > Tested-on: i.MX8MP & i.MX8DXL > > Before: > u-boot=> run netboot > Booting from net ... > ethernet@30bf0000 Waiting for PHY auto negotiation to complete....... done > BOOTP broadcast 1 > DHCP client bound to address 10.193.102.192 (313 ms) > Using ethernet@30bf0000 device > TFTP from server 10.193.108.176; our IP address is 10.193.102.192; sending > through gateway 10.193.102.254 > After: > u-boot=> run netboot > Booting from net ... > BOOTP broadcast 1 > DHCP client bound to address 10.193.102.192 (454 ms) > Using ethernet@30bf0000 device > TFTP from server 10.193.108.176; our IP address is 10.193.102.192; sending > through gateway 10.193.102.254 > How much time do you save exactly, Is it the ~140ms you show here at the commit log ?
> Signed-off-by: Joakim Zhang <qiangqing.zh...@nxp.com> > --- > drivers/net/dwc_eth_qos.c | 132 +++++++++++++++++++------------------- > 1 file changed, 67 insertions(+), 65 deletions(-) > > diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c > index 585101804d..c1923fbe6b 100644 > --- a/drivers/net/dwc_eth_qos.c > +++ b/drivers/net/dwc_eth_qos.c > @@ -1045,20 +1045,6 @@ static int eqos_start(struct udevice *dev) > eqos->tx_desc_idx = 0; > eqos->rx_desc_idx = 0; > > - ret = eqos->config->ops->eqos_start_clks(dev); > - if (ret < 0) { > - pr_err("eqos_start_clks() failed: %d", ret); > - goto err; > - } > - > - ret = eqos->config->ops->eqos_start_resets(dev); > - if (ret < 0) { > - pr_err("eqos_start_resets() failed: %d", ret); > - goto err_stop_clks; > - } > - > - udelay(10); > - > eqos->reg_access_ok = true; > > ret = wait_for_bit_le32(&eqos->dma_regs->mode, > @@ -1066,68 +1052,34 @@ static int eqos_start(struct udevice *dev) > eqos->config->swr_wait, false); > if (ret) { > pr_err("EQOS_DMA_MODE_SWR stuck"); > - goto err_stop_resets; > + goto err; > } > > ret = eqos->config->ops->eqos_calibrate_pads(dev); > if (ret < 0) { > pr_err("eqos_calibrate_pads() failed: %d", ret); > - goto err_stop_resets; > + goto err; > } > rate = eqos->config->ops->eqos_get_tick_clk_rate(dev); > > val = (rate / 1000000) - 1; > writel(val, &eqos->mac_regs->us_tic_counter); > > - /* > - * if PHY was already connected and configured, > - * don't need to reconnect/reconfigure again > - */ > - if (!eqos->phy) { > - int addr = -1; > -#ifdef CONFIG_DM_ETH_PHY > - addr = eth_phy_get_addr(dev); > -#endif > -#ifdef DWC_NET_PHYADDR > - addr = DWC_NET_PHYADDR; > -#endif > - eqos->phy = phy_connect(eqos->mii, addr, dev, > - eqos->config->interface(dev)); > - if (!eqos->phy) { > - pr_err("phy_connect() failed"); > - goto err_stop_resets; > - } > - > - if (eqos->max_speed) { > - ret = phy_set_supported(eqos->phy, eqos->max_speed); > - if (ret) { > - pr_err("phy_set_supported() failed: %d", ret); > - goto err_shutdown_phy; > - } > - } > - > - ret = phy_config(eqos->phy); > - if (ret < 0) { > - pr_err("phy_config() failed: %d", ret); > - goto err_shutdown_phy; > - } > - } > - > ret = phy_startup(eqos->phy); > if (ret < 0) { > pr_err("phy_startup() failed: %d", ret); > - goto err_shutdown_phy; > + goto err; > } > > if (!eqos->phy->link) { > pr_err("No link"); > - goto err_shutdown_phy; > + goto err; > } > > ret = eqos_adjust_link(dev); > if (ret < 0) { > pr_err("eqos_adjust_link() failed: %d", ret); > - goto err_shutdown_phy; > + goto err; > } > > /* Configure MTL */ > @@ -1356,12 +1308,6 @@ static int eqos_start(struct udevice *dev) > debug("%s: OK\n", __func__); > return 0; > > -err_shutdown_phy: > - phy_shutdown(eqos->phy); > -err_stop_resets: > - eqos->config->ops->eqos_stop_resets(dev); > -err_stop_clks: > - eqos->config->ops->eqos_stop_clks(dev); > err: > pr_err("FAILED: %d", ret); > return ret; > @@ -1412,12 +1358,6 @@ static void eqos_stop(struct udevice *dev) > clrbits_le32(&eqos->dma_regs->ch0_rx_control, > EQOS_DMA_CH0_RX_CONTROL_SR); > > - if (eqos->phy) { > - phy_shutdown(eqos->phy); > - } > - eqos->config->ops->eqos_stop_resets(dev); > - eqos->config->ops->eqos_stop_clks(dev); > - > debug("%s: OK\n", __func__); > } > > @@ -1888,9 +1828,65 @@ static int eqos_probe(struct udevice *dev) > eth_phy_set_mdio_bus(dev, eqos->mii); > #endif > > + ret = eqos->config->ops->eqos_start_clks(dev); > + if (ret < 0) { > + pr_err("eqos_start_clks() failed: %d", ret); > + goto err_unregister_mdio; > + } > + > + ret = eqos->config->ops->eqos_start_resets(dev); > + if (ret < 0) { > + pr_err("eqos_start_resets() failed: %d", ret); > + goto err_stop_clks; > + } > + > + udelay(10); > + > + /* > + * if PHY was already connected and configured, > + * don't need to reconnect/reconfigure again > + */ > + if (!eqos->phy) { > + int addr = -1; > +#ifdef CONFIG_DM_ETH_PHY > + addr = eth_phy_get_addr(dev); > +#endif > +#ifdef DWC_NET_PHYADDR > + addr = DWC_NET_PHYADDR; > +#endif > + eqos->phy = phy_connect(eqos->mii, addr, dev, > + eqos->config->interface(dev)); > + if (!eqos->phy) { > + pr_err("phy_connect() failed"); > + goto err_stop_resets; > + } > + > + if (eqos->max_speed) { > + ret = phy_set_supported(eqos->phy, eqos->max_speed); > + if (ret) { > + pr_err("phy_set_supported() failed: %d", ret); > + goto err_shutdown_phy; > + } > + } > + > + ret = phy_config(eqos->phy); > + if (ret < 0) { > + pr_err("phy_config() failed: %d", ret); > + goto err_shutdown_phy; > + } > + } > + > debug("%s: OK\n", __func__); > return 0; > > +err_shutdown_phy: > + phy_shutdown(eqos->phy); > +err_stop_resets: > + eqos->config->ops->eqos_stop_resets(dev); > +err_stop_clks: > + eqos->config->ops->eqos_stop_clks(dev); > +err_unregister_mdio: > + mdio_unregister(eqos->mii); > err_free_mdio: > mdio_free(eqos->mii); > err_remove_resources_tegra: > @@ -1908,6 +1904,12 @@ static int eqos_remove(struct udevice *dev) > > debug("%s(dev=%p):\n", __func__, dev); > > + if (eqos->phy) { > + phy_shutdown(eqos->phy); > + } > + eqos->config->ops->eqos_stop_resets(dev); > + eqos->config->ops->eqos_stop_clks(dev); > + > mdio_unregister(eqos->mii); > mdio_free(eqos->mii); > eqos->config->ops->eqos_remove_resources(dev); > -- > 2.17.1 >