diff mbox

[U-Boot,1/4] udoo: Add Ethernet support.

Message ID 1383769986.3741.15.camel@localhost
State Changes Requested
Delegated to: Stefano Babic
Headers show

Commit Message

Giuseppe Pagano Nov. 6, 2013, 8:33 p.m. UTC
Add Ethernet and networking support on uDoo board (FEC + phy Micrel)


Signed-off-by: Giuseppe Pagano <giuseppe.pagano@seco.com>
Cc: sbabic@denx.de

---

Comments

Stefano Babic Nov. 7, 2013, 8:38 a.m. UTC | #1
Hi Giuseppe,

On 06/11/2013 21:33, Giuseppe Pagano wrote:
> Add Ethernet and networking support on uDoo board (FEC + phy Micrel)
> 
> 
> Signed-off-by: Giuseppe Pagano <giuseppe.pagano@seco.com>
> Cc: sbabic@denx.de
> 
> ---
> 
> diff -uNr a/board/udoo/udoo.c b/board/udoo/udoo.c
> --- a/board/udoo/udoo.c
> +++ b/board/udoo/udoo.c
> @@ -9,6 +9,7 @@
>  #include <asm/arch/clock.h>
>  #include <asm/arch/imx-regs.h>
>  #include <asm/arch/iomux.h>
> +#include <malloc.h>
>  #include <asm/arch/mx6-pins.h>
>  #include <asm/errno.h>
>  #include <asm/gpio.h>
> @@ -18,6 +19,9 @@
>  #include <asm/arch/crm_regs.h>
>  #include <asm/io.h>
>  #include <asm/arch/sys_proto.h>
> +#include <micrel.h>
> +#include <miiphy.h>
> +#include <netdev.h>
>  
>  DECLARE_GLOBAL_DATA_PTR;
>  
> @@ -25,6 +29,9 @@
>         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
>         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
>  
> +#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
> +	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
> +
>  #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                   \
>         PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
>         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
> @@ -58,6 +65,99 @@
>         MX6_PAD_EIM_D19__GPIO_3_19,
>  };
>  
> +int mx6_rgmii_rework(struct phy_device *phydev)
> +{
> +	/* To advertise only 10 Mbs */
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x4, 0x61);
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x0c00);
> +

Why only 10 Mb/s ? I think the Micrel 9031 allows 1Gb/s.

Generally, use defines instead of hard coded values.

> +	/* enable master mode, force phy to 100Mbps */
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x1c00);
> +
> +	/* min rx data delay */
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x0b, 0x8105);
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x0c, 0x0000);
> +
> +	/* max rx/tx clock delay, min rx/tx control delay */
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x0b, 0x8104);
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x0c, 0xf0f0);
> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x0b, 0x104);
> +
> +	/* min rx data delay */
> +	ksz9021_phy_extended_write(phydev,
> +				   MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);

Is is 9021 or 9031 ?

> +
> +static void setup_iomux_enet(void)
> +{
> +	imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
> +	udelay(20);
> +	gpio_direction_output(IMX_GPIO_NR(2, 31), 1); /* Power on of enet */
> +
> +	gpio_direction_output(IMX_GPIO_NR(3, 23), 0); /* SABRE Lite PHY rst */
> +
> +	gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
> +	gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
> +	gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
> +	gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
> +	gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
> +	udelay(1000 * 10);
> +
> +	gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY rst */

SABRE as comment is maybe wrong

> +#define CONFIG_PHY_MICREL_KSZ9021

Ok, it is 9021 - please be consistent with the comments avoiding mixing
9031 and 9021.

Best regards,
Stefano Babic
Giuseppe Pagano Nov. 7, 2013, 12:37 p.m. UTC | #2
Hi Stefano,

On Thu, 2013-11-07 at 09:38 +0100, Stefano Babic wrote:
> Hi Giuseppe,
> 
> On 06/11/2013 21:33, Giuseppe Pagano wrote:
> > Add Ethernet and networking support on uDoo board (FEC + phy Micrel)
> > 
> > 
> > Signed-off-by: Giuseppe Pagano <giuseppe.pagano@seco.com>
> > Cc: sbabic@denx.de
> > 

> > +int mx6_rgmii_rework(struct phy_device *phydev)
> > +{
> > +	/* To advertise only 10 Mbs */
> > +	phy_write(phydev, MDIO_DEVAD_NONE, 0x4, 0x61);
> > +	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x0c00);
> > +
> 
> Why only 10 Mb/s ? I think the Micrel 9031 allows 1Gb/s.

I will check again, I remember this solves an issue present also in
sabrelite board; but not sure. Maybe we can remove.

> Generally, use defines instead of hard coded values.

Ok


> > +	/* min rx data delay */
> > +	ksz9021_phy_extended_write(phydev,
> > +				   MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
> 
> Is is 9021 or 9031 ?

uDoo adopt a Micrel KSZ9031 phy. 
Most of the register address are common to ksz9021 and ksz9031, and have
the same value. Maybe we should rename some variable to MII_KSZ90XX_...


> > +
> > +	gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY rst */
> 
> SABRE as comment is maybe wrong
> 
> > +#define CONFIG_PHY_MICREL_KSZ9021
> 
> Ok, it is 9021 - please be consistent with the comments avoiding mixing
> 9031 and 9021.

No, it is 9031. I will create a new define.

> 
> Best regards,
> Stefano Babic

Best regards,
Giuseppe Pagano
Stefano Babic Nov. 7, 2013, 2:57 p.m. UTC | #3
Hi Giuseppe,

On 07/11/2013 13:37, Giuseppe Pagano wrote:

>>> +int mx6_rgmii_rework(struct phy_device *phydev)
>>> +{
>>> +	/* To advertise only 10 Mbs */
>>> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x4, 0x61);
>>> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x0c00);
>>> +
>>
>> Why only 10 Mb/s ? I think the Micrel 9031 allows 1Gb/s.
> 
> I will check again, I remember this solves an issue present also in
> sabrelite board; but not sure. Maybe we can remove.

Ok - I know the Nitrogen (aka sabrelite) is working fine with 100Mb, I
am worrying that you will constrain the udoo to 10Mb/s

>>> +	/* min rx data delay */
>>> +	ksz9021_phy_extended_write(phydev,
>>> +				   MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
>>
>> Is is 9021 or 9031 ?
> 
> uDoo adopt a Micrel KSZ9031 phy. 
> Most of the register address are common to ksz9021 and ksz9031, and have
> the same value. Maybe we should rename some variable to MII_KSZ90XX_...
> 
> 
>>> +
>>> +	gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY rst */
>>
>> SABRE as comment is maybe wrong
>>
>>> +#define CONFIG_PHY_MICREL_KSZ9021
>>
>> Ok, it is 9021 - please be consistent with the comments avoiding mixing
>> 9031 and 9021.
> 
> No, it is 9031. I will create a new define.

Mmmhh... I remember I did some work with KSZ9031 some times ago, let me see:

	http://patchwork.ozlabs.org/patch/271947/

Joe, what is the current status of that patchset ?

Best regards,
Stefano Babic
Stefano Babic Nov. 7, 2013, 2:58 p.m. UTC | #4
Hi Giuseppe,

On 07/11/2013 13:37, Giuseppe Pagano wrote:

>>> +int mx6_rgmii_rework(struct phy_device *phydev)
>>> +{
>>> +	/* To advertise only 10 Mbs */
>>> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x4, 0x61);
>>> +	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x0c00);
>>> +
>>
>> Why only 10 Mb/s ? I think the Micrel 9031 allows 1Gb/s.
> 
> I will check again, I remember this solves an issue present also in
> sabrelite board; but not sure. Maybe we can remove.

Ok - I know the Nitrogen (aka sabrelite) is working fine with 100Mb, I
am worrying that you will constrain the udoo to 10Mb/s

>>> +	/* min rx data delay */
>>> +	ksz9021_phy_extended_write(phydev,
>>> +				   MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
>>
>> Is is 9021 or 9031 ?
> 
> uDoo adopt a Micrel KSZ9031 phy. 
> Most of the register address are common to ksz9021 and ksz9031, and have
> the same value. Maybe we should rename some variable to MII_KSZ90XX_...
> 
> 
>>> +
>>> +	gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY rst */
>>
>> SABRE as comment is maybe wrong
>>
>>> +#define CONFIG_PHY_MICREL_KSZ9021
>>
>> Ok, it is 9021 - please be consistent with the comments avoiding mixing
>> 9031 and 9021.
> 
> No, it is 9031. I will create a new define.

Mmmhh... I remember I did some work with KSZ9031 some times ago, let me see:

	http://patchwork.ozlabs.org/patch/271947/

Joe, what is the current status of that patchset ? Can you take a look
at it ?

Best regards,
Stefano Babic
Joe Hershberger Nov. 7, 2013, 3:28 p.m. UTC | #5
On Thu, Nov 7, 2013 at 8:58 AM, Stefano Babic <sbabic@denx.de> wrote:
> Hi Giuseppe,
>
> On 07/11/2013 13:37, Giuseppe Pagano wrote:
>
>>>> +int mx6_rgmii_rework(struct phy_device *phydev)
>>>> +{
>>>> +   /* To advertise only 10 Mbs */
>>>> +   phy_write(phydev, MDIO_DEVAD_NONE, 0x4, 0x61);
>>>> +   phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x0c00);
>>>> +
>>>
>>> Why only 10 Mb/s ? I think the Micrel 9031 allows 1Gb/s.
>>
>> I will check again, I remember this solves an issue present also in
>> sabrelite board; but not sure. Maybe we can remove.
>
> Ok - I know the Nitrogen (aka sabrelite) is working fine with 100Mb, I
> am worrying that you will constrain the udoo to 10Mb/s
>
>>>> +   /* min rx data delay */
>>>> +   ksz9021_phy_extended_write(phydev,
>>>> +                              MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
>>>
>>> Is is 9021 or 9031 ?
>>
>> uDoo adopt a Micrel KSZ9031 phy.
>> Most of the register address are common to ksz9021 and ksz9031, and have
>> the same value. Maybe we should rename some variable to MII_KSZ90XX_...
>>
>>
>>>> +
>>>> +   gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY rst */
>>>
>>> SABRE as comment is maybe wrong
>>>
>>>> +#define CONFIG_PHY_MICREL_KSZ9021
>>>
>>> Ok, it is 9021 - please be consistent with the comments avoiding mixing
>>> 9031 and 9021.
>>
>> No, it is 9031. I will create a new define.
>
> Mmmhh... I remember I did some work with KSZ9031 some times ago, let me see:
>
>         http://patchwork.ozlabs.org/patch/271947/
>
> Joe, what is the current status of that patchset ? Can you take a look
> at it ?

Got it... I'll pull that in shortly.

Thanks,
-Joe
diff mbox

Patch

diff -uNr a/board/udoo/udoo.c b/board/udoo/udoo.c
--- a/board/udoo/udoo.c
+++ b/board/udoo/udoo.c
@@ -9,6 +9,7 @@ 
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/iomux.h>
+#include <malloc.h>
 #include <asm/arch/mx6-pins.h>
 #include <asm/errno.h>
 #include <asm/gpio.h>
@@ -18,6 +19,9 @@ 
 #include <asm/arch/crm_regs.h>
 #include <asm/io.h>
 #include <asm/arch/sys_proto.h>
+#include <micrel.h>
+#include <miiphy.h>
+#include <netdev.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -25,6 +29,9 @@ 
        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
        PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
 
+#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                   \
        PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
        PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
@@ -58,6 +65,99 @@ 
        MX6_PAD_EIM_D19__GPIO_3_19,
 };
 
+int mx6_rgmii_rework(struct phy_device *phydev)
+{
+	/* To advertise only 10 Mbs */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x4, 0x61);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x0c00);
+
+	/* enable master mode, force phy to 100Mbps */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x9, 0x1c00);
+
+	/* min rx data delay */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x0b, 0x8105);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x0c, 0x0000);
+
+	/* max rx/tx clock delay, min rx/tx control delay */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x0b, 0x8104);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x0c, 0xf0f0);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x0b, 0x104);
+
+	/* min rx data delay */
+	ksz9021_phy_extended_write(phydev,
+				   MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
+	/* min tx data delay */
+	ksz9021_phy_extended_write(phydev,
+				   MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
+	/* max rx/tx clock delay, min rx/tx control */
+	ksz9021_phy_extended_write(phydev,
+				   MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0x03FF);
+	return 0;
+}
+
+static iomux_v3_cfg_t const enet_pads1[] = {
+	MX6_PAD_ENET_MDIO__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET_MDC__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TXC__ENET_RGMII_TXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD0__ENET_RGMII_TD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD1__ENET_RGMII_TD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD2__ENET_RGMII_TD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD3__ENET_RGMII_TD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RXC__ENET_RGMII_RXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	/* RGMII reset */
+	MX6_PAD_EIM_D23__GPIO_3_23		| MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* alimentazione ethernet*/
+	MX6_PAD_EIM_EB3__GPIO_2_31		| MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* pin 32 - 1 - (MODE0) all */
+	MX6_PAD_RGMII_RD0__GPIO_6_25		| MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* pin 31 - 1 - (MODE1) all */
+	MX6_PAD_RGMII_RD1__GPIO_6_27		| MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* pin 28 - 1 - (MODE2) all */
+	MX6_PAD_RGMII_RD2__GPIO_6_28		| MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* pin 27 - 1 - (MODE3) all */
+	MX6_PAD_RGMII_RD3__GPIO_6_29		| MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
+	MX6_PAD_RGMII_RX_CTL__GPIO_6_24		| MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const enet_pads2[] = {
+	MX6_PAD_RGMII_RD0__ENET_RGMII_RD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RD1__ENET_RGMII_RD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RD2__ENET_RGMII_RD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RD3__ENET_RGMII_RD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+};
+
+static void setup_iomux_enet(void)
+{
+	imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
+	udelay(20);
+	gpio_direction_output(IMX_GPIO_NR(2, 31), 1); /* Power on of enet */
+
+	gpio_direction_output(IMX_GPIO_NR(3, 23), 0); /* SABRE Lite PHY rst */
+
+	gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
+	gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
+	udelay(1000 * 10);
+
+	gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY rst */
+	/* Need delay 100ms according to KSZ9031 spec */
+	udelay(1000 * 100);
+
+	gpio_free(IMX_GPIO_NR(6, 24));
+	gpio_free(IMX_GPIO_NR(6, 25));
+	gpio_free(IMX_GPIO_NR(6, 27));
+	gpio_free(IMX_GPIO_NR(6, 28));
+	gpio_free(IMX_GPIO_NR(6, 29));
+
+	imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
+}
+
 static void setup_iomux_uart(void)
 {
        imx_iomux_v3_setup_multiple_pads(uart2_pads,
ARRAY_SIZE(uart2_pads));
@@ -77,6 +177,37 @@ 
        return 1; /* Always present */
 }
 
+int board_eth_init(bd_t *bis)
+{
+	uint32_t base = IMX_FEC_BASE;
+	struct mii_dev *bus = NULL;
+	struct phy_device *phydev = NULL;
+	int ret;
+
+	setup_iomux_enet();
+
+#ifdef CONFIG_FEC_MXC
+	bus = fec_get_miibus(base, -1);
+	if (!bus)
+		return 0;
+	/* scan phy 4,5,6,7 */
+	phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
+
+	if (!phydev) {
+		free(bus);
+		return 0;
+	}
+	printf("using phy at %d\n", phydev->addr);
+	ret  = fec_probe(bis, -1, base, bus, phydev);
+	if (ret) {
+		printf("FEC MXC: %s:failed\n", __func__);
+		free(phydev);
+		free(bus);
+	}
+#endif
+	return 0;
+}
+
 int board_mmc_init(bd_t *bis)
 {
        imx_iomux_v3_setup_multiple_pads(usdhc3_pads,
ARRAY_SIZE(usdhc3_pads));
@@ -94,6 +225,15 @@ 
        return 0;
 }
 
+int board_phy_config(struct phy_device *phydev)
+{
+	mx6_rgmii_rework(phydev);
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+
+	return 0;
+}
+
 int board_init(void)
 {
        /* address of boot parameters */
diff -uNr a/include/configs/udoo.h b/include/configs/udoo.h
--- a/include/configs/udoo.h
+++ b/include/configs/udoo.h
@@ -34,6 +34,22 @@ 
 #define CONFIG_MXC_UART
 #define CONFIG_MXC_UART_BASE           UART2_BASE
 
+/* Network support */
+
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+#define CONFIG_FEC_MXC
+#define CONFIG_MII
+#define IMX_FEC_BASE                    ENET_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE             RGMII
+#define CONFIG_ETHPRIME                 "FEC"
+#define CONFIG_FEC_MXC_PHYADDR          6
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_MICREL
+#define CONFIG_PHY_MICREL_KSZ9021
+
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
 #define CONFIG_CONS_INDEX              1