diff mbox series

[01/13] imx: imx8mp_evk: enable eth support

Message ID 20201228121710.17235-1-peng.fan@oss.nxp.com
State New
Headers show
Series [01/13] imx: imx8mp_evk: enable eth support | expand

Commit Message

Peng Fan (OSS) Dec. 28, 2020, 12:16 p.m. UTC
From: Peng Fan <peng.fan@nxp.com>


Add board code to configure the network interface
Add net defconfig

Signed-off-by: Peng Fan <peng.fan@nxp.com>

---
 arch/arm/include/asm/arch-imx8m/imx-regs.h |  2 +
 board/freescale/imx8mp_evk/imx8mp_evk.c    | 81 ++++++++++++++++++++++
 configs/imx8mp_evk_defconfig               | 11 +++
 include/configs/imx8mp_evk.h               | 16 +++++
 4 files changed, 110 insertions(+)

-- 
2.28.0

Comments

Adam Ford Dec. 28, 2020, 1:53 p.m. UTC | #1
On Mon, Dec 28, 2020 at 7:27 AM Peng Fan (OSS) <peng.fan@oss.nxp.com> wrote:
>

> From: Ye Li <ye.li@nxp.com>

>

> Enable print to show the DRAM rate of current setting and training

> result.

>

> Signed-off-by: Ye Li <ye.li@nxp.com>

> Reviewed-by: Peng Fan <peng.fan@nxp.com>

> Signed-off-by: Peng Fan <peng.fan@nxp.com>

> ---

>  drivers/ddr/imx/imx8m/ddr_init.c     | 7 ++++---

>  drivers/ddr/imx/imx8m/ddrphy_utils.c | 2 +-

>  2 files changed, 5 insertions(+), 4 deletions(-)

>

> diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c

> index 99a67edfb0..65739dbaa7 100644

> --- a/drivers/ddr/imx/imx8m/ddr_init.c

> +++ b/drivers/ddr/imx/imx8m/ddr_init.c

> @@ -96,7 +96,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

>         unsigned int tmp, initial_drate, target_freq;

>         int ret;

>

> -       debug("DDRINFO: start DRAM init\n");

> +       printf("DDRINFO: start DRAM init\n");


Why not make this optional?  With debug enabled, it will print.  This
makes extra chatter for everyone.
It also undoes: 0d3bc813  ("imx8m: ddr_init: Move ddr_init() messages
to debug level")

>

>         /* Step1: Follow the power up procedure */

>         if (is_imx8mq()) {

> @@ -119,6 +119,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

>

>         initial_drate = dram_timing->fsp_msg[0].drate;

>         /* default to the frequency point 0 clock */

> +       printf("DDRINFO: DRAM rate %dMTS\n", initial_drate);

>         ddrphy_init_set_dfi_clk(initial_drate);

>

>         /* D-aasert the presetn */

> @@ -185,7 +186,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

>                 tmp = reg32_read(DDRPHY_CalBusy(0));

>         } while ((tmp & 0x1));

>

> -       debug("DDRINFO:ddrphy calibration done\n");

> +       printf("DDRINFO:ddrphy calibration done\n");

>

>         /* Step15: Set SWCTL.sw_done to 0 */

>         reg32_write(DDRC_SWCTL(0), 0x00000000);

> @@ -240,7 +241,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

>

>         /* enable port 0 */

>         reg32_write(DDRC_PCTRL_0(0), 0x00000001);

> -       debug("DDRINFO: ddrmix config done\n");

> +       printf("DDRINFO: ddrmix config done\n");

>

>         board_dram_ecc_scrub();

>

> diff --git a/drivers/ddr/imx/imx8m/ddrphy_utils.c b/drivers/ddr/imx/imx8m/ddrphy_utils.c

> index 0f8baefb1f..326b92d784 100644

> --- a/drivers/ddr/imx/imx8m/ddrphy_utils.c

> +++ b/drivers/ddr/imx/imx8m/ddrphy_utils.c

> @@ -104,7 +104,7 @@ int wait_ddrphy_training_complete(void)

>                         debug("Training PASS\n");

>                         return 0;

>                 } else if (mail == 0xff) {

> -                       debug("Training FAILED\n");

> +                       printf("Training FAILED\n");

>                         return -1;

>                 }

>         }

> --

> 2.28.0

>
Fabio Estevam Dec. 28, 2020, 2:01 p.m. UTC | #2
On Mon, Dec 28, 2020 at 10:53 AM Adam Ford <aford173@gmail.com> wrote:

> Why not make this optional?  With debug enabled, it will print.  This

> makes extra chatter for everyone.

> It also undoes: 0d3bc813  ("imx8m: ddr_init: Move ddr_init() messages

> to debug level")


Exactly. This type of information could be of interest during
development, but for the final version, it is noise.
Andrey Zhizhikin Dec. 28, 2020, 9:34 p.m. UTC | #3
Hello Peng,

> -----Original Message-----

> From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Peng Fan (OSS)

> Sent: Monday, December 28, 2020 1:17 PM

> To: sbabic@denx.de; festevam@gmail.com

> Cc: uboot-imx@nxp.com; u-boot@lists.denx.de; Peng Fan <peng.fan@nxp.com>

> Subject: [PATCH 01/13] imx: imx8mp_evk: enable eth support

> 

> 

> From: Peng Fan <peng.fan@nxp.com>

> 

> Add board code to configure the network interface

> Add net defconfig

> 

> Signed-off-by: Peng Fan <peng.fan@nxp.com>

> ---

>  arch/arm/include/asm/arch-imx8m/imx-regs.h |  2 +

>  board/freescale/imx8mp_evk/imx8mp_evk.c    | 81 ++++++++++++++++++++++

>  configs/imx8mp_evk_defconfig               | 11 +++

>  include/configs/imx8mp_evk.h               | 16 +++++

>  4 files changed, 110 insertions(+)

> 

> diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h

> b/arch/arm/include/asm/arch-imx8m/imx-regs.h

> index f1c410ec78..f5711155b7 100644

> --- a/arch/arm/include/asm/arch-imx8m/imx-regs.h

> +++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h

> @@ -62,6 +62,8 @@

>  #define DDRC_IPS_BASE_ADDR(X)  (0x3d400000 + ((X) * 0x2000000))

>  #define DDR_CSD1_BASE_ADDR     0x40000000

> 

> +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK 0x70000

> +

>  #if !defined(__ASSEMBLY__)

>  #include <asm/types.h>

>  #include <linux/bitops.h>

> diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c

> b/board/freescale/imx8mp_evk/imx8mp_evk.c

> index 034a349236..d6b863df84 100644

> --- a/board/freescale/imx8mp_evk/imx8mp_evk.c

> +++ b/board/freescale/imx8mp_evk/imx8mp_evk.c

> @@ -7,9 +7,13 @@

>  #include <env.h>

>  #include <errno.h>

>  #include <init.h>

> +#include <miiphy.h>

> +#include <netdev.h>

> +#include <linux/delay.h>

>  #include <asm/mach-imx/iomux-v3.h>

>  #include <asm-generic/gpio.h>

>  #include <asm/arch/imx8mp_pins.h>

> +#include <asm/arch/clock.h>

>  #include <asm/arch/sys_proto.h>

>  #include <asm/mach-imx/gpio.h>

> 

> @@ -40,8 +44,85 @@ int board_early_init_f(void)

>         return 0;

>  }

> 

> +#define FEC_RST_PAD IMX_GPIO_NR(4, 2)

> +static iomux_v3_cfg_t const fec1_rst_pads[] = {

> +       MX8MP_PAD_SAI1_RXD0__GPIO4_IO02 |

> MUX_PAD_CTRL(NO_PAD_CTRL),

> +};

> +

> +static void setup_iomux_fec(void)

> +{

> +       imx_iomux_v3_setup_multiple_pads(fec1_rst_pads,

> +                                        ARRAY_SIZE(fec1_rst_pads));

> +

> +       gpio_request(FEC_RST_PAD, "fec1_rst");

> +       gpio_direction_output(FEC_RST_PAD, 0);

> +       mdelay(15);

> +       gpio_direction_output(FEC_RST_PAD, 1);

> +       mdelay(100);

> +}

> +

> +static int setup_fec(void)

> +{

> +       struct iomuxc_gpr_base_regs *gpr =

> +               (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;

> +

> +       setup_iomux_fec();

> +

> +       /* Enable RGMII TX clk output */

> +       setbits_le32(&gpr->gpr[1], BIT(22));

> +

> +       return 0;


There is only one return code here (and it is 0), and it is not checked anywhere below.

Can this function be made "static void setup_fec(void)"?

Besides, return code is not checked in board_init below...

> +}

> +

> +#define EQOS_RST_PAD IMX_GPIO_NR(4, 22)

> +static iomux_v3_cfg_t const eqos_rst_pads[] = {

> +       MX8MP_PAD_SAI2_RXC__GPIO4_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL),

> +};

> +

> +static void setup_iomux_eqos(void)

> +{

> +       imx_iomux_v3_setup_multiple_pads(eqos_rst_pads,

> +                                        ARRAY_SIZE(eqos_rst_pads));

> +

> +       gpio_request(EQOS_RST_PAD, "eqos_rst");

> +       gpio_direction_output(EQOS_RST_PAD, 0);

> +       mdelay(15);

> +       gpio_direction_output(EQOS_RST_PAD, 1);

> +       mdelay(100);

> +}

> +

> +static int setup_eqos(void)

> +{

> +       struct iomuxc_gpr_base_regs *gpr =

> +               (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;

> +

> +       setup_iomux_eqos();

> +

> +       /* set INTF as RGMII, enable RGMII TXC clock */

> +       clrsetbits_le32(&gpr->gpr[1],

> +                       IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK, BIT(16));

> +       setbits_le32(&gpr->gpr[1], BIT(19) | BIT(21));

> +

> +       return set_clk_eqos(ENET_125MHZ);

> +}


Function does return a value, but return code is never checked in board_init below.

Perhaps, either make it as void, or check the return code?

> +

> +#if CONFIG_IS_ENABLED(NET)

> +int board_phy_config(struct phy_device *phydev)

> +{

> +       if (phydev->drv->config)

> +               phydev->drv->config(phydev);

> +       return 0;

> +}

> +#endif

> +

>  int board_init(void)

>  {

> +       if (CONFIG_IS_ENABLED(FEC_MXC))

> +               setup_fec();

> +

> +       if (CONFIG_IS_ENABLED(DWC_ETH_QOS))

> +               setup_eqos();

> +


Does it make sense to setup ETH QOS if FEC is not enabled?

>         return 0;

>  }

> 

> diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig

> index cd5724e811..de9db697e8 100644

> --- a/configs/imx8mp_evk_defconfig

> +++ b/configs/imx8mp_evk_defconfig

> @@ -73,6 +73,14 @@ CONFIG_MMC_IO_VOLTAGE=y

>  CONFIG_FSL_ESDHC_IMX=y

>  CONFIG_PHYLIB=y

>  CONFIG_DM_ETH=y

> +CONFIG_DWC_ETH_QOS=y

> +


Are those blanks needed in defconfig (here and one below)? 

> +CONFIG_PHY_GIGE=y

> +CONFIG_FEC_MXC=y

> +CONFIG_MII=y

> +CONFIG_PHYLIB=y

> +CONFIG_PHY_REALTEK=y

> +

>  CONFIG_PINCTRL=y

>  CONFIG_SPL_PINCTRL=y

>  CONFIG_PINCTRL_IMX8M=y

> @@ -85,3 +93,6 @@ CONFIG_SPL_SYSRESET=y

>  CONFIG_SYSRESET_PSCI=y

>  CONFIG_SYSRESET_WATCHDOG=y

>  CONFIG_IMX_WATCHDOG=y

> +CONFIG_CMD_DHCP=y

> +CONFIG_CMD_MII=y

> +CONFIG_CMD_PING=y

> diff --git a/include/configs/imx8mp_evk.h b/include/configs/imx8mp_evk.h

> index 8253c6aa2f..7abaf5ff84 100644

> --- a/include/configs/imx8mp_evk.h

> +++ b/include/configs/imx8mp_evk.h

> @@ -44,6 +44,22 @@

> 

>  #endif

> 

> +#if defined(CONFIG_CMD_NET)

> +#define CONFIG_ETHPRIME                 "eth1" /* Set eqos to primary since we use

> its MDIO */

> +

> +#define CONFIG_FEC_XCV_TYPE             RGMII

> +#define CONFIG_FEC_MXC_PHYADDR          1

> +#define FEC_QUIRK_ENET_MAC

> +

> +#define DWC_NET_PHYADDR                        1

> +#ifdef CONFIG_DWC_ETH_QOS

> +#define CONFIG_SYS_NONCACHED_MEMORY     (1 * SZ_1M)     /* 1M */

> +#endif

> +

> +#define PHY_ANEG_TIMEOUT 20000

> +

> +#endif

> +

>  /* Initial environment variables */

>  #define CONFIG_EXTRA_ENV_SETTINGS              \

>         "script=boot.scr\0" \

> --

> 2.28.0



-- andrey
Fabio Estevam Dec. 28, 2020, 10 p.m. UTC | #4
Hi Peng,

On Mon, Dec 28, 2020 at 8:48 AM Peng Fan (OSS) <peng.fan@oss.nxp.com> wrote:

> +static void setup_iomux_fec(void)

> +{

> +       imx_iomux_v3_setup_multiple_pads(fec1_rst_pads,

> +                                        ARRAY_SIZE(fec1_rst_pads));

> +

> +       gpio_request(FEC_RST_PAD, "fec1_rst");

> +       gpio_direction_output(FEC_RST_PAD, 0);

> +       mdelay(15);

> +       gpio_direction_output(FEC_RST_PAD, 1);

> +       mdelay(100);


The Ethernet PHY reset can be handled by the device tree.
Peng Fan Dec. 29, 2020, 1:26 a.m. UTC | #5
> Subject: Re: [PATCH 01/13] imx: imx8mp_evk: enable eth support

> 

> Hi Peng,

> 

> On Mon, Dec 28, 2020 at 8:48 AM Peng Fan (OSS) <peng.fan@oss.nxp.com>

> wrote:

> 

> > +static void setup_iomux_fec(void)

> > +{

> > +       imx_iomux_v3_setup_multiple_pads(fec1_rst_pads,

> > +

> ARRAY_SIZE(fec1_rst_pads));

> > +

> > +       gpio_request(FEC_RST_PAD, "fec1_rst");

> > +       gpio_direction_output(FEC_RST_PAD, 0);

> > +       mdelay(15);

> > +       gpio_direction_output(FEC_RST_PAD, 1);

> > +       mdelay(100);

> 

> The Ethernet PHY reset can be handled by the device tree.


I could use phy-reset-gpios for it. But latest device tree I think prefer
reset-gpios under the phy node which is not supported by U-Boot.

I'll use phy-reset-gpios.

Thanks,
Peng.
diff mbox series

Patch

diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h
index f1c410ec78..f5711155b7 100644
--- a/arch/arm/include/asm/arch-imx8m/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h
@@ -62,6 +62,8 @@ 
 #define DDRC_IPS_BASE_ADDR(X)	(0x3d400000 + ((X) * 0x2000000))
 #define DDR_CSD1_BASE_ADDR	0x40000000
 
+#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK 0x70000
+
 #if !defined(__ASSEMBLY__)
 #include <asm/types.h>
 #include <linux/bitops.h>
diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c b/board/freescale/imx8mp_evk/imx8mp_evk.c
index 034a349236..d6b863df84 100644
--- a/board/freescale/imx8mp_evk/imx8mp_evk.c
+++ b/board/freescale/imx8mp_evk/imx8mp_evk.c
@@ -7,9 +7,13 @@ 
 #include <env.h>
 #include <errno.h>
 #include <init.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <linux/delay.h>
 #include <asm/mach-imx/iomux-v3.h>
 #include <asm-generic/gpio.h>
 #include <asm/arch/imx8mp_pins.h>
+#include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/mach-imx/gpio.h>
 
@@ -40,8 +44,85 @@  int board_early_init_f(void)
 	return 0;
 }
 
+#define FEC_RST_PAD IMX_GPIO_NR(4, 2)
+static iomux_v3_cfg_t const fec1_rst_pads[] = {
+	MX8MP_PAD_SAI1_RXD0__GPIO4_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static void setup_iomux_fec(void)
+{
+	imx_iomux_v3_setup_multiple_pads(fec1_rst_pads,
+					 ARRAY_SIZE(fec1_rst_pads));
+
+	gpio_request(FEC_RST_PAD, "fec1_rst");
+	gpio_direction_output(FEC_RST_PAD, 0);
+	mdelay(15);
+	gpio_direction_output(FEC_RST_PAD, 1);
+	mdelay(100);
+}
+
+static int setup_fec(void)
+{
+	struct iomuxc_gpr_base_regs *gpr =
+		(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
+
+	setup_iomux_fec();
+
+	/* Enable RGMII TX clk output */
+	setbits_le32(&gpr->gpr[1], BIT(22));
+
+	return 0;
+}
+
+#define EQOS_RST_PAD IMX_GPIO_NR(4, 22)
+static iomux_v3_cfg_t const eqos_rst_pads[] = {
+	MX8MP_PAD_SAI2_RXC__GPIO4_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static void setup_iomux_eqos(void)
+{
+	imx_iomux_v3_setup_multiple_pads(eqos_rst_pads,
+					 ARRAY_SIZE(eqos_rst_pads));
+
+	gpio_request(EQOS_RST_PAD, "eqos_rst");
+	gpio_direction_output(EQOS_RST_PAD, 0);
+	mdelay(15);
+	gpio_direction_output(EQOS_RST_PAD, 1);
+	mdelay(100);
+}
+
+static int setup_eqos(void)
+{
+	struct iomuxc_gpr_base_regs *gpr =
+		(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
+
+	setup_iomux_eqos();
+
+	/* set INTF as RGMII, enable RGMII TXC clock */
+	clrsetbits_le32(&gpr->gpr[1],
+			IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK, BIT(16));
+	setbits_le32(&gpr->gpr[1], BIT(19) | BIT(21));
+
+	return set_clk_eqos(ENET_125MHZ);
+}
+
+#if CONFIG_IS_ENABLED(NET)
+int board_phy_config(struct phy_device *phydev)
+{
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+	return 0;
+}
+#endif
+
 int board_init(void)
 {
+	if (CONFIG_IS_ENABLED(FEC_MXC))
+		setup_fec();
+
+	if (CONFIG_IS_ENABLED(DWC_ETH_QOS))
+		setup_eqos();
+
 	return 0;
 }
 
diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig
index cd5724e811..de9db697e8 100644
--- a/configs/imx8mp_evk_defconfig
+++ b/configs/imx8mp_evk_defconfig
@@ -73,6 +73,14 @@  CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
 CONFIG_DM_ETH=y
+CONFIG_DWC_ETH_QOS=y
+
+CONFIG_PHY_GIGE=y
+CONFIG_FEC_MXC=y
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_REALTEK=y
+
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 CONFIG_PINCTRL_IMX8M=y
@@ -85,3 +93,6 @@  CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_PSCI=y
 CONFIG_SYSRESET_WATCHDOG=y
 CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
diff --git a/include/configs/imx8mp_evk.h b/include/configs/imx8mp_evk.h
index 8253c6aa2f..7abaf5ff84 100644
--- a/include/configs/imx8mp_evk.h
+++ b/include/configs/imx8mp_evk.h
@@ -44,6 +44,22 @@ 
 
 #endif
 
+#if defined(CONFIG_CMD_NET)
+#define CONFIG_ETHPRIME                 "eth1" /* Set eqos to primary since we use its MDIO */
+
+#define CONFIG_FEC_XCV_TYPE             RGMII
+#define CONFIG_FEC_MXC_PHYADDR          1
+#define FEC_QUIRK_ENET_MAC
+
+#define DWC_NET_PHYADDR			1
+#ifdef CONFIG_DWC_ETH_QOS
+#define CONFIG_SYS_NONCACHED_MEMORY     (1 * SZ_1M)     /* 1M */
+#endif
+
+#define PHY_ANEG_TIMEOUT 20000
+
+#endif
+
 /* Initial environment variables */
 #define CONFIG_EXTRA_ENV_SETTINGS		\
 	"script=boot.scr\0" \