[U-Boot] [PATCH v3 08/15] cgtqmx6eval: Add Ethernet support
Stefano Babic
sbabic at denx.de
Sun Jul 26 11:54:20 CEST 2015
Hi Otavio,
On 23/07/2015 16:02, Otavio Salvador wrote:
> cgtqmx6eval can be populated with a AR8035 or KSZ9031 depending on the
> board revision.
>
> Add Ethernet support.
>
> Signed-off-by: Otavio Salvador <otavio at ossystems.com.br>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
> board/congatec/cgtqmx6eval/cgtqmx6eval.c | 206 +++++++++++++++++++++++++++++++
> include/configs/cgtqmx6eval.h | 14 +++
> 2 files changed, 220 insertions(+)
>
> diff --git a/board/congatec/cgtqmx6eval/cgtqmx6eval.c b/board/congatec/cgtqmx6eval/cgtqmx6eval.c
> index 1ae126c..1563ac7 100644
> --- a/board/congatec/cgtqmx6eval/cgtqmx6eval.c
> +++ b/board/congatec/cgtqmx6eval/cgtqmx6eval.c
> @@ -16,8 +16,11 @@
> #include <asm/gpio.h>
> #include <asm/imx-common/iomux-v3.h>
> #include <asm/imx-common/boot_mode.h>
> +#include <malloc.h>
> #include <mmc.h>
> #include <fsl_esdhc.h>
> +#include <miiphy.h>
> +#include <netdev.h>
>
> DECLARE_GLOBAL_DATA_PTR;
>
> @@ -27,6 +30,11 @@ DECLARE_GLOBAL_DATA_PTR;
> #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW |\
> PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
>
> +
> +#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
> + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
> + PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
> +
> int dram_init(void)
> {
> gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
> @@ -77,6 +85,204 @@ static iomux_v3_cfg_t const usdhc4_pads[] = {
> MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
> };
>
> +static iomux_v3_cfg_t enet_pads_ksz9031[] = {
> + 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__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD3__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__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
> + MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
> + MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
> + MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
> + MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
> + MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +static iomux_v3_cfg_t enet_pads_final_ksz9031[] = {
> + MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
> +};
> +
> +static iomux_v3_cfg_t enet_pads_ar8035[] = {
> + 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__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_TD3__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__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
> + MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
> +};
> +
> +int board_eth_init(bd_t *bis)
> +{
> + struct phy_device *phydev;
> + struct mii_dev *bus;
> + unsigned short id1, id2;
> + int ret;
> +
> + iomux_v3_cfg_t enet_reset = MX6_PAD_EIM_D23__GPIO3_IO23 |
> + MUX_PAD_CTRL(NO_PAD_CTRL);
> +
> + /* check whether KSZ9031 or AR8035 has to be configured */
> + imx_iomux_v3_setup_multiple_pads(enet_pads_ar8035,
> + ARRAY_SIZE(enet_pads_ar8035));
> + imx_iomux_v3_setup_pad(enet_reset);
> +
> + /* phy reset */
> + gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
> + udelay(2000);
> + gpio_set_value(IMX_GPIO_NR(3, 23), 1);
> + udelay(500);
> +
> + bus = fec_get_miibus(IMX_FEC_BASE, -1);
> + if (!bus)
> + return -EINVAL;
> + phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
> + if (!phydev) {
> + printf("Error: phy device not found.\n");
> + ret = -ENODEV;
> + goto free_bus;
> + }
> +
> + /* get the PHY id */
> + id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
> + id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
> +
> + if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
> + /* re-configure for Micrel KSZ9031 */
> + printf("configure Micrel KSZ9031 Ethernet Phy at address %d\n",
> + phydev->addr);
> +
> + /* phy reset: gpio3-23 */
> + gpio_set_value(IMX_GPIO_NR(3, 23), 0);
> + gpio_set_value(IMX_GPIO_NR(6, 30), (phydev->addr >> 2));
> + gpio_set_value(IMX_GPIO_NR(6, 25), 1);
> + gpio_set_value(IMX_GPIO_NR(6, 27), 1);
> + gpio_set_value(IMX_GPIO_NR(6, 28), 1);
> + gpio_set_value(IMX_GPIO_NR(6, 29), 1);
> + imx_iomux_v3_setup_multiple_pads(enet_pads_ksz9031,
> + ARRAY_SIZE(enet_pads_ksz9031));
> + gpio_set_value(IMX_GPIO_NR(6, 24), 1);
> + udelay(500);
> + gpio_set_value(IMX_GPIO_NR(3, 23), 1);
> + imx_iomux_v3_setup_multiple_pads(enet_pads_final_ksz9031,
> + ARRAY_SIZE(enet_pads_final_ksz9031));
> + } else if ((id1 == 0x004d) && (id2 == 0xd072)) {
> + /* configure Atheros AR8035 - actually nothing to do */
> + printf("configure Atheros AR8035 Ethernet Phy at address %d\n",
> + phydev->addr);
> + } else {
> + printf("Unknown Ethernet-Phy: 0x%04x 0x%04x\n", id1, id2);
> + ret = -EINVAL;
> + goto free_phydev;
> + }
> +
> + ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
> + if (ret)
> + goto free_phydev;
> +
> + return 0;
> +
> +free_phydev:
> + free(phydev);
> +free_bus:
> + free(bus);
> + return ret;
> +}
> +
> +int mx6_rgmii_rework(struct phy_device *phydev)
> +{
> + unsigned short id1, id2;
> + unsigned short val;
> +
> + /* check whether KSZ9031 or AR8035 has to be configured */
> + id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
> + id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
> +
> + if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
> + /* finalize phy configuration for Micrel KSZ9031 */
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 2);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 4);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0xc002);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0x0000);
I agree that defines in include/micrel.h are not complete. However, each
board has added the constants needed in the file without using
hexadecimal values (see tqma6, aristainetos, udoo).
Can you also add defines to the phy and using them for this board ?
> +
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 2);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 5);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0xc002);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0x0000);
> +
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 2);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 6);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0xc002);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0xFFFF);
> +
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 2);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 8);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0xc002);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0x3FFF);
> +
> + /* fix KSZ9031 link up issue */
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0x0);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0x4);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0x4000);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0x6);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0x0000);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0x3);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0d, 0x4000);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x0e, 0x1A80);
> + }
> +
> + if ((id1 == 0x004d) && (id2 == 0xd072)) {
> + /* enable AR8035 ouput a 125MHz clk from CLK_25M */
> + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
> + val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
> + val &= 0xfe63;
> + val |= 0x18;
> + phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
> +
> + /* introduce tx clock delay */
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
> + val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
> + val |= 0x0100;
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
> +
> + /* disable hibernation */
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0xb);
> + val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3c40);
> + }
> + return 0;
> +}
> +
> +int board_phy_config(struct phy_device *phydev)
> +{
> + mx6_rgmii_rework(phydev);
> +
> + if (phydev->drv->config)
> + phydev->drv->config(phydev);
> +
> + return 0;
> +}
> +
> static void setup_iomux_uart(void)
> {
> imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
> diff --git a/include/configs/cgtqmx6eval.h b/include/configs/cgtqmx6eval.h
> index 9d9e388..8ba47bf 100644
> --- a/include/configs/cgtqmx6eval.h
> +++ b/include/configs/cgtqmx6eval.h
> @@ -32,6 +32,20 @@
> /* Miscellaneous commands */
> #define CONFIG_CMD_BMODE
>
> +/* Ethernet */
> +#define CONFIG_CMD_PING
> +#define CONFIG_CMD_DHCP
> +#define CONFIG_CMD_MII
> +#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_ATHEROS
> +
> #define CONFIG_DEFAULT_FDT_FILE "imx6q-congatec.dtb"
>
> #define CONFIG_EXTRA_ENV_SETTINGS \
>
By the way, your patches are orthogonal. I do not see any issues on the
rest of the series, and I will apply the remaining 14 patches.
Best regards,
Stefano Babic
--
=====================================================================
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
More information about the U-Boot
mailing list