KSZ9031 is a very common PHY used with many ethernet design. This document will show you how to add it in u-boot and kernel. 1. Schematic The MODE[3:0] strap-in pins are sampled and latched at power-up/reset. MODE[3:0]=1111 is RGMII mode - Advertise all capabilities (10/100/1000 speed half-/full-duplex) The PHY address, PHYAD[2:0], is sampled and latched at power-up/reset. Here PHY address is set to 001. In this design example, the ENET_RESET_B is connected to GPIO pin GPIO1_IO03. 2. Source code modification In u-boot source code, add the following code in the <board_name>.c file. - IOMUX setup for the GPIO1_IO03 pin. static iomux_v3_cfg_t const phy_reset_pads[] = { MX7D_PAD_GPIO1_IO03__GPIO1_IO3 | MUX_PAD_CTRL(NO_PAD_CTRL), }; - In the function setup_fec(int fec_id), add the code for phy reset. imx_iomux_v3_setup_multiple_pads(phy_reset_pads, ARRAY_SIZE(phy_reset_pads)); gpio_request(IMX_GPIO_NR(1, 3), "ENET PHY Reset"); gpio_direction_output(IMX_GPIO_NR(1, 3) , 0); mdelay(20); gpio_set_value(IMX_GPIO_NR(1, 3), 1); - There is a PHY config for the KSZ9031. int board_phy_config(struct phy_device *phydev) { /* * Default setting for GMII Clock Pad Skew Register 0x1EF: * MMD Address 0x2h, Register 0x8h * * GTX_CLK Pad Skew 0xF -> 0.9 nsec skew * RX_CLK Pad Skew 0xF -> 0.9 nsec skew * * Adjustment -> write 0x3FF: * GTX_CLK Pad Skew 0x1F -> 1.8 nsec skew * RX_CLK Pad Skew 0x1F -> 1.8 nsec skew * */ /* control data pad skew - devaddr = 0x02, register = 0x04 */ ksz9031_phy_extended_write(phydev, 0x02, MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000); /* rx data pad skew - devaddr = 0x02, register = 0x05 */ ksz9031_phy_extended_write(phydev, 0x02, MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000); /* tx data pad skew - devaddr = 0x02, register = 0x05 */ ksz9031_phy_extended_write(phydev, 0x02, MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000); /* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */ ksz9031_phy_extended_write(phydev, 0x02, MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF); if (phydev->drv->config) phydev->drv->config(phydev); return 0; } The KSZ9031 driver (drivers/net/phy/micrel.c) had already supported in the u-boot source code. Add the following #define in the <board_name>.h file to enable the driver for building. #define CONFIG_PHY_MICREL As the PHY address on the board is 001, change the PHYADDR to 1 in the <board_name>.h file. #define CONFIG_FEC_MXC_PHYADDR 0x1 In the kernel source code, add/modify the PHY setting in dts file like this. &fec1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet_reset>; assigned-clocks = <&clks IMX7D_ENET_PHY_REF_ROOT_SRC>, <&clks IMX7D_ENET_AXI_ROOT_SRC>, <&clks IMX7D_ENET1_TIME_ROOT_SRC>, <&clks IMX7D_ENET1_TIME_ROOT_CLK>, <&clks IMX7D_ENET_AXI_ROOT_CLK>; assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_25M_CLK>, <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>, <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; assigned-clock-rates = <0>, <0>, <0>, <100000000>, <250000000>; phy-mode = "rgmii"; phy-handle = <ðphy0>; phy-reset-gpios = <&gpio1 3 0>; fsl,magic-packet; status = "okay"; mdio { #address-cells = <1>; #size-cells = <0>; ethphy0: ethernet-phy@1 { //here '@1' is the PHY address compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; }; }; }; Add the GPIO pin for the ENET_RESET_B &iomuxc { ... ... pinctrl_enet_reset: enet_resetgrp { fsl,pins = < MX7D_PAD_GPIO1_IO03__GPIO1_IO3 0x14 //ENET_RESET_B >; }; } There is a PHY fixup in the arch/arm/mach-imx/<imx_cpu>.c Here is the example in mach-imx7d.c #define PHY_ID_KSZ9031 0x00221620 #define MICREL_PHY_ID_MASK 0x00fffff0 static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val) { phy_write(dev, 0x0d, device); phy_write(dev, 0x0e, reg); phy_write(dev, 0x0d, (1 << 14) | device); phy_write(dev, 0x0e, val); } static int ksz9031rn_phy_fixup(struct phy_device *dev) { /* * min rx data delay, max rx/tx clock delay, * min rx/tx control delay */ mmd_write_reg(dev, -1, 0x4, 0); mmd_write_reg(dev, -1, 0x5, 0); mmd_write_reg(dev, -1, 0x6, 0); mmd_write_reg(dev, -1, 0x8, 0x003ff); return 0; } static void __init imx7d_enet_phy_init(void) { if (IS_BUILTIN(CONFIG_PHYLIB)) { phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff, ar8031_phy_fixup); phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff, bcm54220_phy_fixup); phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK, ksz9031rn_phy_fixup); } } Now, the PHY is working on your board. Reference: 1. Create an Ubuntu VM environment to build Yocto BSP 2. i.MX Software | NXP
View full article