查看: 1994|回复: 1

[分享] 将 KSZ9031 加入到 i.MX BSP

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
    发表于 2020-8-10 16:20:00 | 显示全部楼层 |阅读模式
    将 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。
    1. static iomux_v3_cfg_t const phy_reset_pads[] = {
    2. MX7D_PAD_GPIO1_IO03__GPIO1_IO3 | MUX_PAD_CTRL(NO_PAD_CTRL),
    3. };
    复制代码
    - 在函数 setup fec (int fec id)中,添加 phy reset 的代码。
    1. imx_iomux_v3_setup_multiple_pads(phy_reset_pads,
    2. ARRAY_SIZE(phy_reset_pads));
    3. gpio_request(IMX_GPIO_NR(1, 3), "ENET PHY Reset");
    4. gpio_direction_output(IMX_GPIO_NR(1, 3) , 0);
    5. mdelay(20);
    6. gpio_set_value(IMX_GPIO_NR(1, 3), 1);
    复制代码
    - 在 KSZ9031 中加入一个 PHY 配置
    1. int board_phy_config(struct phy_device *phydev)
    2. { /*
    3. * Default setting for GMII Clock Pad Skew Register 0x1EF:
    4. * MMD Address 0x2h, Register 0x8h
    5. *
    6. * GTX_CLK Pad Skew 0xF -> 0.9 nsec skew
    7. * RX_CLK Pad Skew 0xF -> 0.9 nsec skew
    8. *
    9. * Adjustment -> write 0x3FF:
    10. * GTX_CLK Pad Skew 0x1F -> 1.8 nsec skew
    11. * RX_CLK Pad Skew 0x1F -> 1.8 nsec skew
    12. *
    13. */
    14. /* control data pad skew - devaddr = 0x02, register = 0x04 */
    15. ksz9031_phy_extended_write(phydev, 0x02,
    16. MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
    17. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
    18. /* rx data pad skew - devaddr = 0x02, register = 0x05 */
    19. ksz9031_phy_extended_write(phydev, 0x02,
    20. MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
    21. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
    22. /* tx data pad skew - devaddr = 0x02, register = 0x05 */
    23. ksz9031_phy_extended_write(phydev, 0x02,
    24. MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
    25. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
    26. /* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */
    27. ksz9031_phy_extended_write(phydev, 0x02,
    28. MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
    29. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
    30. if (phydev->drv->config)
    31. phydev->drv->config(phydev);
    32. return 0;
    33. }
    复制代码
    KSZ9031 驱动程序(drivers/net/phy/micrel.c)已经在 u-boot 源代码中得到了支持。把下面的#define 加入到<board_name>.h 文件中来使驱动程序能够生成。
    1. #define CONFIG_PHY_MICREL
    复制代码
    由于板上的 PHY 地址使 001,请将<board_name>.h 文件中的 PHYADDR 更改为1。
    1. #define CONFIG_FEC_MXC_PHYADDR 0x1
    复制代码
    在核源代码,在 dts 文件中添加/修改 PHY 设置,如下所示:
    1. &fec1 {
    2. pinctrl-names = "default";
    3. pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet_reset>;
    4. assigned-clocks = <&clks IMX7D_ENET_PHY_REF_ROOT_SRC>,
    5. <&clks IMX7D_ENET_AXI_ROOT_SRC>,
    6. <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
    7. <&clks IMX7D_ENET1_TIME_ROOT_CLK>,
    8. <&clks IMX7D_ENET_AXI_ROOT_CLK>;
    9. assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_25M_CLK>,
    10. <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>,
    11. <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
    12. assigned-clock-rates = <0>, <0>, <0>, <100000000>, <250000000>;
    13. phy-mode = "rgmii";
    14. phy-handle = <ðphy0>;
    15. phy-reset-gpios = <&gpio1 3 0>;
    16. fsl,magic-packet;
    17. status = "okay";
    18. mdio {
    19. #address-cells = <1>;
    20. #size-cells = <0>;
    21. ethphy0: ethernet-phy@1 { //here '@1' is the PHY address
    22. compatible = "ethernet-phy-ieee802.3-c22";
    23. reg = <1>;
    24. };
    25. };
    26. };
    复制代码
    在 ENET_RESET_B 中加入 GPIO 指针
    1. &iomuxc {
    2. ...
    3. ...
    4. pinctrl_enet_reset: enet_resetgrp {
    5. fsl,pins = <
    6. MX7D_PAD_GPIO1_IO03__GPIO1_IO3 0x14 //ENET_RE
    7. SET_B
    8. >;
    9. };
    10. }
    复制代码
    在 arch/arm/mach-imx/<imx_cpu>.c 中有一个 PHY 修复程序。下面是在 mach-imx7d.c 中的示例。
    1. #define PHY_ID_KSZ9031 0x00221620
    2. #define MICREL_PHY_ID_MASK 0x00fffff0
    3. static void mmd_write_reg(struct phy_device *dev, int device, int
    4. reg, int val)
    5. {
    6. phy_write(dev, 0x0d, device);
    7. phy_write(dev, 0x0e, reg);
    8. phy_write(dev, 0x0d, (1 << 14) | device);
    9. phy_write(dev, 0x0e, val);
    10. }
    11. static int ksz9031rn_phy_fixup(struct phy_device *dev)
    12. {
    13. /*
    14. * min rx data delay, max rx/tx clock delay,
    15. * min rx/tx control delay
    16. */
    17. mmd_write_reg(dev, -1, 0x4, 0);
    18. mmd_write_reg(dev, -1, 0x5, 0);
    19. mmd_write_reg(dev, -1, 0x6, 0);
    20. mmd_write_reg(dev, -1, 0x8, 0x003ff);
    21. return 0;
    22. }
    23. static void __init imx7d_enet_phy_init(void)
    24. {
    25. if (IS_BUILTIN(CONFIG_PHYLIB)) {
    26. phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
    27. ar8031_phy_fixup);
    28. phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
    29. bcm54220_phy_fixup);
    30. phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
    31. ksz9031rn_phy_fixup);
    32. }
    33. }
    复制代码
    现在,PHY 已经可以在你的板子上运行。

    签到签到
    回复

    使用道具 举报

    该用户从未签到

    2

    主题

    108

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    281
    最后登录
    2020-9-10
    发表于 2020-8-28 08:58:56 | 显示全部楼层
    谢谢分享,学习到了。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-19 12:46 , Processed in 0.105463 second(s), 19 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表