在线时间4067 小时
UID3441752
注册时间2017-11-21
NXP金币759430
TA的每日心情 | 开心 2024-3-26 15:16 |
---|
签到天数: 266 天 [LV.8]以坛为家I
管理员
- 积分
- 32003
- 最后登录
- 2024-4-9
|
将 KSZ9031 加入到 i.MX BSP
KSZ9031 是一个非常常见的 PHY,被应用于许多以太网设计中。这篇文章将会向
你展示如何将它加入到 u-boot 和 kernel 中。
1.示意图
MODE[3:0]在电源启动/复位时被采样并被锁定。MODE[3:0]=1111 是 RGMII 模式公布所有能力(10/100/1000 速度减半-/全双工)PHY 地址,PHYAD[2:0],在电
源启动/复位时被采样并被锁定。在这一步 PHY 的地址被设置为 001。
在这个设计实例中,ENET_RESET_B 被连接到 GPIO pin GPIO1_IO03 中。
2. 源代码修改
在 U-boot 源代码中,将下面的代码加入到<board_name>.c file 中。
- 在 GPIO1_IO03 指针中加入 IOMUX setup。
- static iomux_v3_cfg_t const phy_reset_pads[] = {
- MX7D_PAD_GPIO1_IO03__GPIO1_IO3 | MUX_PAD_CTRL(NO_PAD_CTRL),
- };
复制代码 - 在函数 setup fec (int fec id)中,添加 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);
复制代码 - 在 KSZ9031 中加入一个 PHY 配置
- 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;
- }
复制代码 KSZ9031 驱动程序(drivers/net/phy/micrel.c)已经在 u-boot 源代码中得到了支持。把下面的#define 加入到<board_name>.h 文件中来使驱动程序能够生成。
- #define CONFIG_PHY_MICREL
复制代码 由于板上的 PHY 地址使 001,请将<board_name>.h 文件中的 PHYADDR 更改为1。
- #define CONFIG_FEC_MXC_PHYADDR 0x1
复制代码 在核源代码,在 dts 文件中添加/修改 PHY 设置,如下所示:
- &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>;
- };
- };
- };
复制代码 在 ENET_RESET_B 中加入 GPIO 指针
- &iomuxc {
- ...
- ...
- pinctrl_enet_reset: enet_resetgrp {
- fsl,pins = <
- MX7D_PAD_GPIO1_IO03__GPIO1_IO3 0x14 //ENET_RE
- SET_B
- >;
- };
- }
复制代码 在 arch/arm/mach-imx/<imx_cpu>.c 中有一个 PHY 修复程序。下面是在 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);
- }
- }
复制代码 现在,PHY 已经可以在你的板子上运行。
|
|