MLK-23279-4 net: eqos: Add support for i.MX8DXL SoC
authorTeo Hall <teo.hall@nxp.com>
Wed, 5 Feb 2020 23:44:36 +0000 (17:44 -0600)
committerYe Li <ye.li@nxp.com>
Thu, 29 Apr 2021 07:56:40 +0000 (00:56 -0700)
Update dwc qos driver for i.MX8DXL

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
(cherry picked from commit d1e718565972495c99345ee8119651ffa14a3238)
(cherry picked from commit 90e308053a02cb6804ebfc06ada20733f000ecc3)

drivers/net/dwc_eth_qos.c

index 14aafc6..560a122 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2016, NVIDIA CORPORATION.
+ * Copyright 2020 NXP
  *
  * Portions based on U-Boot's rtl8169.c.
  */
@@ -45,7 +46,7 @@
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <eth_phy.h>
-#ifdef CONFIG_ARCH_IMX8M
+#if defined(CONFIG_IMX8MP) || defined(CONFIG_IMX8DXL)
 #include <asm/arch/clock.h>
 #include <asm/mach-imx/sys_proto.h>
 #endif
@@ -620,7 +621,43 @@ err:
 
 static int eqos_start_clks_imx(struct udevice *dev)
 {
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+       struct eqos_priv *eqos = dev_get_priv(dev);
+       int ret;
+
+       debug("%s(dev=%p):\n", __func__, dev);
+
+       ret = clk_enable(&eqos->clk_slave_bus);
+       if (ret < 0) {
+               pr_err("clk_enable(clk_slave_bus) failed: %d", ret);
+               goto err;
+       }
+
+       ret = clk_enable(&eqos->clk_master_bus);
+       if (ret < 0) {
+               pr_err("clk_enable(clk_master_bus) failed: %d", ret);
+               goto err_disable_clk_slave_bus;
+       }
+
+       ret = clk_enable(&eqos->clk_tx);
+       if (ret < 0) {
+               pr_err("clk_enable(clk_tx) failed: %d", ret);
+               goto err_disable_clk_master_bus;
+       }
+#endif
+
+       debug("%s: OK\n", __func__);
        return 0;
+
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+err_disable_clk_master_bus:
+       clk_disable(&eqos->clk_master_bus);
+err_disable_clk_slave_bus:
+       clk_disable(&eqos->clk_slave_bus);
+err:
+       debug("%s: FAILED: %d\n", __func__, ret);
+       return ret;
+#endif
 }
 
 static void eqos_stop_clks_tegra186(struct udevice *dev)
@@ -659,7 +696,17 @@ static void eqos_stop_clks_stm32(struct udevice *dev)
 
 static void eqos_stop_clks_imx(struct udevice *dev)
 {
-       /* empty */
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+       struct eqos_priv *eqos = dev_get_priv(dev);
+
+       debug("%s(dev=%p):\n", __func__, dev);
+
+       clk_disable(&eqos->clk_tx);
+       clk_disable(&eqos->clk_slave_bus);
+       clk_disable(&eqos->clk_master_bus);
+#endif
+
+       debug("%s: OK\n", __func__);
 }
 
 static int eqos_start_resets_tegra186(struct udevice *dev)
@@ -851,7 +898,12 @@ __weak int imx_eqos_txclk_set_rate(unsigned long rate)
 
 static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev)
 {
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+       struct eqos_priv *eqos = dev_get_priv(dev);
+       return clk_get_rate(&eqos->clk_slave_bus);
+#else
        return imx_get_eqos_csr_clk();
+#endif
 }
 
 static int eqos_calibrate_pads_stm32(struct udevice *dev)
@@ -979,7 +1031,7 @@ static int eqos_set_tx_clk_speed_imx(struct udevice *dev)
 {
        struct eqos_priv *eqos = dev_get_priv(dev);
        ulong rate;
-       int ret;
+       int ret = 0;
 
        debug("%s(dev=%p):\n", __func__, dev);
 
@@ -998,7 +1050,12 @@ static int eqos_set_tx_clk_speed_imx(struct udevice *dev)
                return -EINVAL;
        }
 
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+       if (!is_imx8dxl())
+               ret = clk_set_rate(&eqos->clk_tx, rate);
+#else
        ret = imx_eqos_txclk_set_rate(rate);
+#endif
        if (ret < 0) {
                pr_err("imx (tx_clk, %lu) failed: %d", rate, ret);
                return ret;
@@ -1118,7 +1175,7 @@ static int eqos_read_rom_hwaddr(struct udevice *dev)
 {
        struct eth_pdata *pdata = dev_get_plat(dev);
 
-#ifdef CONFIG_ARCH_IMX8M
+#if defined(CONFIG_IMX8MP) || defined(CONFIG_IMX8DXL)
        imx_get_mac_from_fuse(dev_seq(dev), pdata->enetaddr);
 #endif
        return !is_valid_ethaddr(pdata->enetaddr);
@@ -1929,9 +1986,35 @@ static int eqos_probe_resources_imx(struct udevice *dev)
                        mdelay(eqos->reset_post_delay);
        }
 
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+       ret = clk_get_by_name(dev, "aclk", &eqos->clk_master_bus);
+       if (ret) {
+               pr_err("clk_get_by_name(csr) failed: %d", ret);
+               goto err_free_gpio_phy_reset;
+       }
+
+       ret = clk_get_by_name(dev, "csr", &eqos->clk_slave_bus);
+       if (ret) {
+               pr_err("clk_get_by_name(aclk) failed: %d", ret);
+               goto err_free_clk_master_bus;
+       }
+
+       ret = clk_get_by_name(dev, "tx_clk", &eqos->clk_tx);
+       if (ret) {
+               pr_err("clk_get_by_name(tx) failed: %d", ret);
+               goto err_free_clk_slave_bus;
+       }
+#endif
+
        debug("%s: OK\n", __func__);
        return 0;
 
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+err_free_clk_slave_bus:
+       clk_free(&eqos->clk_slave_bus);
+err_free_clk_master_bus:
+       clk_free(&eqos->clk_master_bus);
+#endif
 err_free_gpio_phy_reset:
        if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
                dm_gpio_free(dev, &eqos->phy_reset_gpio);
@@ -2001,6 +2084,11 @@ static int eqos_remove_resources_imx(struct udevice *dev)
        struct eqos_priv *eqos = dev_get_priv(dev);
 
        debug("%s(dev=%p):\n", __func__, dev);
+#if CONFIG_IS_ENABLED(CLK) && IS_ENABLED(CONFIG_IMX8)
+       clk_free(&eqos->clk_tx);
+       clk_free(&eqos->clk_slave_bus);
+       clk_free(&eqos->clk_master_bus);
+#endif
        if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
                dm_gpio_free(dev, &eqos->phy_reset_gpio);
        }