net: fec_mxc: add support for i.MX8X
authorAnatolij Gustschin <agust@denx.de>
Thu, 18 Oct 2018 14:15:11 +0000 (16:15 +0200)
committerJoe Hershberger <joe.hershberger@ni.com>
Wed, 24 Oct 2018 19:45:38 +0000 (14:45 -0500)
Add compatible property and enable the FEC ipg clock when probing
on i.MX8X. Add specific function for reading FEC clock rate via
clock driver when configuring MII speed register. Allow FEC_MXC
selection for i.MX8.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Joe Hershberger <joe.hershberger@ni.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
drivers/net/Kconfig
drivers/net/fec_mxc.c
drivers/net/fec_mxc.h

index f1f0e2d94ef164ce4666bc6bf222006e374c510f..39687431fb1cc50c42efa1429c0005255f03cec0 100644 (file)
@@ -176,7 +176,7 @@ config FEC_MXC_MDIO_BASE
 
 config FEC_MXC
        bool "FEC Ethernet controller"
-       depends on MX5 || MX6 || MX7
+       depends on MX5 || MX6 || MX7 || IMX8
        help
          This driver supports the 10/100 Fast Ethernet controller for
          NXP i.MX processors.
index 03df92c6c130c02cee0b725834a46f65f5d69b29..99c5c649a0a261d2612c6f03a7c84849c83ce4d7 100644 (file)
@@ -123,6 +123,32 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr,
        return val;
 }
 
+static int fec_get_clk_rate(void *udev, int idx)
+{
+#if IS_ENABLED(CONFIG_IMX8)
+       struct fec_priv *fec;
+       struct udevice *dev;
+       int ret;
+
+       dev = udev;
+       if (!dev) {
+               ret = uclass_get_device(UCLASS_ETH, idx, &dev);
+               if (ret < 0) {
+                       debug("Can't get FEC udev: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       fec = dev_get_priv(dev);
+       if (fec)
+               return fec->clk_rate;
+
+       return -EINVAL;
+#else
+       return imx_get_fecclk();
+#endif
+}
+
 static void fec_mii_setspeed(struct ethernet_regs *eth)
 {
        /*
@@ -140,9 +166,20 @@ static void fec_mii_setspeed(struct ethernet_regs *eth)
         * Given that ceil(clkrate / 5000000) <= 64, the calculation for
         * holdtime cannot result in a value greater than 3.
         */
-       u32 pclk = imx_get_fecclk();
-       u32 speed = DIV_ROUND_UP(pclk, 5000000);
-       u32 hold = DIV_ROUND_UP(pclk, 100000000) - 1;
+       u32 pclk;
+       u32 speed;
+       u32 hold;
+       int ret;
+
+       ret = fec_get_clk_rate(NULL, 0);
+       if (ret < 0) {
+               printf("Can't find FEC0 clk rate: %d\n", ret);
+               return;
+       }
+       pclk = ret;
+       speed = DIV_ROUND_UP(pclk, 5000000);
+       hold = DIV_ROUND_UP(pclk, 100000000) - 1;
+
 #ifdef FEC_QUIRK_ENET_MAC
        speed--;
 #endif
@@ -1269,6 +1306,21 @@ static int fecmxc_probe(struct udevice *dev)
        uint32_t start;
        int ret;
 
+       if (IS_ENABLED(CONFIG_IMX8)) {
+               ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
+               if (ret < 0) {
+                       debug("Can't get FEC ipg clk: %d\n", ret);
+                       return ret;
+               }
+               ret = clk_enable(&priv->ipg_clk);
+               if (ret < 0) {
+                       debug("Can't enable FEC ipg clk: %d\n", ret);
+                       return ret;
+               }
+
+               priv->clk_rate = clk_get_rate(&priv->ipg_clk);
+       }
+
        ret = fec_alloc_descs(priv);
        if (ret)
                return ret;
@@ -1412,6 +1464,7 @@ static const struct udevice_id fecmxc_ids[] = {
        { .compatible = "fsl,imx6sx-fec" },
        { .compatible = "fsl,imx6ul-fec" },
        { .compatible = "fsl,imx53-fec" },
+       { .compatible = "fsl,imx7d-fec" },
        { }
 };
 
index 848cd7c22779b8973997386a1a8e2f8f65bc1bb2..e9a661f0a1dd4bcc38cee467cd983567e3493848 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef __FEC_MXC_H
 #define __FEC_MXC_H
 
+#include <clk.h>
+
 /* Layout description of the FEC */
 struct ethernet_regs {
        /* [10:2]addr = 00 */
@@ -260,6 +262,8 @@ struct fec_priv {
 #ifdef CONFIG_DM_ETH
        u32 interface;
 #endif
+       struct clk ipg_clk;
+       u32 clk_rate;
 };
 
 void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);