[U-Boot] [PATCH V1 0/6] imx: imx8mm-evk: support eth

This patchset is based on imx/next.
Add imx8mm enet clk Add fec_mxc more clks support for i.MX8M Add board code to configure phy and gpr Fix imx8mm boot
Peng Fan (6): clk: imx8mm: add enet clk clk: imx: imx8mm: add set_parent callback arm: dts: imx8mm: drop assigned clocks for clk node net: Kconfig: FEC: Add dependency on i.MX8M net: fec_mxc: support i.MX8M with CLK_CCF imx: imx8mm-evk: enable ethernet
arch/arm/dts/imx8mm-evk-u-boot.dtsi | 7 ++++ board/freescale/imx8mm_evk/imx8mm_evk.c | 37 +++++++++++++++++ configs/imx8mm_evk_defconfig | 7 ++++ drivers/clk/imx/clk-imx8mm.c | 46 ++++++++++++++++++++ drivers/net/Kconfig | 2 +- drivers/net/fec_mxc.c | 74 ++++++++++++++++++++++++++------- drivers/net/fec_mxc.h | 4 ++ include/configs/imx8mm_evk.h | 8 ++++ 8 files changed, 169 insertions(+), 16 deletions(-)

Add enet ref/timer/PHY_REF/root clk which are required to make enet function well.
Signed-off-by: Peng Fan peng.fan@nxp.com --- drivers/clk/imx/clk-imx8mm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index f4913e70ab..4911345fd9 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -80,6 +80,17 @@ static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_80 static const char *imx8mm_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+#ifndef CONFIG_SPL_BUILD +static const char *imx8mm_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m", + "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", }; + +static const char *imx8mm_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4", "video_pll1_out", }; + +static const char *imx8mm_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m", + "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", }; +#endif + static const char *imx8mm_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
@@ -363,6 +374,22 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
+ /* clks not needed in SPL stage */ +#ifndef CONFIG_SPL_BUILD + clk_dm(IMX8MM_CLK_ENET_REF, + imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, + base + 0xa980)); + clk_dm(IMX8MM_CLK_ENET_TIMER, + imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, + base + 0xaa00)); + clk_dm(IMX8MM_CLK_ENET_PHY_REF, + imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, + base + 0xaa80)); + clk_dm(IMX8MM_CLK_ENET1_ROOT, + imx_clk_gate4("enet1_root_clk", "enet_axi", + base + 0x40a0, 0)); +#endif + #ifdef CONFIG_SPL_BUILD struct clk *clkp, *clkp1;

On 22.10.19 05:29, Peng Fan wrote:
Add enet ref/timer/PHY_REF/root clk which are required to make enet function well.
Signed-off-by: Peng Fan peng.fan@nxp.com
Reviewed-by: Frieder Schrempf frieder.schrempf@kontron.de Tested-by: Frieder Schrempf frieder.schrempf@kontron.de
drivers/clk/imx/clk-imx8mm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index f4913e70ab..4911345fd9 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -80,6 +80,17 @@ static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_80 static const char *imx8mm_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+#ifndef CONFIG_SPL_BUILD +static const char *imx8mm_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
"sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+static const char *imx8mm_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
"clk_ext3", "clk_ext4", "video_pll1_out", };
+static const char *imx8mm_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
"sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+#endif
- static const char *imx8mm_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
@@ -363,6 +374,22 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
- /* clks not needed in SPL stage */
+#ifndef CONFIG_SPL_BUILD
- clk_dm(IMX8MM_CLK_ENET_REF,
imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels,
base + 0xa980));
- clk_dm(IMX8MM_CLK_ENET_TIMER,
imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels,
base + 0xaa00));
- clk_dm(IMX8MM_CLK_ENET_PHY_REF,
imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels,
base + 0xaa80));
- clk_dm(IMX8MM_CLK_ENET1_ROOT,
imx_clk_gate4("enet1_root_clk", "enet_axi",
base + 0x40a0, 0));
+#endif
- #ifdef CONFIG_SPL_BUILD struct clk *clkp, *clkp1;

Add set_parent callback, then assigned-clock-parents in dts could be work.
Signed-off-by: Peng Fan peng.fan@nxp.com --- drivers/clk/imx/clk-imx8mm.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 4911345fd9..091b092bbb 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -175,11 +175,30 @@ static int imx8mm_clk_enable(struct clk *clk) return __imx8mm_clk_enable(clk, 1); }
+static int imx8mm_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *cp; + int ret; + + debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id); + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + ret = clk_get_by_id(parent->id, &cp); + if (ret) + return ret; + + return clk_set_parent(c, cp); +} + static struct clk_ops imx8mm_clk_ops = { .set_rate = imx8mm_clk_set_rate, .get_rate = imx8mm_clk_get_rate, .enable = imx8mm_clk_enable, .disable = imx8mm_clk_disable, + .set_parent = imx8mm_clk_set_parent, };
static int imx8mm_clk_probe(struct udevice *dev)

On 22.10.19 05:29, Peng Fan wrote:
Add set_parent callback, then assigned-clock-parents in dts could be work.
Signed-off-by: Peng Fan peng.fan@nxp.com
Reviewed-by: Frieder Schrempf frieder.schrempf@kontron.de Tested-by: Frieder Schrempf frieder.schrempf@kontron.de
drivers/clk/imx/clk-imx8mm.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 4911345fd9..091b092bbb 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -175,11 +175,30 @@ static int imx8mm_clk_enable(struct clk *clk) return __imx8mm_clk_enable(clk, 1); }
+static int imx8mm_clk_set_parent(struct clk *clk, struct clk *parent) +{
- struct clk *c, *cp;
- int ret;
- debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
- ret = clk_get_by_id(clk->id, &c);
- if (ret)
return ret;
- ret = clk_get_by_id(parent->id, &cp);
- if (ret)
return ret;
- return clk_set_parent(c, cp);
+}
static struct clk_ops imx8mm_clk_ops = { .set_rate = imx8mm_clk_set_rate, .get_rate = imx8mm_clk_get_rate, .enable = imx8mm_clk_enable, .disable = imx8mm_clk_disable,
.set_parent = imx8mm_clk_set_parent, };
static int imx8mm_clk_probe(struct udevice *dev)

Drop assigned clocks for clk node, this will break boot on i.MX8MM EVK board.
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/dts/imx8mm-evk-u-boot.dtsi | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm/dts/imx8mm-evk-u-boot.dtsi b/arch/arm/dts/imx8mm-evk-u-boot.dtsi index 16093f2067..f62a7cf97d 100644 --- a/arch/arm/dts/imx8mm-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-evk-u-boot.dtsi @@ -11,6 +11,9 @@ &clk { u-boot,dm-spl; u-boot,dm-pre-reloc; + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; + /delete-property/ assigned-clock-rates; };
&osc_24m {

Make FEC driver could be used by i.MX8M when CONFIG_FEC_MXC defined in defconfig.
Signed-off-by: Peng Fan peng.fan@nxp.com --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2ce3092db0..08cdd95727 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -236,7 +236,7 @@ config FEC_MXC_MDIO_BASE
config FEC_MXC bool "FEC Ethernet controller" - depends on MX28 || MX5 || MX6 || MX7 || IMX8 || VF610 + depends on MX28 || MX5 || MX6 || MX7 || IMX8 || IMX8M || VF610 help This driver supports the 10/100 Fast Ethernet controller for NXP i.MX processors.

On 22.10.19 05:29, Peng Fan wrote:
Make FEC driver could be used by i.MX8M when CONFIG_FEC_MXC defined in defconfig.
Signed-off-by: Peng Fan peng.fan@nxp.com
Reviewed-by: Frieder Schrempf frieder.schrempf@kontron.de Tested-by: Frieder Schrempf frieder.schrempf@kontron.de
drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2ce3092db0..08cdd95727 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -236,7 +236,7 @@ config FEC_MXC_MDIO_BASE
config FEC_MXC bool "FEC Ethernet controller"
- depends on MX28 || MX5 || MX6 || MX7 || IMX8 || VF610
- depends on MX28 || MX5 || MX6 || MX7 || IMX8 || IMX8M || VF610 help This driver supports the 10/100 Fast Ethernet controller for NXP i.MX processors.

Add more clks for fec_mxc according to Linux Kernel 5.4.0-rc1 drivers/net/ethernet/freescale/fec_main.c.
Since i.MX8MQ not support CLK_CCF, so add a check to restrict the code only effect when CONFIG_IMX8M and CONFIG_CLK_CCF both defined.
Signed-off-by: Peng Fan peng.fan@nxp.com --- drivers/net/fec_mxc.c | 74 ++++++++++++++++++++++++++++++++++++++++----------- drivers/net/fec_mxc.h | 4 +++ 2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 080dbcf7db..9362aa0d05 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -125,28 +125,29 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr,
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; + if (IS_ENABLED(CONFIG_IMX8) || + (IS_ENABLED(CONFIG_IMX8M) && IS_ENABLED(CONFIG_CLK_CCF))) { + 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; + fec = dev_get_priv(dev); + if (fec) + return fec->clk_rate;
- return -EINVAL; -#else - return imx_get_fecclk(); -#endif + return -EINVAL; + } else { + return imx_get_fecclk(); + } }
static void fec_mii_setspeed(struct ethernet_regs *eth) @@ -1335,6 +1336,49 @@ static int fecmxc_probe(struct udevice *dev) return ret; }
+ priv->clk_rate = clk_get_rate(&priv->ipg_clk); + } else if (IS_ENABLED(CONFIG_IMX8M) && IS_ENABLED(CONFIG_CLK_CCF)) { + 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; + } else { + ret = clk_enable(&priv->ipg_clk); + if(ret) + return ret; + } + + ret = clk_get_by_name(dev, "ipg", &priv->ahb_clk); + if (ret < 0) { + debug("Can't get FEC ahb clk: %d\n", ret); + return ret; + } else { + ret = clk_enable(&priv->ahb_clk); + if (ret) + return ret; + } + + ret = clk_get_by_name(dev, "enet_out", &priv->clk_enet_out); + if (!ret) { + ret = clk_enable(&priv->clk_enet_out); + if (ret) + return ret; + } + + ret = clk_get_by_name(dev, "enet_clk_ref", &priv->clk_ref); + if (!ret) { + ret = clk_enable(&priv->clk_ref); + if (ret) + return ret; + } + + ret = clk_get_by_name(dev, "ptp", &priv->clk_ptp); + if (!ret) { + ret = clk_enable(&priv->clk_ptp); + if (ret) + return ret; + } + priv->clk_rate = clk_get_rate(&priv->ipg_clk); }
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index e5f2dd75c5..723b06a651 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -264,6 +264,10 @@ struct fec_priv { u32 interface; #endif struct clk ipg_clk; + struct clk ahb_clk; + struct clk clk_enet_out; + struct clk clk_ref; + struct clk clk_ptp; u32 clk_rate; };

On 22.10.19 05:30, Peng Fan wrote:
Add more clks for fec_mxc according to Linux Kernel 5.4.0-rc1 drivers/net/ethernet/freescale/fec_main.c.
Since i.MX8MQ not support CLK_CCF, so add a check to restrict the code only effect when CONFIG_IMX8M and CONFIG_CLK_CCF both defined.
Signed-off-by: Peng Fan peng.fan@nxp.com
drivers/net/fec_mxc.c | 74 ++++++++++++++++++++++++++++++++++++++++----------- drivers/net/fec_mxc.h | 4 +++ 2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 080dbcf7db..9362aa0d05 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -125,28 +125,29 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr,
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;
- if (IS_ENABLED(CONFIG_IMX8) ||
(IS_ENABLED(CONFIG_IMX8M) && IS_ENABLED(CONFIG_CLK_CCF))) {
Can't we just drop the IS_ENABLED(CONFIG_IMX8M)? Otherwise we always need to touch this code when other SoCs will start using CCF.
Also can you use CONFIG_IS_ENABLED(CLK_CCF) instead of IS_ENABLED(CONFIG_CLK_CCF), so we can detect the config options for SPL and non-SPL separately?
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;
fec = dev_get_priv(dev);
if (fec)
return fec->clk_rate;
- return -EINVAL;
-#else
- return imx_get_fecclk();
-#endif
return -EINVAL;
} else {
return imx_get_fecclk();
} }
static void fec_mii_setspeed(struct ethernet_regs *eth)
@@ -1335,6 +1336,49 @@ static int fecmxc_probe(struct udevice *dev) return ret; }
priv->clk_rate = clk_get_rate(&priv->ipg_clk);
- } else if (IS_ENABLED(CONFIG_IMX8M) && IS_ENABLED(CONFIG_CLK_CCF)) {
Same questions here as above.
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;
} else {
You can drop the else branches here and below as the code returns before it will be evaluated.
ret = clk_enable(&priv->ipg_clk);
if(ret)
return ret;
}
ret = clk_get_by_name(dev, "ipg", &priv->ahb_clk);
This should be "ahb", not "ipg".
if (ret < 0) {
debug("Can't get FEC ahb clk: %d\n", ret);
return ret;
} else {
ret = clk_enable(&priv->ahb_clk);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "enet_out", &priv->clk_enet_out);
if (!ret) {
ret = clk_enable(&priv->clk_enet_out);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "enet_clk_ref", &priv->clk_ref);
if (!ret) {
ret = clk_enable(&priv->clk_ref);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "ptp", &priv->clk_ptp);
if (!ret) {
ret = clk_enable(&priv->clk_ptp);
if (ret)
return ret;
}
- priv->clk_rate = clk_get_rate(&priv->ipg_clk); }
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index e5f2dd75c5..723b06a651 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -264,6 +264,10 @@ struct fec_priv { u32 interface; #endif struct clk ipg_clk;
- struct clk ahb_clk;
- struct clk clk_enet_out;
- struct clk clk_ref;
- struct clk clk_ptp; u32 clk_rate; };

Subject: Re: [U-Boot] [PATCH V1 5/6] net: fec_mxc: support i.MX8M with CLK_CCF
On 22.10.19 05:30, Peng Fan wrote:
Add more clks for fec_mxc according to Linux Kernel 5.4.0-rc1 drivers/net/ethernet/freescale/fec_main.c.
Since i.MX8MQ not support CLK_CCF, so add a check to restrict the code only effect when CONFIG_IMX8M and CONFIG_CLK_CCF both defined.
Signed-off-by: Peng Fan peng.fan@nxp.com
drivers/net/fec_mxc.c | 74
++++++++++++++++++++++++++++++++++++++++-----------
drivers/net/fec_mxc.h | 4 +++ 2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 080dbcf7db..9362aa0d05 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -125,28 +125,29 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr,
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;
- if (IS_ENABLED(CONFIG_IMX8) ||
(IS_ENABLED(CONFIG_IMX8M) &&
IS_ENABLED(CONFIG_CLK_CCF))) {
Can't we just drop the IS_ENABLED(CONFIG_IMX8M)? Otherwise we always need to touch this code when other SoCs will start using CCF.
ok.
Also can you use CONFIG_IS_ENABLED(CLK_CCF) instead of IS_ENABLED(CONFIG_CLK_CCF), so we can detect the config options for SPL and non-SPL separately?
FEC will not be used in SPL stage, so I not use CONFIG_IS_ENABLED. But it does not hurt using IS_ENABLED, change in v2.
Regards, Peng.
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;
fec = dev_get_priv(dev);
if (fec)
return fec->clk_rate;
- return -EINVAL;
-#else
- return imx_get_fecclk();
-#endif
return -EINVAL;
} else {
return imx_get_fecclk();
} }
static void fec_mii_setspeed(struct ethernet_regs *eth) @@ -1335,6
+1336,49 @@ static int fecmxc_probe(struct udevice *dev) return ret; }
priv->clk_rate = clk_get_rate(&priv->ipg_clk);
- } else if (IS_ENABLED(CONFIG_IMX8M) &&
IS_ENABLED(CONFIG_CLK_CCF)) {
Same questions here as above.
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;
} else {
You can drop the else branches here and below as the code returns before it will be evaluated.
ret = clk_enable(&priv->ipg_clk);
if(ret)
return ret;
}
ret = clk_get_by_name(dev, "ipg", &priv->ahb_clk);
This should be "ahb", not "ipg".
if (ret < 0) {
debug("Can't get FEC ahb clk: %d\n", ret);
return ret;
} else {
ret = clk_enable(&priv->ahb_clk);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "enet_out", &priv->clk_enet_out);
if (!ret) {
ret = clk_enable(&priv->clk_enet_out);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "enet_clk_ref", &priv->clk_ref);
if (!ret) {
ret = clk_enable(&priv->clk_ref);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "ptp", &priv->clk_ptp);
if (!ret) {
ret = clk_enable(&priv->clk_ptp);
if (ret)
return ret;
}
- priv->clk_rate = clk_get_rate(&priv->ipg_clk); }
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index e5f2dd75c5..723b06a651 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -264,6 +264,10 @@ struct fec_priv { u32 interface; #endif struct clk ipg_clk;
- struct clk ahb_clk;
- struct clk clk_enet_out;
- struct clk clk_ref;
- struct clk clk_ptp; u32 clk_rate; };

On 24.10.19 03:09, Peng Fan wrote:
Subject: Re: [U-Boot] [PATCH V1 5/6] net: fec_mxc: support i.MX8M with CLK_CCF
On 22.10.19 05:30, Peng Fan wrote:
Add more clks for fec_mxc according to Linux Kernel 5.4.0-rc1 drivers/net/ethernet/freescale/fec_main.c.
Since i.MX8MQ not support CLK_CCF, so add a check to restrict the code only effect when CONFIG_IMX8M and CONFIG_CLK_CCF both defined.
Signed-off-by: Peng Fan peng.fan@nxp.com
drivers/net/fec_mxc.c | 74
++++++++++++++++++++++++++++++++++++++++-----------
drivers/net/fec_mxc.h | 4 +++ 2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 080dbcf7db..9362aa0d05 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -125,28 +125,29 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr,
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;
- if (IS_ENABLED(CONFIG_IMX8) ||
(IS_ENABLED(CONFIG_IMX8M) &&
IS_ENABLED(CONFIG_CLK_CCF))) {
Can't we just drop the IS_ENABLED(CONFIG_IMX8M)? Otherwise we always need to touch this code when other SoCs will start using CCF.
ok.
Also can you use CONFIG_IS_ENABLED(CLK_CCF) instead of IS_ENABLED(CONFIG_CLK_CCF), so we can detect the config options for SPL and non-SPL separately?
FEC will not be used in SPL stage, so I not use CONFIG_IS_ENABLED. But it does not hurt using IS_ENABLED, change in v2.
Regards, Peng.
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;
fec = dev_get_priv(dev);
if (fec)
return fec->clk_rate;
- return -EINVAL;
-#else
- return imx_get_fecclk();
-#endif
return -EINVAL;
} else {
return imx_get_fecclk();
} }
static void fec_mii_setspeed(struct ethernet_regs *eth) @@ -1335,6
+1336,49 @@ static int fecmxc_probe(struct udevice *dev) return ret; }
priv->clk_rate = clk_get_rate(&priv->ipg_clk);
- } else if (IS_ENABLED(CONFIG_IMX8M) &&
IS_ENABLED(CONFIG_CLK_CCF)) {
Same questions here as above.
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;
} else {
You can drop the else branches here and below as the code returns before it will be evaluated.
I think you missed this comment for your v2.
ret = clk_enable(&priv->ipg_clk);
if(ret)
return ret;
}
ret = clk_get_by_name(dev, "ipg", &priv->ahb_clk);
This should be "ahb", not "ipg".
And this one, too.
if (ret < 0) {
debug("Can't get FEC ahb clk: %d\n", ret);
return ret;
} else {
ret = clk_enable(&priv->ahb_clk);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "enet_out", &priv->clk_enet_out);
if (!ret) {
ret = clk_enable(&priv->clk_enet_out);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "enet_clk_ref", &priv->clk_ref);
if (!ret) {
ret = clk_enable(&priv->clk_ref);
if (ret)
return ret;
}
ret = clk_get_by_name(dev, "ptp", &priv->clk_ptp);
if (!ret) {
ret = clk_enable(&priv->clk_ptp);
if (ret)
return ret;
}
}priv->clk_rate = clk_get_rate(&priv->ipg_clk);
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index e5f2dd75c5..723b06a651 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -264,6 +264,10 @@ struct fec_priv { u32 interface; #endif struct clk ipg_clk;
- struct clk ahb_clk;
- struct clk clk_enet_out;
- struct clk clk_ref;
- struct clk clk_ptp; u32 clk_rate; };

add phy-reset-gpios to reset phy Add board_phy_config to configure phy Enable DM_ETH
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/dts/imx8mm-evk-u-boot.dtsi | 4 ++++ board/freescale/imx8mm_evk/imx8mm_evk.c | 37 +++++++++++++++++++++++++++++++++ configs/imx8mm_evk_defconfig | 7 +++++++ include/configs/imx8mm_evk.h | 8 +++++++ 4 files changed, 56 insertions(+)
diff --git a/arch/arm/dts/imx8mm-evk-u-boot.dtsi b/arch/arm/dts/imx8mm-evk-u-boot.dtsi index f62a7cf97d..3502602fbb 100644 --- a/arch/arm/dts/imx8mm-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-evk-u-boot.dtsi @@ -113,3 +113,7 @@ &pinctrl_pmic { u-boot,dm-spl; }; + +&fec1 { + phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; +}; diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c b/board/freescale/imx8mm_evk/imx8mm_evk.c index e4742338e3..a0af550f5e 100644 --- a/board/freescale/imx8mm_evk/imx8mm_evk.c +++ b/board/freescale/imx8mm_evk/imx8mm_evk.c @@ -4,6 +4,11 @@ */
#include <common.h> +#include <miiphy.h> +#include <netdev.h> + +#include <asm/arch/clock.h> +#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -14,8 +19,40 @@ int dram_init(void) return 0; }
+#if IS_ENABLED(CONFIG_FEC_MXC) +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ + clrsetbits_le32(&gpr->gpr[1], 0x2000, 0); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + /* enable rgmii rxc skew and phy mode select to RGMII copper */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + int board_init(void) { + if (IS_ENABLED(CONFIG_FEC_MXC)) + setup_fec(); + return 0; }
diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig index 4cbc62fd8f..9bf5c45a87 100644 --- a/configs/imx8mm_evk_defconfig +++ b/configs/imx8mm_evk_defconfig @@ -35,6 +35,9 @@ CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y CONFIG_CMD_CACHE=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT2=y @@ -62,7 +65,11 @@ CONFIG_DM_MMC=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_FSL_ESDHC_IMX=y CONFIG_PHYLIB=y +CONFIG_PHY_ATHEROS=y CONFIG_DM_ETH=y +CONFIG_PHY_GIGE=y +CONFIG_FEC_MXC=y +CONFIG_MII=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8M=y diff --git a/include/configs/imx8mm_evk.h b/include/configs/imx8mm_evk.h index a9d99ec8b7..e0c5f5a626 100644 --- a/include/configs/imx8mm_evk.h +++ b/include/configs/imx8mm_evk.h @@ -150,4 +150,12 @@
#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_ETHPRIME "FEC" + +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_FEC_MXC_PHYADDR 0 +#define FEC_QUIRK_ENET_MAC + +#define IMX_FEC_BASE 0x30BE0000 + #endif

Hi Peng,
On Tue, Oct 22, 2019 at 12:30 AM Peng Fan peng.fan@nxp.com wrote:
add phy-reset-gpios to reset phy Add board_phy_config to configure phy Enable DM_ETH
Signed-off-by: Peng Fan peng.fan@nxp.com
arch/arm/dts/imx8mm-evk-u-boot.dtsi | 4 ++++ board/freescale/imx8mm_evk/imx8mm_evk.c | 37 +++++++++++++++++++++++++++++++++ configs/imx8mm_evk_defconfig | 7 +++++++ include/configs/imx8mm_evk.h | 8 +++++++ 4 files changed, 56 insertions(+)
diff --git a/arch/arm/dts/imx8mm-evk-u-boot.dtsi b/arch/arm/dts/imx8mm-evk-u-boot.dtsi index f62a7cf97d..3502602fbb 100644 --- a/arch/arm/dts/imx8mm-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-evk-u-boot.dtsi @@ -113,3 +113,7 @@ &pinctrl_pmic { u-boot,dm-spl; };
+&fec1 {
phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
This does not seem to be U-Boot specific information.
I would suggest adding this in the main dts instead.

Subject: Re: [PATCH V1 6/6] imx: imx8mm-evk: enable ethernet
Hi Peng,
On Tue, Oct 22, 2019 at 12:30 AM Peng Fan peng.fan@nxp.com wrote:
add phy-reset-gpios to reset phy Add board_phy_config to configure phy Enable DM_ETH
Signed-off-by: Peng Fan peng.fan@nxp.com
arch/arm/dts/imx8mm-evk-u-boot.dtsi | 4 ++++ board/freescale/imx8mm_evk/imx8mm_evk.c | 37
+++++++++++++++++++++++++++++++++
configs/imx8mm_evk_defconfig | 7 +++++++ include/configs/imx8mm_evk.h | 8 +++++++ 4 files changed, 56 insertions(+)
diff --git a/arch/arm/dts/imx8mm-evk-u-boot.dtsi
b/arch/arm/dts/imx8mm-evk-u-boot.dtsi
index f62a7cf97d..3502602fbb 100644 --- a/arch/arm/dts/imx8mm-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-evk-u-boot.dtsi @@ -113,3 +113,7 @@ &pinctrl_pmic { u-boot,dm-spl; };
+&fec1 {
phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
This does not seem to be U-Boot specific information.
I would suggest adding this in the main dts instead.
I have sent patches to Linux community. When that got merged, we could sync the dts and drop it from u-boot.dtsi. But for now, I prefer to add it in u-boot.dtsi, because Linux dts not have that for now.
Thanks, Peng.
participants (3)
-
Fabio Estevam
-
Peng Fan
-
Schrempf Frieder