diff options
-rw-r--r-- | drivers/net/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/fec_mxc.c | 59 | ||||
-rw-r--r-- | drivers/net/fec_mxc.h | 4 |
3 files changed, 61 insertions, 4 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f1f0e2d94e..39687431fb 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -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. diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 03df92c6c1..99c5c649a0 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -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" }, { } }; diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 848cd7c227..e9a661f0a1 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -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); |